Exponential Basic 2.4.0.1 Exponential Basic CMS — PHP Class Reference

ezwebdavcontentbackend.php
Go to the documentation of this file.
1 <?php
30 class eZWebDAVContentBackend extends ezcWebdavSimpleBackend implements ezcWebdavLockBackend
31 {
35 const VIRTUAL_CONTENT_FOLDER_NAME = 'Content';
36
40 const VIRTUAL_MEDIA_FOLDER_NAME = 'Media';
41
45 const WEBDAV_INI_FILE = "webdav.ini";
46
50 const DIRECTORY_MIMETYPE = 'httpd/unix-directory';
51
55 const DEFAULT_MIMETYPE = "application/octet-stream";
56
60 const DEFAULT_SIZE = 0;
61
68 protected $handledLiveProperties = array(
69 'getcontentlength',
70 'getlastmodified',
71 'creationdate',
72 'displayname',
73 'getetag',
74 'getcontenttype',
75 'resourcetype',
76 'supportedlock',
77 'lockdiscovery',
78 );
79
85 protected $FolderClasses = null;
86
92 protected $availableSites = array();
93
99 protected $cachedNodes = array();
100
106 protected $cachedProperties = array();
107
115 protected static $useLogging;
116
120 public function __construct()
121 {
122 // @as @todo check how to make Article class to be handled as a resource (document) instead of a collection
123 $webdavINI = eZINI::instance( self::WEBDAV_INI_FILE );
124
125 $folderClasses = array();
126 if ( $webdavINI->hasGroup( 'GeneralSettings' ) and
127 $webdavINI->hasVariable( 'GeneralSettings', 'FolderClasses' ) )
128 {
129 $folderClasses = $webdavINI->variable( 'GeneralSettings', 'FolderClasses' );
130 }
131 $this->FolderClasses = $folderClasses;
132
133 $ini = eZINI::instance();
134 $this->availableSites = $ini->variable( 'SiteSettings', 'SiteList' );
135 }
136
149 public function lock( $waitTime, $timeout )
150 {
151 // @as @todo implement locking with Exponential functionality (object states)
152 }
153
159 public function unlock()
160 {
161 // @as @todo implement locking with Exponential functionality (object states)
162 }
163
181 protected function acquireLock( $readOnly = false )
182 {
183 // @as @todo implement locking with Exponential functionality (object states)
184 }
185
191 protected function freeLock()
192 {
193 // @as @todo implement locking with Exponential functionality (object states)
194 }
195
208 protected function getNodes( $requestUri, $depth )
209 {
210 $source = $requestUri;
211 $nodeInfo = $this->getNodeInfo( $requestUri );
212
213 if ( !$nodeInfo['nodeExists'] )
214 {
215 return array();
216 }
217
218 // No special handling for plain resources
219 if ( !$nodeInfo['isCollection'] )
220 {
221 return array( new ezcWebdavResource( $source, $this->getAllProperties( $source ) ) );
222 }
223
224 // For zero depth just return the collection
225 if ( $depth === ezcWebdavRequest::DEPTH_ZERO )
226 {
227 return array( new ezcWebdavCollection( $source, $this->getAllProperties( $source ) ) );
228 }
229
230 $nodes = array( new ezcWebdavCollection( $source, $this->getAllProperties( $source ) ) );
231 $recurseCollections = array( $source );
232
233 // Collect children for all collections listed in $recurseCollections.
234 for ( $i = 0; $i < count( $recurseCollections ); ++$i )
235 {
236 $source = $recurseCollections[$i];
237
238 // add the slash at the end of the path if it is missing
239 if ( $source{strlen( $source ) - 1} !== '/' )
240 {
241 $source .= '/';
242 }
243 $children = $this->getCollectionMembers( $source, $depth );
244
245 foreach ( $children as $child )
246 {
247 $nodes[] = $child;
248
249 // Check if we should recurse deeper, and add collections to
250 // processing list in this case.
251 if ( $child instanceof ezcWebdavCollection
252 && $depth === ezcWebdavRequest::DEPTH_INFINITY
253 && $child->path !== $source ) // @as added for recursive DEPTH_INFINITY
254 {
255 $recurseCollections[] = $child->path;
256 }
257 }
258 }
259
260 return $nodes;
261 }
262
272 protected function getResourceContents( $target )
273 {
274 $result = array( 'data' => false, 'file' => false );
275 $fullPath = $target;
276 $target = $this->splitFirstPathElement( $fullPath, $currentSite );
277
278 $data = $this->getVirtualFolderData( $result, $currentSite, $target, $fullPath );
279 if ( $data['file'] )
280 {
281 $file = eZClusterFileHandler::instance( $data['file'] );
282 //$this->cachedProperties[ $data['file'] ]['size'] = $file->size();
283 return $file->fetchContents();
284 }
285
286 return false;
287 }
288
303 protected function getCollectionMembers( $path, $depth = ezcWebdavRequest::DEPTH_INFINITY )
304 {
305 $properties = $this->handledLiveProperties;
306 $fullPath = $path;
307 $collection = $this->splitFirstPathElement( $fullPath, $currentSite );
308
309 if ( !$currentSite )
310 {
311 // Display the root which contains a list of sites
312 $entries = $this->fetchSiteListContent( $fullPath, $depth, $properties );
313 }
314 else
315 {
316 $entries = $this->getVirtualFolderCollection( $currentSite, $collection, $fullPath, $depth, $properties );
317 }
318
319 $contents = array();
320
321 foreach ( $entries as $entry )
322 {
323 // prevent infinite recursion
324 if ( $path === $entry['href'] )
325 {
326 continue;
327 }
328
329 if ( $entry['mimetype'] === self::DIRECTORY_MIMETYPE )
330 {
331 // Add collection without any children
332 $contents[] = new ezcWebdavCollection( $entry['href'], $this->getAllProperties( $path ) );
333 }
334 else
335 {
336 // If this is not a collection, don't leave a trailing '/'
337 // on the href. If you do, Goliath gets confused.
338 $entry['href'] = rtrim( $entry['href'], '/' );
339
340 // Add files without content
341 $contents[] = new ezcWebdavResource( $entry['href'], $this->getAllProperties( $path ) );
342 }
343 }
344
345 return $contents;
346 }
347
359 protected function getNodeInfo( $requestUri, $source = null )
360 {
361 $path = ( $source === null ) ? $requestUri : $source;
362
363 $fullPath = $path;
364 $target = $this->splitFirstPathElement( $path, $currentSite );
365
366 if ( !$currentSite )
367 {
368 $data = $this->fetchSiteListContent( $fullPath, 0, array() );
369 $data = $data[0];
370 $data['nodeExists'] = true;
371 $data['isCollection'] = true;
372 }
373 else
374 {
375 if ( !in_array( $currentSite, $this->availableSites ) )
376 {
377 $data = array();
378 $data['nodeExists'] = false;
379 $data['isCollection'] = false;
380 }
381 else
382 {
383 if ( $target === "" )
384 {
385 $data = $this->fetchVirtualSiteContent( $fullPath, $currentSite, 0, array() );
386 }
387 else if ( in_array( $target, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
388 {
389 $data = $this->fetchContainerNodeInfo( $fullPath, $currentSite, $target );
390 }
391 else
392 {
393 $data = $this->getCollectionContent( $fullPath, 0, array() );
394 }
395
396 if ( is_array( $data ) )
397 {
398 $data = $data[0];
399 $data['nodeExists'] = true;
400 $data['isCollection'] = ( $data['mimetype'] === self::DIRECTORY_MIMETYPE );
401 $data['href'] = $fullPath; // @as @todo move this hack to correct function
402 }
403 else
404 {
405 $data = array();
406 $data['nodeExists'] = false;
407 $data['isCollection'] = false;
408 }
409 }
410 }
411 return $data;
412 }
413
426 public function getProperty( $path, $propertyName, $namespace = 'DAV:' )
427 {
428 $storage = $this->getPropertyStorage( $path );
429
430 // Handle dead propreties
431 if ( $namespace !== 'DAV:' )
432 {
433 $properties = $storage->getAllProperties();
434 return $properties[$namespace][$name];
435 }
436
437 if ( !isset( $this->cachedProperties[$path] ) )
438 {
439 $this->cachedProperties[$path] = $this->getNodeInfo( $path );
440 }
441
442 $item = $this->cachedProperties[$path];
443
444 // Handle live properties
445 switch ( $propertyName )
446 {
447 case 'getcontentlength':
448 $property = new ezcWebdavGetContentLengthProperty();
449 $mimetype = isset( $item['mimetype'] ) ? $item['mimetype'] : self::DEFAULT_MIMETYPE;
450 $size = isset( $item['size'] ) ? $item['size'] : self::DEFAULT_SIZE;
451 $property->length = ( $mimetype === self::DIRECTORY_MIMETYPE ) ?
452 ezcWebdavGetContentLengthProperty::COLLECTION :
453 (string) $size;
454 break;
455
456 case 'getlastmodified':
457 $property = new ezcWebdavGetLastModifiedProperty();
458 $timestamp = isset( $item['mtime'] ) ? $item['mtime'] : time();
459 $property->date = new ezcWebdavDateTime( '@' . $timestamp );
460 break;
461
462 case 'creationdate':
463 $property = new ezcWebdavCreationDateProperty();
464 $timestamp = isset( $item['ctime'] ) ? $item['ctime'] : time();
465 $property->date = new ezcWebdavDateTime( '@' . $timestamp );
466 break;
467
468 case 'displayname':
469 $property = new ezcWebdavDisplayNameProperty();
470 $property->displayName = isset( $item['name'] ) ? $item['name'] : 'Unknown displayname';
471 break;
472
473 case 'getcontenttype':
474 $property = new ezcWebdavGetContentTypeProperty();
475 $property->mime = isset( $item['mimetype'] ) ? $item['mimetype'] : self::DEFAULT_MIMETYPE;
476 break;
477
478 case 'getetag':
479 $property = new ezcWebdavGetEtagProperty();
480 $mimetype = isset( $item['mimetype'] ) ? $item['mimetype'] : self::DEFAULT_MIMETYPE;
481 $size = isset( $item['size'] ) ? $item['size'] : self::DEFAULT_SIZE;
482 $size = ( $mimetype === self::DIRECTORY_MIMETYPE ) ?
483 ezcWebdavGetContentLengthProperty::COLLECTION :
484 (string) $size;
485 $timestamp = isset( $item['mtime'] ) ? $item['mtime'] : time();
486 $property->etag = md5( $path . $size . date( 'c', $timestamp ) );
487 break;
488
489 case 'resourcetype':
490 $property = new ezcWebdavResourceTypeProperty();
491 $mimetype = isset( $item['mimetype'] ) ? $item['mimetype'] : self::DEFAULT_MIMETYPE;
492 $property->type = ( $mimetype === self::DIRECTORY_MIMETYPE ) ?
493 ezcWebdavResourceTypeProperty::TYPE_COLLECTION :
494 ezcWebdavResourceTypeProperty::TYPE_RESOURCE;
495 break;
496
497 case 'supportedlock':
498 $property = new ezcWebdavSupportedLockProperty();
499 break;
500
501 case 'lockdiscovery':
502 $property = new ezcWebdavLockDiscoveryProperty();
503 break;
504
505 default:
506 // Handle all other live properties like dead properties
507 $properties = $storage->getAllProperties();
508 $property = $properties['DAV:'][$name]; // @as (need to figure $namespace)
509 break;
510 }
511
512 return $property;
513 }
514
524 public function getAllProperties( $path )
525 {
526 $storage = $this->getPropertyStorage( $path );
527
528 // Add all live properties to stored properties
529 foreach ( $this->handledLiveProperties as $property )
530 {
531 $storage->attach(
532 $this->getProperty( $path, $property )
533 );
534 }
535
536 return $storage;
537 }
538
548 protected function getPropertyStorage( $path )
549 {
550 $storage = new ezcWebdavBasicPropertyStorage();
551
552 // @todo implement property storage
553 return $storage;
554 }
555
564 protected function nodeExists( $path )
565 {
566 if ( !isset( $this->cachedNodes[$path] ) )
567 {
568 $this->cachedNodes[$path] = $this->getNodeInfo( $path );
569 }
570
571 return $this->cachedNodes[$path]['nodeExists'];
572 }
573
583 protected function isCollection( $path )
584 {
585 if ( !isset( $this->cachedNodes[$path] ) )
586 {
587 $this->cachedNodes[$path] = $this->getNodeInfo( $path );
588 }
589
590 return $this->cachedNodes[$path]['isCollection'];
591 }
592
610 public function get( ezcWebdavGetRequest $request )
611 {
612 $this->acquireLock( true );
613 $return = parent::get( $request );
614 $this->freeLock();
615
616 return $return;
617 }
618
634 public function head( ezcWebdavHeadRequest $request )
635 {
636 $this->acquireLock( true );
637 $return = parent::head( $request );
638 $this->freeLock();
639
640 return $return;
641 }
642
673 public function propFind( ezcWebdavPropFindRequest $request )
674 {
675 $ini = eZINI::instance( 'i18n.ini' );
676 $dataCharset = $ini->variable( 'CharacterSettings', 'Charset' );
677 $xmlCharset = 'utf-8';
678
679 $this->acquireLock( true );
680 $return = parent::propFind( $request );
681 if ( isset( $return->responses ) && is_array( $return->responses ) )
682 {
683 foreach ( $return->responses as $response )
684 {
685 $href = $response->node->path;
686 $pathArray = explode( '/', self::recode( $href, $dataCharset, $xmlCharset ) );
687 $encodedPath = '/';
688
689 foreach ( $pathArray as $pathElement )
690 {
691 if ( $pathElement != '' )
692 {
693 $encodedPath .= rawurlencode( $pathElement );
694 $encodedPath .= '/';
695 }
696 }
697 $encodedPath = rtrim( $encodedPath, '/' );
698 $response->node->path = $encodedPath;
699 }
700 }
701 $this->freeLock();
702
703 return $return;
704 }
705
724 public function propPatch( ezcWebdavPropPatchRequest $request )
725 {
726 $this->acquireLock();
727 $return = parent::propPatch( $request );
728 $this->freeLock();
729
730 return $return;
731 }
732
743 protected function storeProperties( $path, ezcWebdavBasicPropertyStorage $storage )
744 {
745 // @as @todo implement storing properties
746 return true;
747 }
748
758 public function setProperty( $path, ezcWebdavProperty $property )
759 {
760 if ( !in_array( $property->name, $this->handledLiveProperties, true ) )
761 {
762 return false;
763 }
764
765 // @as @todo implement setting properties
766 // @todo implement locking and unlocking based on the code
767 // lock:
768 // replace 30607 with your object ID
769 // $object = eZContentObject::fetch( 30607 );
770 // $stateGroup = eZContentObjectStateGroup::fetchByIdentifier( 'ez_lock' );
771 // $state = eZContentObjectState::fetchByIdentifier( 'locked', $stateGroup->attribute( 'id' ) );
772 // $object->assignState( $state );
773
774 // unlock:
775 // $state = eZContentObjectState::fetchByIdentifier( 'not_locked', $stateGroup->attribute( 'id' ) );
776 // $object->assignState( $state );
777
778 // Get namespace property storage
779 $storage = new ezcWebdavBasicPropertyStorage();
780
781 // Attach property to store
782 $storage->attach( $property );
783
784 // Store document back
785 $this->storeProperties( $path, $storage );
786
787 return true;
788 }
789
799 public function removeProperty( $path, ezcWebdavProperty $property )
800 {
801 // @as @todo implement removing properties
802 return true;
803 }
804
815 public function resetProperties( $path, ezcWebdavPropertyStorage $storage )
816 {
817 $this->storeProperties( $path, $storage );
818 }
819
835 public function put( ezcWebdavPutRequest $request )
836 {
837 $this->acquireLock();
838 $return = parent::put( $request );
839 $this->freeLock();
840
841 return $return;
842 }
843
853 protected function createResource( $path, $content = null )
854 {
855 // the creation of the resource is done in setResourceContents()
856 }
857
867 protected function setResourceContents( $path, $content )
868 {
869 // Attempt to get file/resource sent from client/browser.
870 $tempFile = $this->storeUploadedFile( $path, $content );
871 eZWebDAVContentBackend::appendLogEntry( 'SetResourceContents:' . $path . ';' . $tempFile );
872
873 // If there was an actual file:
874 if ( !$tempFile )
875 {
876 return false; // @as self::FAILED_FORBIDDEN;
877 }
878
879 // Attempt to do something with it (copy/whatever).
880 $fullPath = $path;
881 $target = $this->splitFirstPathElement( $path, $currentSite );
882
883 if ( !$currentSite )
884 {
885 return false; // @as self::FAILED_FORBIDDEN;
886 }
887
888 $result = $this->putVirtualFolderData( $currentSite, $target, $tempFile );
889
890 unlink( $tempFile );
891 eZDir::cleanupEmptyDirectories( dirname( $tempFile ) );
892
893 return $result;
894 }
895
911 public function delete( ezcWebdavDeleteRequest $request )
912 {
913 $this->acquireLock();
914 $return = parent::delete( $request );
915 $this->freeLock();
916
917 return $return;
918 }
919
930 public function checkDeleteRecursive( $target )
931 {
932 $errors = array();
933
934 $fullPath = $target;
935 $target = $this->splitFirstPathElement( $target, $currentSite );
936
937 if ( !$currentSite )
938 {
939 // Cannot delete root folder
940 return array(
941 new ezcWebdavErrorResponse(
942 ezcWebdavResponse::STATUS_403,
943 $fullPath
944 ),
945 );
946 }
947
948 if ( $target === "" )
949 {
950 // Cannot delete entries in site list
951 return array(
952 new ezcWebdavErrorResponse(
953 ezcWebdavResponse::STATUS_403,
954 $fullPath
955 ),
956 );
957 }
958
959 return $errors;
960 }
961
977 protected function performDelete( $target )
978 {
979 switch ( $_SERVER['REQUEST_METHOD'] )
980 {
981 case 'MOVE':
982 // in case performDelete() was called from a MOVE operation,
983 // do not delete anything, because the move() function in
984 // ezcWebdavSimpleBackend first calls performDelete(), which
985 // deletes the destination if the source and destination
986 // are the same in URL alias terms
987 return null;
988
989 default:
990 $errors = $this->checkDeleteRecursive( $target );
991 break;
992 }
993
994 // If an error will occur return the proper status. We return
995 // multistatus in any case.
996 if ( count( $errors ) > 0 )
997 {
998 return new ezcWebdavMultistatusResponse(
999 $errors
1000 );
1001 }
1002
1003 $fullPath = $target;
1004 $target = $this->splitFirstPathElement( $target, $currentSite );
1005
1006 $status = $this->deleteVirtualFolder( $currentSite, $target );
1007 // @as @todo return based on $status
1008
1009 // Return success
1010 return null;
1011 }
1012
1029 public function copy( ezcWebdavCopyRequest $request )
1030 {
1031 $this->acquireLock();
1032 $return = parent::copy( $request );
1033 $this->freeLock();
1034
1035 return $return;
1036 }
1037
1062 protected function performCopy( $source, $destination, $depth = ezcWebdavRequest::DEPTH_INFINITY )
1063 {
1064 switch ( $_SERVER['REQUEST_METHOD'] )
1065 {
1066 case 'MOVE':
1067 // in case performCopy() was called from a MOVE operation,
1068 // do a real move operation, because the move() function
1069 // from ezcWebdavSimpleBackend calls performCopy() and
1070 // performDelete()
1071 $errors = $this->moveRecursive( $source, $destination, $depth );
1072 break;
1073
1074 case 'COPY':
1075 $errors = $this->copyRecursive( $source, $destination, $depth );
1076 break;
1077
1078 default:
1079 $errors = $this->moveRecursive( $source, $destination, $depth );
1080 break;
1081 }
1082
1083 // Transform errors
1084 foreach ( $errors as $nr => $error )
1085 {
1086 $errors[$nr] = new ezcWebdavErrorResponse(
1087 ezcWebdavResponse::STATUS_423,
1088 $error
1089 );
1090 }
1091
1092 // Copy dead properties
1093 $storage = $this->getPropertyStorage( $source );
1094 $this->storeProperties( $destination, $storage );
1095
1096 // Updateable live properties are updated automagically, because they
1097 // are regenerated on request on base of the file they affect. So there
1098 // is no reason to keep them "alive".
1099
1100 return $errors;
1101 }
1102
1120 public function copyRecursive( $source, $destination, $depth = ezcWebdavRequest::DEPTH_INFINITY )
1121 {
1122 $errors = array();
1123 $fullSource = $source;
1124 $fullDestination = $destination;
1125 $source = $this->splitFirstPathElement( $source, $sourceSite );
1126 $destination = $this->splitFirstPathElement( $destination, $destinationSite );
1127
1128 if ( $sourceSite !== $destinationSite )
1129 {
1130 // We do not support copying from one site to another yet
1131 // TODO: Check if the sites are using the same db,
1132 // if so allow the copy as a simple object copy
1133 // If not we will have to do an object export from
1134 // $sourceSite and import it in $destinationSite
1135 return array(); // @as self::FAILED_FORBIDDEN;
1136 }
1137
1138 if ( !$sourceSite or
1139 !$destinationSite )
1140 {
1141 // Cannot copy entries in site list
1142 return array( $fullSource ); // @as self::FAILED_FORBIDDEN;
1143 }
1144
1145 $this->copyVirtualFolder( $sourceSite, $destinationSite,
1146 $source, $destination );
1147
1148 if ( $depth === ezcWebdavRequest::DEPTH_ZERO || !$this->isCollection( $fullSource ) )
1149 {
1150 // Do not recurse (any more)
1151 return array();
1152 }
1153
1154 // Recurse
1155 $nodes = $this->getCollectionMembers( $fullSource );
1156 foreach ( $nodes as $node )
1157 {
1158 if ( $node->path === $fullSource . '/' )
1159 {
1160 // skip the current node which was copied with copyVirtualFolder() above
1161 continue;
1162 }
1163
1164 $newDepth = ( $depth !== ezcWebdavRequest::DEPTH_ONE ) ? $depth : ezcWebdavRequest::DEPTH_ZERO;
1165 $errors = array_merge(
1166 $errors,
1167 $this->copyRecursive( $node->path,
1168 $fullDestination . '/' . $this->getProperty( $node->path, 'displayname' )->displayName,
1169 $newDepth ) );
1170 }
1171
1172 return $errors;
1173 }
1174
1192 public function moveRecursive( $source, $destination, $depth = ezcWebdavRequest::DEPTH_INFINITY )
1193 {
1194 $errors = array();
1195 $fullSource = $source;
1196 $fullDestination = $destination;
1197 $source = $this->splitFirstPathElement( $source, $sourceSite );
1198 $destination = $this->splitFirstPathElement( $destination, $destinationSite );
1199
1200 if ( $sourceSite !== $destinationSite )
1201 {
1202 // We do not support copying from one site to another yet
1203 // TODO: Check if the sites are using the same db,
1204 // if so allow the copy as a simple object copy
1205 // If not we will have to do an object export from
1206 // $sourceSite and import it in $destinationSite
1207 return array(); // @as self::FAILED_FORBIDDEN;
1208 }
1209
1210 if ( !$sourceSite or
1211 !$destinationSite )
1212 {
1213 // Cannot copy entries in site list
1214 return array( $fullSource ); // @as self::FAILED_FORBIDDEN;
1215 }
1216
1217 $this->moveVirtualFolder( $sourceSite, $destinationSite,
1218 $source, $destination,
1219 $fullSource, $fullDestination );
1220
1221 if ( $depth === ezcWebdavRequest::DEPTH_ZERO || !$this->isCollection( $fullSource ) )
1222 {
1223 // Do not recurse (any more)
1224 return array();
1225 }
1226
1227 // Recurse
1228 $nodes = $this->getCollectionMembers( $fullSource );
1229 foreach ( $nodes as $node )
1230 {
1231 if ( $node->path === $fullSource . '/' )
1232 {
1233 // skip the current node which was copied with copyVirtualFolder() above
1234 continue;
1235 }
1236
1237 $newDepth = ( $depth !== ezcWebdavRequest::DEPTH_ONE ) ? $depth : ezcWebdavRequest::DEPTH_ZERO;
1238 $errors = array_merge(
1239 $errors,
1240 $this->moveRecursive( $node->path,
1241 $fullDestination . '/' . $this->getProperty( $node->path, 'displayname' )->displayName,
1242 $newDepth ) );
1243 }
1244
1245 return $errors;
1246 }
1247
1264 public function move( ezcWebdavMoveRequest $request )
1265 {
1266 $this->acquireLock();
1267 $return = parent::move( $request );
1268 $this->freeLock();
1269
1270 return $return;
1271 }
1272
1288 public function makeCollection( ezcWebdavMakeCollectionRequest $request )
1289 {
1290 $this->acquireLock();
1291 $return = parent::makeCollection( $request );
1292 $this->freeLock();
1293
1294 return $return;
1295 }
1296
1297
1309 public function options( ezcWebdavOptionsRequest $request )
1310 {
1311 $response = new ezcWebdavOptionsResponse( '1' );
1312
1313 // Always allowed
1314 $allowed = 'GET, HEAD, PROPFIND, PROPPATCH, OPTIONS, ';
1315
1316 // Check if modifications are allowed
1317 if ( $this instanceof ezcWebdavBackendChange )
1318 {
1319 $allowed .= 'DELETE, COPY, MOVE, ';
1320 }
1321
1322 // Check if MKCOL is allowed
1323 if ( $this instanceof ezcWebdavBackendMakeCollection )
1324 {
1325 $allowed .= 'MKCOL, ';
1326 }
1327
1328 // Check if PUT is allowed
1329 if ( $this instanceof ezcWebdavBackendPut )
1330 {
1331 $allowed .= 'PUT, ';
1332 }
1333
1334 // Check if LOCK and UNLOCK are allowed
1335 if ( $this instanceof ezcWebdavLockBackend )
1336 {
1337 $allowed .= 'LOCK, UNLOCK, ';
1338 }
1339
1340 $response->setHeader( 'Allow', substr( $allowed, 0, -2 ) );
1341
1342 return $response;
1343 }
1344
1345
1346 // Exponential functionality -----------------------------------------
1347
1348
1357 public function setCurrentSite( $site )
1358 {
1359 eZWebDAVContentBackend::appendLogEntry( __FUNCTION__ . '1:' . $site );
1360 $access = array( 'name' => $site,
1361 'type' => eZSiteAccess::TYPE_STATIC );
1362
1363 $access = eZSiteAccess::change( $access );
1364 eZWebDAVContentBackend::appendLogEntry( __FUNCTION__ . '2:' . $site );
1365
1366 eZDebugSetting::writeDebug( 'kernel-siteaccess', $access, 'current siteaccess' );
1367
1368 // Clear/flush global database instance.
1369 $nullVar = null;
1370 eZDB::setInstance( $nullVar );
1371 }
1372
1383 public function currentSiteFromPath( $path )
1384 {
1385 $indexDir = eZSys::indexDir();
1386
1387 // Remove indexDir if used in non-virtualhost mode.
1388 if ( preg_match( "#^" . preg_quote( $indexDir ) . "(.+)$#", $path, $matches ) )
1389 {
1390 $path = $matches[1];
1391 }
1392
1393 foreach ( $this->availableSites as $site )
1394 {
1395 // Check if given path starts with this site-name, if so: return it.
1396 if ( preg_match( "#^/" . preg_quote( $site ) . "(.*)$#", $path, $matches ) )
1397 {
1398 return $site;
1399 }
1400 }
1401
1402 return false;
1403 }
1404
1424 protected function fetchNodeInfo( $target, &$node )
1425 {
1426 // When finished, we'll return an array of attributes/properties.
1427 $entry = array();
1428
1429 $classIdentifier = $node->attribute( 'class_identifier' );
1430
1431 $object = $node->attribute( 'object' );
1432 $urlAlias = $node->urlAlias();
1433
1434 // By default, everything is displayed as a folder:
1435 // Trim the name of the node, it is in some cases whitespace in Exponential
1436 $name = trim( $node->attribute( 'name' ) );
1437
1438 // @as 2009-03-09: return node_id as displayname in case name is missing
1439 // displayname is not actually used by WebDAV clients
1440 $entry["name"] = ( $name !== '' && $name !== NULL ) ? $name : $node->attribute( 'node_id' );
1441 $entry["size"] = 0;
1442 $entry["mimetype"] = self::DIRECTORY_MIMETYPE;
1443 eZWebDAVContentBackend::appendLogEntry( 'FetchNodeInfo:' . $node->attribute( 'name' ) . '/' . $urlAlias );
1444
1445 // @todo handle articles as files
1446 // if ( $classIdentifier === 'article' )
1447 // {
1448 // $entry["mimetype"] = 'application/ms-word';
1449 // }
1450
1451 $entry["ctime"] = $object->attribute( 'published' );
1452 $entry["mtime"] = $object->attribute( 'modified' );
1453
1454 $upload = new eZContentUpload();
1455 $info = $upload->objectFileInfo( $object );
1456
1457 $suffix = '';
1458 $class = $object->contentClass();
1459 $isObjectFolder = $this->isObjectFolder( $object, $class );
1460
1461 if ( $isObjectFolder )
1462 {
1463 // We do nothing, the default is to see it as a folder
1464 }
1465 else if ( $info )
1466 {
1467 $filePath = $info['filepath'];
1468 $entry['filepath'] = $filePath;
1469 $entry["mimetype"] = false;
1470 $entry["size"] = false;
1471 if ( isset( $info['filesize'] ) )
1472 {
1473 $entry['size'] = $info['filesize'];
1474 }
1475 if ( isset( $info['mime_type'] ) )
1476 {
1477 $entry['mimetype'] = $info['mime_type'];
1478 }
1479
1480 // Fill in information from the actual file if they are missing.
1481 $file = eZClusterFileHandler::instance( $filePath );
1482 if ( !$entry['size'] and $file->exists() )
1483 {
1484 $entry["size"] = $file->size();
1485 }
1486 if ( !$entry['mimetype'] )
1487 {
1488 $mimeInfo = eZMimeType::findByURL( $filePath );
1489 $entry["mimetype"] = $mimeInfo['name'];
1490
1491 $suffix = $mimeInfo['suffix'];
1492
1493 if ( strlen( $suffix ) > 0 )
1494 {
1495 $entry["name"] .= '.' . $suffix;
1496 }
1497 }
1498 else
1499 {
1500 // eZMimeType returns first suffix in its list
1501 // this could be another one than the original file extension
1502 // so let's try to get the suffix from the file path first
1503 $suffix = eZFile::suffix( $filePath );
1504 if ( !$suffix )
1505 {
1506 $mimeInfo = eZMimeType::findByName( $entry['mimetype'] );
1507 $suffix = $mimeInfo['suffix'];
1508 }
1509
1510 if ( strlen( $suffix ) > 0 )
1511 {
1512 $entry["name"] .= '.' . $suffix;
1513 }
1514 }
1515
1516 if ( $file->exists() )
1517 {
1518 $entry["ctime"] = $file->mtime();
1519 $entry["mtime"] = $file->mtime();
1520 }
1521 }
1522 else
1523 {
1524 // Here we only show items as folders if they have
1525 // is_container set to true, otherwise it's an unknown binary file
1526 if ( !$class->attribute( 'is_container' ) )
1527 {
1528 $entry['mimetype'] = 'application/octet-stream';
1529 }
1530 }
1531
1532 $scriptURL = $target;
1533 if ( strlen( $scriptURL ) > 0 and $scriptURL[ strlen( $scriptURL ) - 1 ] !== "/" )
1534 {
1535 $scriptURL .= "/";
1536 }
1537
1538 $trimmedScriptURL = trim( $scriptURL, '/' );
1539 $scriptURLParts = explode( '/', $trimmedScriptURL );
1540
1541 $urlPartCount = count( $scriptURLParts );
1542
1543 if ( $urlPartCount >= 2 )
1544 {
1545 // one of the virtual folders
1546 // or inside one of the virtual folders
1547 $siteAccess = $scriptURLParts[0];
1548 $virtualFolder = $scriptURLParts[1];
1549
1550 // only when the virtual folder is Content we need to add its path to the start URL
1551 // the paths of other top level folders (like Media) are included in URL aliases of their descending nodes
1552 if ( $virtualFolder === self::virtualContentFolderName() )
1553 {
1554 $startURL = '/' . $siteAccess . '/' . $virtualFolder . '/';
1555 }
1556 // Media folder is special since the virtual folder name is translated via ezpI18n (@see self::virtualMediaFolderName())
1557 // but the URL Alias of this top node can vary (depends if content objects are available in the current siteaccess's language).
1558 // So we need to replace the media folder URL Alias part by the one translated via ezpI18n, which never varies.
1559 // Otherwise unexpected errors can occurred, depending on WebDAV client, especially when URL Alias from media child nodes
1560 // doesn't match EXACTLY with the virtual media folder name.
1561 // e.g. : having "Média" as virtual media folder name and a child node with Media/Images (without accent) as URL alias will break.
1562 // See http://issues.ez.no/15035
1563 else if ( $virtualFolder === self::virtualMediaFolderName() )
1564 {
1565 $startURL = '/' . $siteAccess . '/' . $virtualFolder . '/';
1566 $urlAlias = substr( $urlAlias, strpos( $urlAlias, '/' ) + 1 );
1567 }
1568 else
1569 {
1570 $startURL = '/' . $siteAccess . '/';
1571 }
1572 }
1573 else
1574 {
1575 // site access level
1576 $startURL = $scriptURL;
1577 }
1578
1579 // Set the href attribute (note that it doesn't just equal the name).
1580 if ( !isset( $entry['href'] ) )
1581 {
1582 if ( strlen( $suffix ) > 0 )
1583 {
1584 $suffix = '.' . $suffix;
1585 }
1586
1587 $entry["href"] = $startURL . $urlAlias . $suffix;
1588 }
1589
1590 // Return array of attributes/properties (name, size, mime, times, etc.).
1591 return $entry;
1592 }
1593
1610 protected function getVirtualFolderData( $result, $currentSite, $target, $fullPath )
1611 {
1612 $target = $this->splitFirstPathElement( $target, $virtualFolder );
1613 if ( !$target )
1614 {
1615 // The rest in the virtual folder does not have any data
1616 return false; // self::FAILED_NOT_FOUND;
1617 }
1618
1619 if ( !in_array( $virtualFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
1620 {
1621 return false; // self::FAILED_NOT_FOUND;
1622 }
1623
1624 if ( $virtualFolder === self::virtualContentFolderName() or
1625 $virtualFolder === self::virtualMediaFolderName() )
1626 {
1627 return $this->getContentNodeData( $result, $currentSite, $virtualFolder, $target, $fullPath );
1628 }
1629 return false; // self::FAILED_NOT_FOUND;
1630 }
1631
1650 protected function getContentNodeData( $result, $currentSite, $virtualFolder, $target, $fullPath )
1651 {
1652 // Attempt to fetch the node the client wants to get.
1653 $nodePath = $this->internalNodePath( $virtualFolder, $target );
1654 eZWebDAVContentBackend::appendLogEntry( __FUNCTION__ . " Path:" . $nodePath );
1655 $node = $this->fetchNodeByTranslation( $nodePath );
1656 $info = $this->fetchNodeInfo( $fullPath, $node );
1657
1658 // Proceed only if the node is valid:
1659 if ( $node === null )
1660 {
1661 return $result;
1662 }
1663
1664 // Can we fetch the contents of the node
1665 if ( !$node->canRead() )
1666 {
1667 return false; // @as self::FAILED_FORBIDDEN;
1668 }
1669
1670 $object = $node->attribute( 'object' );
1671
1672 foreach ( $info as $key => $value )
1673 {
1674 $result[$key] = $value;
1675 }
1676
1677 $upload = new eZContentUpload();
1678 $info = $upload->objectFileInfo( $object );
1679
1680 if ( $info )
1681 {
1682 $result['file'] = $info['filepath'];
1683 }
1684 else
1685 {
1686 $class = $object->contentClass();
1687 if ( $this->isObjectFolder( $object, $class ) )
1688 {
1689 $result['isCollection'] = true;
1690 }
1691
1692 }
1693 return $result;
1694 }
1695
1708 protected function getCollectionContent( $collection, $depth = false, $properties = false )
1709 {
1710 $fullPath = $collection;
1711 $collection = $this->splitFirstPathElement( $collection, $currentSite );
1712
1713 if ( !$currentSite )
1714 {
1715 // Display the root which contains a list of sites
1716 $entries = $this->fetchSiteListContent( $fullPath, $depth, $properties );
1717 return $entries;
1718 }
1719
1720 return $this->getVirtualFolderCollection( $currentSite, $collection, $fullPath, $depth, $properties );
1721 }
1722
1742 protected function fetchContainerNodeInfo( $fullPath, $site, $nodeName )
1743 {
1744 $contentEntry = array();
1745 $contentEntry["name"] = $nodeName;
1746 $contentEntry["size"] = 0;
1747 $contentEntry["mimetype"] = self::DIRECTORY_MIMETYPE;
1748 $contentEntry["ctime"] = filectime( 'settings/siteaccess/' . $site );
1749 $contentEntry["mtime"] = filemtime( 'settings/siteaccess/' . $site );
1750 $contentEntry["href"] = $fullPath;
1751
1752 $entries[] = $contentEntry;
1753
1754 return $entries;
1755 }
1756
1780 protected function fetchVirtualSiteContent( $target, $site, $depth, $properties )
1781 {
1782 $requestUri = $target;
1783
1784 // Always add the current collection
1785 $contentEntry = array();
1786 $scriptURL = $requestUri;
1787 if ( $scriptURL{strlen( $scriptURL ) - 1} !== '/' )
1788 {
1789 $scriptURL .= "/";
1790 }
1791 $contentEntry["name"] = $scriptURL;
1792 $contentEntry["size"] = 0;
1793 $contentEntry["mimetype"] = self::DIRECTORY_MIMETYPE;
1794 $contentEntry["ctime"] = filectime( 'settings/siteaccess/' . $site );
1795 $contentEntry["mtime"] = filemtime( 'settings/siteaccess/' . $site );
1796 $contentEntry["href"] = $requestUri;
1797 $entries[] = $contentEntry;
1798
1799 $defctime = $contentEntry['ctime'];
1800 $defmtime = $contentEntry['mtime'];
1801
1802 if ( $depth > 0 )
1803 {
1804 $scriptURL = $requestUri;
1805 if ( $scriptURL{strlen( $scriptURL ) - 1} !== '/' )
1806 {
1807 $scriptURL .= "/";
1808 }
1809
1810 // Set up attributes for the virtual content folder:
1811 foreach ( array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) as $name )
1812 {
1813 $entry = array();
1814 $entry["name"] = $name;
1815 $entry["size"] = 0;
1816 $entry["mimetype"] = self::DIRECTORY_MIMETYPE;
1817 $entry["ctime"] = $defctime;
1818 $entry["mtime"] = $defmtime;
1819 $entry["href"] = $scriptURL . $name;
1820
1821 $entries[] = $entry;
1822 }
1823 }
1824
1825 return $entries;
1826 }
1827
1849 protected function getVirtualFolderCollection( $currentSite, $collection, $fullPath, $depth, $properties )
1850 {
1851 if ( !$collection )
1852 {
1853 // We are inside a site so we display the virtual folder for the site
1854 $entries = $this->fetchVirtualSiteContent( $fullPath, $currentSite, $depth, $properties );
1855 return $entries;
1856 }
1857
1858 $collection = $this->splitFirstPathElement( $collection, $virtualFolder );
1859
1860 if ( !in_array( $virtualFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
1861 {
1862 return false; // self::FAILED_NOT_FOUND;
1863 }
1864
1865 // added by @ds 2008-12-07 to fix problems with IE6 SP2
1866 $ini = eZINI::instance();
1867 $prefixAdded = false;
1868 $prefix = $ini->hasVariable( 'SiteAccessSettings', 'PathPrefix' ) &&
1869 $ini->variable( 'SiteAccessSettings', 'PathPrefix' ) != '' ? eZURLAliasML::cleanURL( $ini->variable( 'SiteAccessSettings', 'PathPrefix' ) ) : false;
1870
1871 if ( $prefix )
1872 {
1873 $escapedPrefix = preg_quote( $prefix, '#' );
1874 // Only prepend the path prefix if it's not already the first element of the url.
1875 if ( !preg_match( "#^$escapedPrefix(/.*)?$#i", $collection ) )
1876 {
1877 $exclude = $ini->hasVariable( 'SiteAccessSettings', 'PathPrefixExclude' )
1878 ? $ini->variable( 'SiteAccessSettings', 'PathPrefixExclude' )
1879 : false;
1880 $breakInternalURI = false;
1881 foreach ( $exclude as $item )
1882 {
1883 $escapedItem = preg_quote( $item, '#' );
1884 if ( preg_match( "#^$escapedItem(/.*)?$#i", $collection ) )
1885 {
1886 $breakInternalURI = true;
1887 break;
1888 }
1889 }
1890
1891 if ( !$breakInternalURI )
1892 {
1893 $collection = $prefix . '/' . $collection;
1894 $prefixAdded = true;
1895 }
1896 }
1897 }
1898
1899 return $this->getContentTreeCollection( $currentSite, $virtualFolder, $collection, $fullPath, $depth, $properties );
1900 }
1901
1926 protected function getContentTreeCollection( $currentSite, $virtualFolder, $collection, $fullPath, $depth, $properties )
1927 {
1928 $nodePath = $this->internalNodePath( $virtualFolder, $collection );
1929 $node = $this->fetchNodeByTranslation( $nodePath );
1930
1931 if ( !$node )
1932 {
1933 return false; // self::FAILED_NOT_FOUND;
1934 }
1935
1936 // Can we list the children of the node?
1937 if ( !$node->canRead() )
1938 {
1939 return false; // self::FAILED_FORBIDDEN;
1940 }
1941
1942 $entries = $this->fetchContentList( $fullPath, $node, $nodePath, $depth, $properties );
1943 return $entries;
1944 }
1945
1969 protected function fetchContentList( $fullPath, &$node, $target, $depth, $properties )
1970 {
1971 // We'll return an array of entries (which is an array of attributes).
1972 $entries = array();
1973
1974 if ( $depth === ezcWebdavRequest::DEPTH_ONE || $depth === ezcWebdavRequest::DEPTH_INFINITY )
1975 // @as added || $depth === ezcWebdavRequest::DEPTH_INFINITY
1976 {
1977 // Get all the children of the target node.
1978 $subTree = $node->subTree( array ( 'Depth' => 1 ) );
1979
1980 // Build the entries array by going through all the
1981 // nodes in the subtree and getting their attributes:
1982 foreach ( $subTree as $someNode )
1983 {
1984 $entries[] = $this->fetchNodeInfo( $fullPath, $someNode );
1985 }
1986 }
1987
1988 // Always include the information about the current level node
1989 $thisNodeInfo = $this->fetchNodeInfo( $fullPath, $node );
1990
1991 $scriptURL = $fullPath;
1992 if ( $scriptURL{strlen( $scriptURL ) - 1} !== '/' )
1993 {
1994 $scriptURL .= "/";
1995 }
1996
1997 $thisNodeInfo["href"] = $scriptURL;
1998 $entries[] = $thisNodeInfo;
1999
2000 // Return the content of the target.
2001 return $entries;
2002 }
2003
2022 protected function fetchSiteListContent( $target, $depth, $properties )
2023 {
2024 // At the end: we'll return an array of entry-arrays.
2025 $entries = array();
2026
2027 // An entry consists of several attributes (name, size, etc).
2028 $contentEntry = array();
2029 $entries = array();
2030
2031 // add a slash at the end of the path, if it is missing
2032 $scriptURL = $target;
2033 if ( $scriptURL{strlen( $scriptURL ) - 1} !== '/' )
2034 {
2035 $scriptURL .= "/";
2036 }
2037
2038 $thisNodeInfo["href"] = $scriptURL;
2039
2040 // Set up attributes for the virtual site-list folder:
2041 $contentEntry["name"] = '/';
2042 $contentEntry["href"] = $scriptURL;
2043 $contentEntry["size"] = 0;
2044 $contentEntry["mimetype"] = self::DIRECTORY_MIMETYPE;
2045 $contentEntry["ctime"] = filectime( 'var' );
2046 $contentEntry["mtime"] = filemtime( 'var' );
2047
2048 $entries[] = $contentEntry;
2049
2050 if ( $depth > 0 )
2051 {
2052 // For all available sites:
2053 foreach ( $this->availableSites as $site )
2054 {
2055 // Set up attributes for the virtual site-list folder:
2056 $contentEntry["name"] = $scriptURL . $site . '/'; // @as added '/'
2057 $contentEntry["size"] = 0;
2058 $contentEntry["mimetype"] = self::DIRECTORY_MIMETYPE;
2059 $contentEntry["ctime"] = filectime( 'settings/siteaccess/' . $site );
2060 $contentEntry["mtime"] = filemtime( 'settings/siteaccess/' . $site );
2061
2062 if ( $target === '/' )
2063 {
2064 $contentEntry["href"] = $contentEntry["name"];
2065 }
2066 else
2067 {
2068 $contentEntry["href"] = $scriptURL . $contentEntry["name"];
2069 }
2070
2071 $entries[] = $contentEntry;
2072 }
2073 }
2074
2075 return $entries;
2076 }
2077
2085 protected function fetchNodeByTranslation( $nodePathString )
2086 {
2087 // Get rid of possible extensions, remove .jpeg .txt .html etc..
2088 $nodePathString = $this->fileBasename( $nodePathString );
2089
2090 // Strip away last slash
2091 if ( strlen( $nodePathString ) > 0 and
2092 $nodePathString[strlen( $nodePathString ) - 1] === '/' )
2093 {
2094 $nodePathString = substr( $nodePathString, 0, strlen( $nodePathString ) - 1 );
2095 }
2096
2097 if ( strlen( $nodePathString ) > 0 )
2098 {
2099 $nodePathString = eZURLAliasML::convertPathToAlias( $nodePathString );
2100 }
2101
2102 $nodeID = eZURLAliasML::fetchNodeIDByPath( $nodePathString );
2103 if ( $nodeID == 2 )
2104 {
2105 // added by @ds 2008-12-07 to fix problems with IE6 SP2
2106 $ini = eZINI::instance( 'webdav.ini' );
2107 if ( $ini->hasVariable( 'GeneralSettings', 'StartNode' ) )
2108 {
2109 $nodeID = $ini->variable( 'GeneralSettings', 'StartNode' );
2110 }
2111 }
2112 elseif ( $nodeID )
2113 {
2114 }
2115 else
2116 {
2117 return false;
2118 }
2119
2120 // Attempt to fetch the node.
2121 $node = eZContentObjectTreeNode::fetch( $nodeID );
2122
2123 // Return the node.
2124 return $node;
2125 }
2126
2137 protected function fetchParentNodeByTranslation( $nodePathString )
2138 {
2139 // Strip extensions. E.g. .jpg
2140 $nodePathString = $this->fileBasename( $nodePathString );
2141
2142 // Strip away last slash
2143 if ( strlen( $nodePathString ) > 0 and
2144 $nodePathString[strlen( $nodePathString ) - 1] === '/' )
2145 {
2146 $nodePathString = substr( $nodePathString, 0, strlen( $nodePathString ) - 1 );
2147 }
2148
2149 $nodePathString = $this->splitLastPathElement( $nodePathString, $element );
2150
2151 if ( strlen( $nodePathString ) === 0 )
2152 {
2153 $nodePathString = '/';
2154 }
2155
2156 $nodePathString = eZURLAliasML::convertPathToAlias( $nodePathString );
2157
2158 // Attempt to translate the URL to something like "/content/view/full/84".
2159 $translateResult = eZURLAliasML::translate( $nodePathString );
2160
2161 // handle redirects
2162 while ( $nodePathString === 'error/301' )
2163 {
2164 $nodePathString = $translateResult;
2165
2166 $translateResult = eZURLAliasML::translate( $nodePathString );
2167 }
2168
2169 // Get the ID of the node (which is the last part of the translated path).
2170 if ( preg_match( "#^content/view/full/([0-9]+)$#", $nodePathString, $matches ) )
2171 {
2172 $nodeID = $matches[1];
2173 }
2174 else
2175 {
2176 $ini = eZINI::instance( 'webdav.ini' );
2177 if ( $ini->hasVariable( 'GeneralSettings', 'StartNode' ) )
2178 {
2179 $nodeID = $ini->variable( 'GeneralSettings', 'StartNode' );
2180 }
2181 }
2182
2183 // Attempt to fetch the node.
2184 $node = eZContentObjectTreeNode::fetch( $nodeID );
2185
2186 // Return the node.
2187 return $node;
2188 }
2189
2196 protected function createCollection( $target )
2197 {
2198 $target = $this->splitFirstPathElement( $target, $currentSite );
2199
2200 if ( !$currentSite )
2201 {
2202 // Site list cannot get new entries
2203 return false; // @as self::FAILED_FORBIDDEN;
2204 }
2205
2206 return $this->mkcolVirtualFolder( $currentSite, $target );
2207 }
2208
2219 protected function mkcolVirtualFolder( $currentSite, $target )
2220 {
2221 $target = $this->splitFirstPathElement( $target, $virtualFolder );
2222
2223 if ( !in_array( $virtualFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
2224 {
2225 return false; // @as self::FAILED_NOT_FOUND;
2226 }
2227
2228 if ( !$target )
2229 {
2230 // We have reached the end of the path
2231 // We do not allow 'mkcol' operations for the virtual folder.
2232 return false; // @as self::FAILED_FORBIDDEN;
2233 }
2234
2235 if ( $virtualFolder === self::virtualContentFolderName() or
2236 $virtualFolder === self::virtualMediaFolderName() )
2237 {
2238 return $this->mkcolContent( $currentSite, $virtualFolder, $target );
2239 }
2240
2241 return false; // @as self::FAILED_FORBIDDEN;
2242 }
2243
2255 protected function mkcolContent( $currentSite, $virtualFolder, $target )
2256 {
2257 $nodePath = $this->internalNodePath( $virtualFolder, $target );
2258 $node = $this->fetchNodeByTranslation( $nodePath );
2259 if ( $node )
2260 {
2261 return false; // @as self::FAILED_EXISTS;
2262 }
2263
2264 $parentNode = $this->fetchParentNodeByTranslation( $nodePath );
2265
2266 if ( !$parentNode )
2267 {
2268 return false; // @as self::FAILED_NOT_FOUND;
2269 }
2270
2271 // Can we create a collection in the parent node
2272 if ( !$parentNode->canRead() )
2273 {
2274 return false; // @as self::FAILED_FORBIDDEN;
2275 }
2276
2277 return $this->createFolder( $parentNode, $nodePath );
2278 }
2279
2287 protected function createFolder( $parentNode, $target )
2288 {
2289 // Grab settings from the ini file:
2290 $webdavINI = eZINI::instance( self::WEBDAV_INI_FILE );
2291 $folderClassID = $webdavINI->variable( 'FolderSettings', 'FolderClass' );
2292 $languageCode = eZContentObject::defaultLanguage();
2293
2294 $contentObject = eZContentObject::createWithNodeAssignment( $parentNode, $folderClassID, $languageCode );
2295 if ( $contentObject )
2296 {
2297 $db = eZDB::instance();
2298 $db->begin();
2299 $version = $contentObject->version( 1 );
2300 $version->setAttribute( 'status', eZContentObjectVersion::STATUS_DRAFT );
2301 $version->store();
2302
2303 $contentObjectID = $contentObject->attribute( 'id' );
2304 $contentObjectAttributes = $version->contentObjectAttributes();
2305
2306 // @todo @as avoid using [0] (could be another index in some classes)
2307 $contentObjectAttributes[0]->setAttribute( 'data_text', basename( $target ) );
2308 $contentObjectAttributes[0]->store();
2309 $db->commit();
2310
2311 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID,
2312 'version' => 1 ) );
2313 return true; // @as self::OK_CREATED;
2314 }
2315 else
2316 {
2317 return false; // @as self::FAILED_FORBIDDEN;
2318 }
2319 }
2320
2331 protected function deleteVirtualFolder( $currentSite, $target )
2332 {
2333 $target = $this->splitFirstPathElement( $target, $virtualFolder );
2334
2335 if ( !in_array( $virtualFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
2336 {
2337 return false; // @as self::FAILED_NOT_FOUND;
2338 }
2339
2340 if ( !$target )
2341 {
2342 // We have reached the end of the path
2343 // We do not allow 'delete' operations for the virtual folder.
2344 return false; // @as self::FAILED_FORBIDDEN;
2345 }
2346
2347 if ( $virtualFolder === self::virtualContentFolderName() or
2348 $virtualFolder === self::virtualMediaFolderName() )
2349 {
2350 return $this->deleteContent( $currentSite, $virtualFolder, $target );
2351 }
2352
2353 return false; // @as self::FAILED_FORBIDDEN;
2354 }
2355
2367 protected function deleteContent( $currentSite, $virtualFolder, $target )
2368 {
2369 $nodePath = $this->internalNodePath( $virtualFolder, $target );
2370 $node = $this->fetchNodeByTranslation( $nodePath );
2371
2372 if ( $node === null )
2373 {
2374 return false; // @as self::FAILED_NOT_FOUND;
2375 }
2376
2377 // Can we delete the node?
2378 if ( !$node->canRead() or
2379 !$node->canRemove() )
2380 {
2381 return false; // @as self::FAILED_FORBIDDEN;
2382 }
2383
2384 // added by @as: use the content.ini setting for handling delete: 'delete' or 'trash'
2385 // default is 'trash'
2386 $contentINI = eZINI::instance( 'content.ini' );
2387 $removeAction = $contentINI->hasVariable( 'RemoveSettings', 'DefaultRemoveAction' ) ?
2388 $contentINI->variable( 'RemoveSettings', 'DefaultRemoveAction' ) : 'trash';
2389
2390 if ( $removeAction !== 'trash' && $removeAction !== 'delete' )
2391 {
2392 // default remove action is to trash
2393 $removeAction = 'trash';
2394 }
2395
2396 $moveToTrash = ( $removeAction === 'trash' ) ? true : false;
2397
2398 $node->removeNodeFromTree( $moveToTrash );
2399 return true; // @as self::OK;
2400 }
2401
2413 protected function putVirtualFolderData( $currentSite, $target, $tempFile )
2414 {
2415 $target = $this->splitFirstPathElement( $target, $virtualFolder );
2416
2417 if ( !$target )
2418 {
2419 // We have reached the end of the path
2420 // We do not allow 'put' operations for the virtual folder.
2421 return false; // @as self::FAILED_FORBIDDEN;
2422 }
2423
2424 if ( !in_array( $virtualFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
2425 {
2426 return false; // @as self::FAILED_CONFLICT;
2427 }
2428
2429 if ( $virtualFolder === self::virtualContentFolderName() or
2430 $virtualFolder === self::virtualMediaFolderName() )
2431 {
2432 $result = $this->putContentData( $currentSite, $virtualFolder, $target, $tempFile );
2433 return $result;
2434 }
2435
2436 return false; // @as self::FAILED_FORBIDDEN;
2437 }
2438
2452 protected function putContentData( $currentSite, $virtualFolder, $target, $tempFile )
2453 {
2454 $nodePath = $this->internalNodePath( $virtualFolder, $target );
2455
2456 $parentNode = $this->fetchParentNodeByTranslation( $nodePath );
2457 if ( $parentNode === null )
2458 {
2459 // The node does not exist, so we cannot put the file
2460 return false; // @as self::FAILED_CONFLICT;
2461 }
2462
2463 // Can we put content in the parent node
2464 if ( !$parentNode->canRead() )
2465 {
2466 return false; // @as self::FAILED_FORBIDDEN;
2467 }
2468
2469 $parentNodeID = $parentNode->attribute( 'node_id' );
2470
2471 $existingNode = $this->fetchNodeByTranslation( $nodePath );
2472
2473 $upload = new eZContentUpload();
2474
2475 if ( !$upload->handleLocalFile( $result, $tempFile, $parentNodeID, $existingNode ) )
2476 {
2477 if ( $result['status'] === eZContentUpload::STATUS_PERMISSION_DENIED )
2478 {
2479 return false; // @as self::FAILED_FORBIDDEN;
2480 }
2481 else
2482 {
2483 return false; // @as self::FAILED_UNSUPPORTED;
2484 }
2485 }
2486
2487 return true; // @as self::OK_CREATED;
2488 }
2489
2502 protected function copyVirtualFolder( $sourceSite, $destinationSite,
2503 $source, $destination )
2504 {
2505 $source = $this->splitFirstPathElement( $source, $sourceVFolder );
2506 $destination = $this->splitFirstPathElement( $destination, $destinationVFolder );
2507
2508 if ( !in_array( $sourceVFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
2509 {
2510 return false; // @as self::FAILED_NOT_FOUND;
2511 }
2512
2513 if ( !in_array( $destinationVFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
2514 {
2515 return false; // @as self::FAILED_NOT_FOUND;
2516 }
2517
2518 if ( !$source or
2519 !$destination )
2520 {
2521 // We have reached the end of the path for source or destination
2522 // We do not allow 'copy' operations for the virtual folder (from or to)
2523 return false; // @as self::FAILED_FORBIDDEN;
2524 }
2525
2526 if ( ( $sourceVFolder === self::virtualContentFolderName() or
2527 $sourceVFolder === self::virtualMediaFolderName() ) and
2528 ( $destinationVFolder === self::virtualContentFolderName() or
2529 $destinationVFolder === self::virtualMediaFolderName() ) )
2530 {
2531 return $this->copyContent( $sourceSite, $destinationSite,
2532 $sourceVFolder, $destinationVFolder,
2533 $source, $destination );
2534 }
2535
2536 return false; // @as self::FAILED_FORBIDDEN;
2537 }
2538
2550 protected function copyContent( $sourceSite, $destinationSite,
2551 $sourceVFolder, $destinationVFolder,
2552 $source, $destination )
2553 {
2554 $nodePath = $this->internalNodePath( $sourceVFolder, $source );
2555 $destinationNodePath = $this->internalNodePath( $destinationVFolder, $destination );
2556
2557 // Get rid of possible extensions, remove .jpeg .txt .html etc..
2558 $source = $this->fileBasename( $source );
2559
2560 $sourceNode = $this->fetchNodeByTranslation( $nodePath );
2561
2562 if ( !$sourceNode )
2563 {
2564 return false; // @as self::FAILED_NOT_FOUND;
2565 }
2566
2567 $object = $sourceNode->attribute( 'object' );
2568 $classID = $object->attribute( 'contentclass_id' );
2569
2570 // Get rid of possible extensions, remove .jpeg .txt .html etc..
2571 $destination = $this->fileBasename( $destination );
2572
2573 $destinationNode = $this->fetchNodeByTranslation( $destinationNodePath );
2574
2575 // @as @todo check if this is needed
2576 // if ( $destinationNode )
2577 // {
2578 // return false; // @as self::FAILED_EXISTS;
2579 // }
2580
2581 $destinationNode = $this->fetchParentNodeByTranslation( $destinationNodePath );
2582
2583 if ( !$destinationNode )
2584 {
2585 return false; // @as self::FAILED_NOT_FOUND;
2586 }
2587
2588 // Can we move the node to $destinationNode
2589 if ( !$destinationNode->canMoveTo( $classID ) )
2590 {
2591 return false; // @as self::FAILED_FORBIDDEN;
2592 }
2593
2594 $srcParentPath = $this->splitLastPathElement( $nodePath, $srcNodeName );
2595 $dstParentPath = $this->splitLastPathElement( $destinationNodePath, $dstNodeName );
2596 if ( $srcParentPath === $dstParentPath )
2597 {
2598 // @todo check if copy in the same folder is correct
2599 return $this->copyObjectSameDirectory( $sourceNode, $destinationNode, $this->fileBasename( $dstNodeName ) );
2600 }
2601 else
2602 {
2603 // @todo check if copy in different folders is correct
2604 return $this->copyObject( $sourceNode, $destinationNode );
2605 }
2606
2607 /*
2608 // Todo: add lookup of the name setting for the current object
2609 $contentObjectID = $object->attribute( 'id' );
2610 $contentObjectAttributes =& $object->contentObjectAttributes();
2611 // @todo @as avoid using [0] (could be another index in some classes)
2612 $contentObjectAttributes[0]->setAttribute( 'data_text', basename( $destination ) );
2613 $contentObjectAttributes[0]->store();
2614
2615 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 'version' => 1 ) );
2616 $object->store();
2617 */
2618
2619 // @todo Unreachable code?
2620 return true; // @as self::OK_CREATED;
2621 }
2622
2630 protected function copyObject( $object, $newParentNode )
2631 {
2632 $object = $object->ContentObject;
2633 $newParentNodeID = $newParentNode->attribute( 'node_id' );
2634 $classID = $object->attribute( 'contentclass_id' );
2635
2636 if ( !$newParentNode->checkAccess( 'create', $classID ) )
2637 {
2638 $objectID = $object->attribute( 'id' );
2639 return false;
2640 }
2641
2642 $db = eZDB::instance();
2643 $db->begin();
2644 $newObject = $object->copy( true );
2645
2646 // We should reset section that will be updated in updateSectionID().
2647 // If sectionID is 0 than the object has been newly created
2648 $newObject->setAttribute( 'section_id', 0 );
2649 $newObject->store();
2650
2651 $curVersion = $newObject->attribute( 'current_version' );
2652 $curVersionObject = $newObject->attribute( 'current' );
2653 $newObjAssignments = $curVersionObject->attribute( 'node_assignments' );
2654 unset( $curVersionObject );
2655
2656 // remove old node assignments
2657 foreach ( $newObjAssignments as $assignment )
2658 {
2659 $assignment->purge();
2660 }
2661
2662 // and create a new one
2663 $nodeAssignment = eZNodeAssignment::create( array(
2664 'contentobject_id' => $newObject->attribute( 'id' ),
2665 'contentobject_version' => $curVersion,
2666 'parent_node' => $newParentNodeID,
2667 'is_main' => 1
2668 ) );
2669 $nodeAssignment->store();
2670
2671 // publish the newly created object
2672 eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObject->attribute( 'id' ),
2673 'version' => $curVersion ) );
2674 // Update "is_invisible" attribute for the newly created node.
2675 $newNode = $newObject->attribute( 'main_node' );
2676 eZContentObjectTreeNode::updateNodeVisibility( $newNode, $newParentNode );
2677
2678 $db->commit();
2679 return true;
2680 }
2681
2690 protected function copyObjectSameDirectory( $object, $newParentNode, $destinationName = null )
2691 {
2692 $object = $object->ContentObject;
2693 $newParentNodeID = $newParentNode->attribute( 'node_id' );
2694 $classID = $object->attribute( 'contentclass_id' );
2695
2696 if ( !$newParentNode->checkAccess( 'create', $classID ) )
2697 {
2698 $objectID = $object->attribute( 'id' );
2699 return false;
2700 }
2701
2702 $db = eZDB::instance();
2703 $db->begin();
2704 $newObject = $object->copy( true );
2705
2706 // We should reset section that will be updated in updateSectionID().
2707 // If sectionID is 0 than the object has been newly created
2708 $newObject->setAttribute( 'section_id', 0 );
2709
2710 // @as 2009-01-08 - Added check for destination name the same as the source name
2711 // (this was causing problems with nodes disappearing after renaming)
2712 $newName = $destinationName;
2713 if ( $destinationName === null
2714 || strtolower( $destinationName ) === strtolower( $object->attribute( 'name' ) ) )
2715 {
2716 $newName = 'Copy of ' . $object->attribute( 'name' );
2717 }
2718
2719 // @todo @as avoid using [0] (could be another index in some classes)
2720 $contentObjectAttributes = $newObject->contentObjectAttributes();
2721 $contentObjectAttributes[0]->setAttribute( 'data_text', $newName );
2722 $contentObjectAttributes[0]->store();
2723
2724 $newObject->store();
2725
2726 $curVersion = $newObject->attribute( 'current_version' );
2727 $curVersionObject = $newObject->attribute( 'current' );
2728 $newObjAssignments = $curVersionObject->attribute( 'node_assignments' );
2729 unset( $curVersionObject );
2730
2731 // remove old node assignments
2732 foreach ( $newObjAssignments as $assignment )
2733 {
2734 $assignment->purge();
2735 }
2736
2737 // and create a new one
2738 $nodeAssignment = eZNodeAssignment::create( array(
2739 'contentobject_id' => $newObject->attribute( 'id' ),
2740 'contentobject_version' => $curVersion,
2741 'parent_node' => $newParentNodeID,
2742 'is_main' => 1
2743 ) );
2744 $nodeAssignment->store();
2745
2746 // publish the newly created object
2747 eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObject->attribute( 'id' ),
2748 'version' => $curVersion ) );
2749 // Update "is_invisible" attribute for the newly created node.
2750 $newNode = $newObject->attribute( 'main_node' );
2751 eZContentObjectTreeNode::updateNodeVisibility( $newNode, $newParentNode );
2752
2753 $db->commit();
2754 return true;
2755 }
2756
2769 protected function moveVirtualFolder( $sourceSite, $destinationSite,
2770 $source, $destination,
2771 $fullSource, $fullDestination )
2772 {
2773 $this->setCurrentSite( $sourceSite );
2774
2775 $source = $this->splitFirstPathElement( $source, $sourceVFolder );
2776 $destination = $this->splitFirstPathElement( $destination, $destinationVFolder );
2777
2778 if ( !$source or
2779 !$destination )
2780 {
2781 // We have reached the end of the path for source or destination
2782 // We do not allow 'move' operations for the virtual folder (from or to)
2783 return false; // @as self::FAILED_FORBIDDEN;
2784 }
2785
2786 if ( ( $sourceVFolder === self::virtualContentFolderName() or
2787 $sourceVFolder === self::virtualMediaFolderName() ) and
2788 ( $destinationVFolder === self::virtualContentFolderName() or
2789 $destinationVFolder === self::virtualMediaFolderName() ) )
2790 {
2791 return $this->moveContent( $sourceSite, $destinationSite,
2792 $sourceVFolder, $destinationVFolder,
2793 $source, $destination,
2794 $fullSource, $fullDestination );
2795 }
2796
2797 return false; // @as self::FAILED_FORBIDDEN;
2798 }
2799
2811 protected function moveContent( $sourceSite, $destinationSite,
2812 $sourceVFolder, $destinationVFolder,
2813 $source, $destination,
2814 $fullSource, $fullDestination )
2815 {
2816 $nodePath = $this->internalNodePath( $sourceVFolder, $source );
2817 $destinationNodePath = $this->internalNodePath( $destinationVFolder, $destination );
2818
2819 // Get rid of possible extensions, remove .jpeg .txt .html etc..
2820 $source = $this->fileBasename( $source );
2821
2822 $sourceNode = $this->fetchNodeByTranslation( $nodePath );
2823
2824 if ( !$sourceNode )
2825 {
2826 return false; // @as self::FAILED_NOT_FOUND;
2827 }
2828
2829 // Can we move the node from $sourceNode
2830 if ( !$sourceNode->canMoveFrom() )
2831 {
2832 $this->appendLogEntry( "No access to move the node '$sourceSite':'$nodePath'", 'CS:moveContent' );
2833 return false; // @as self::FAILED_FORBIDDEN;
2834 }
2835
2836 $object = $sourceNode->attribute( 'object' );
2837 $classID = $object->attribute( 'contentclass_id' );
2838
2839 // Get rid of possible extensions, remove .jpeg .txt .html etc..
2840 $destination = $this->fileBasename( $destination );
2841
2842 $destinationNode = $this->fetchNodeByTranslation( $destinationNodePath );
2843 $this->appendLogEntry( "Destination: $destinationNodePath", 'CS:moveContent' );
2844
2845 if ( $destinationNode )
2846 {
2847 return false; // @as self::FAILED_EXISTS;
2848 }
2849
2850 $destinationNode = $this->fetchParentNodeByTranslation( $destinationNodePath );
2851
2852 // Can we move the node to $destinationNode
2853 if ( !$destinationNode->canMoveTo( $classID ) )
2854 {
2855 $this->appendLogEntry( "No access to move the node '$sourceSite':'$nodePath' to '$destinationSite':'$destinationNodePath'", 'CS:moveContent' );
2856 return false; // @as self::FAILED_FORBIDDEN;
2857 }
2858
2859 $srcParentPath = $this->splitLastPathElement( $nodePath, $srcNodeName );
2860 $dstParentPath = $this->splitLastPathElement( $destinationNodePath, $dstNodeName );
2861 if ( $srcParentPath == $dstParentPath )
2862 {
2863 // @as 2009-03-02 - removed urldecode of name before renaming
2864 $dstNodeName = $this->fileBasename( $dstNodeName );
2865 if( !$object->rename( $dstNodeName ) )
2866 {
2867 $this->appendLogEntry( "Unable to rename the node '$sourceSite':'$nodePath' to '$destinationSite':'$destinationNodePath'", 'CS:moveContent' );
2868 return false; // @as self::FAILED_FORBIDDEN;
2869 }
2870 }
2871 else
2872 {
2873 if( !eZContentObjectTreeNodeOperations::move( $sourceNode->attribute( 'node_id' ), $destinationNode->attribute( 'node_id' ) ) )
2874 {
2875 $this->appendLogEntry( "Unable to move the node '$sourceSite':'$nodePath' to '$destinationSite':'$destinationNodePath'", 'CS:moveContent' );
2876 return false; // @as self::FAILED_FORBIDDEN;
2877 }
2878 }
2879
2880 /*
2881
2882 // Todo: add lookup of the name setting for the current object
2883 $contentObjectID = $object->attribute( 'id' );
2884 $contentObjectAttributes =& $object->contentObjectAttributes();
2885 $contentObjectAttributes[0]->setAttribute( 'data_text', basename( $destination ) );
2886 $contentObjectAttributes[0]->store();
2887
2888 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 'version' => 1 ) );
2889 $object->store();
2890 */
2891
2892 return true; // @as self::OK_CREATED;
2893 }
2894
2901 protected function isObjectFolder( $object, $class )
2902 {
2903 $classIdentifier = $class->attribute( 'identifier' );
2904
2905 return in_array( $classIdentifier, $this->FolderClasses );
2906 }
2907
2916 protected function storeUploadedFile( $target, $contents )
2917 {
2918 $dir = self::tempDirectory() . '/' . md5( microtime() . '-' . $target );
2919 $filePath = $dir . '/' . basename( $target );
2920
2921 if ( !file_exists( $dir ) )
2922 {
2923 eZDir::mkdir( $dir, false, true );
2924 }
2925
2926 $result = file_put_contents( $filePath, $contents );
2927 if ( !$result )
2928 {
2929 $result = file_exists( $filePath );
2930 }
2931
2932 if ( $result )
2933 {
2934 return $filePath;
2935 }
2936 return false;
2937 }
2938
2947 protected static function tempDirectory()
2948 {
2949 $tempDir = eZSys::varDirectory() . '/webdav/tmp';
2950 if ( !file_exists( $tempDir ) )
2951 {
2952 eZDir::mkdir( $tempDir, eZDir::directoryPermission(), true );
2953 }
2954 return $tempDir;
2955 }
2956
2964 protected function fileBasename( $name )
2965 {
2966 $pos = strrpos( $name, '.' );
2967 if ( $pos !== false )
2968 {
2969 $name = substr( $name, 0, $pos );
2970 }
2971 return $name;
2972 }
2973
2982 protected function internalNodePath( $virtualFolder, $collection )
2983 {
2984 // All root nodes needs to prepend their name to get the correct path
2985 // except for the content root which uses the path directly.
2986 if ( $virtualFolder === self::virtualMediaFolderName() )
2987 {
2988 $nodePath = 'media';
2989 if ( strlen( $collection ) > 0 )
2990 {
2991 $nodePath .= '/' . $collection;
2992 }
2993 }
2994 else
2995 {
2996 $nodePath = $collection;
2997 }
2998 return $nodePath;
2999 }
3000
3019 protected function splitFirstPathElement( $path, &$element )
3020 {
3021 if ( $path[0] === '/' )
3022 {
3023 $path = substr( $path, 1 );
3024 }
3025 $pos = strpos( $path, '/' );
3026 if ( $pos === false )
3027 {
3028 $element = $path;
3029 $path = '';
3030 }
3031 else
3032 {
3033 $element = substr( $path, 0, $pos );
3034 $path = substr( $path, $pos + 1 );
3035 }
3036 return $path;
3037 }
3038
3057 protected function splitLastPathElement( $path, &$element )
3058 {
3059 $len = strlen( $path );
3060 if ( $len > 0 and $path[$len - 1] === '/' )
3061 {
3062 $path = substr( $path, 0, $len - 1 );
3063 }
3064 $pos = strrpos( $path, '/' );
3065 if ( $pos === false )
3066 {
3067 $element = $path;
3068 $path = '';
3069 }
3070 else
3071 {
3072 $element = substr( $path, $pos + 1 );
3073 $path = substr( $path, 0, $pos );
3074 }
3075 return $path;
3076 }
3077
3086 public static function appendLogEntry( $logString, $label = false )
3087 {
3088 if ( !isset( self::$useLogging ) )
3089 {
3090 $webdavINI = eZINI::instance( self::WEBDAV_INI_FILE );
3091 self::$useLogging = $webdavINI->variable( 'GeneralSettings', 'Logging' ) === 'enabled';
3092 }
3093
3094 if ( self::$useLogging )
3095 {
3096 if ( PHP_SAPI === 'cli' )
3097 {
3098 // var_dump( $logString );
3099 }
3100 else
3101 {
3102 $varDir = realpath( eZSys::varDirectory() );
3103 $logDir = 'log';
3104 $logName = 'webdav.log';
3105 $fileName = $varDir . DIRECTORY_SEPARATOR . $logDir . DIRECTORY_SEPARATOR . $logName;
3106 if ( !file_exists( $varDir . DIRECTORY_SEPARATOR . $logDir ) )
3107 {
3108 eZDir::mkdir( $varDir . DIRECTORY_SEPARATOR . $logDir, 0775, true );
3109 }
3110
3111 $logFile = fopen( $fileName, 'a' );
3112 $nowTime = date( "Y-m-d H:i:s : " );
3113 $text = $nowTime . $logString;
3114 if ( $label )
3115 {
3116 $text .= ' [' . $label . ']';
3117 }
3118 fwrite( $logFile, $text . "\n" );
3119 fclose( $logFile );
3120 }
3121 }
3122 }
3123
3133 protected static function recode( $string, $fromCharset, $toCharset, $stop = false )
3134 {
3135 $codec = eZTextCodec::instance( $fromCharset, $toCharset, false );
3136 if ( $codec )
3137 {
3138 $string = $codec->convertString( $string );
3139 }
3140
3141 return $string;
3142 }
3143
3151 protected function encodeResponse( ezcWebdavResponse $response )
3152 {
3153
3154 return $response;
3155 }
3156
3162 public static function virtualContentFolderName()
3163 {
3164 return ezpI18n::tr( 'kernel/content', 'Content' );
3165 }
3166
3172 public static function virtualMediaFolderName()
3173 {
3174 return ezpI18n::tr( 'kernel/content', 'Media' );
3175 }
3176 }
3177 ?>
$pathArray
$pathArray
Definition: admin/adlist.php:74
$i
$i
Definition: admin/adlist.php:91
$access
if(! $user->isRegistered()) $access
Definition: authorize.php:88
$status
$status
Definition: bugedit.php:473
eZClusterFileHandler\instance
static instance( $filename=false)
Definition: ezclusterfilehandler.php:22
eZDebugSetting\writeDebug
static writeDebug( $conditionName, $string, $label="")
Definition: ezdebugsetting.php:128
eZDir\mkdir
static mkdir( $dir, $perm=false, $recursive=false)
Definition: ezdir.php:74
eZDir\cleanupEmptyDirectories
static cleanupEmptyDirectories( $dir)
Definition: ezdir.php:96
eZDir\directoryPermission
static directoryPermission()
Definition: ezdir.php:143
eZFile\suffix
static suffix( $filename)
Definition: ezfile.php:103
eZSiteAccess\change
static change(array $access, eZINI $siteINI=null)
Definition: ezsiteaccess.php:504
eZSiteAccess\TYPE_STATIC
const TYPE_STATIC
Definition: ezsiteaccess.php:29
eZSys\indexDir
static indexDir( $withAccessList=true)
Definition: ezsys.php:594
eZSys\varDirectory
static varDirectory()
Definition: ezsys.php:504
eZTextCodec\instance
static instance( $inputCharsetCode, $outputCharsetCode=false, $alwaysReturn=true)
Definition: ezi18n/classes/eztextcodec.php:447
eZWebDAVContentBackend
Provides access to Exponential kernel using WebDAV. Based on the eZ Components Webdav component.
Definition: ezwebdavcontentbackend.php:31
eZWebDAVContentBackend\getProperty
getProperty( $path, $propertyName, $namespace='DAV:')
Definition: ezwebdavcontentbackend.php:426
eZWebDAVContentBackend\moveVirtualFolder
moveVirtualFolder( $sourceSite, $destinationSite, $source, $destination, $fullSource, $fullDestination)
Definition: ezwebdavcontentbackend.php:2769
eZWebDAVContentBackend\fetchVirtualSiteContent
fetchVirtualSiteContent( $target, $site, $depth, $properties)
Definition: ezwebdavcontentbackend.php:1780
eZWebDAVContentBackend\tempDirectory
static tempDirectory()
Definition: ezwebdavcontentbackend.php:2947
eZWebDAVContentBackend\freeLock
freeLock()
Definition: ezwebdavcontentbackend.php:191
eZWebDAVContentBackend\copyVirtualFolder
copyVirtualFolder( $sourceSite, $destinationSite, $source, $destination)
Definition: ezwebdavcontentbackend.php:2502
eZWebDAVContentBackend\copy
copy(ezcWebdavCopyRequest $request)
Definition: ezwebdavcontentbackend.php:1029
eZWebDAVContentBackend\checkDeleteRecursive
checkDeleteRecursive( $target)
Definition: ezwebdavcontentbackend.php:930
eZWebDAVContentBackend\getNodes
getNodes( $requestUri, $depth)
Definition: ezwebdavcontentbackend.php:208
eZWebDAVContentBackend\getResourceContents
getResourceContents( $target)
Definition: ezwebdavcontentbackend.php:272
eZWebDAVContentBackend\setCurrentSite
setCurrentSite( $site)
Definition: ezwebdavcontentbackend.php:1357
eZWebDAVContentBackend\$handledLiveProperties
$handledLiveProperties
Definition: ezwebdavcontentbackend.php:68
eZWebDAVContentBackend\getContentTreeCollection
getContentTreeCollection( $currentSite, $virtualFolder, $collection, $fullPath, $depth, $properties)
Definition: ezwebdavcontentbackend.php:1926
eZWebDAVContentBackend\storeProperties
storeProperties( $path, ezcWebdavBasicPropertyStorage $storage)
Definition: ezwebdavcontentbackend.php:743
eZWebDAVContentBackend\getVirtualFolderData
getVirtualFolderData( $result, $currentSite, $target, $fullPath)
Definition: ezwebdavcontentbackend.php:1610
eZWebDAVContentBackend\fetchContentList
fetchContentList( $fullPath, &$node, $target, $depth, $properties)
Definition: ezwebdavcontentbackend.php:1969
eZWebDAVContentBackend\copyObject
copyObject( $object, $newParentNode)
Definition: ezwebdavcontentbackend.php:2630
eZWebDAVContentBackend\getCollectionContent
getCollectionContent( $collection, $depth=false, $properties=false)
Definition: ezwebdavcontentbackend.php:1708
eZWebDAVContentBackend\isCollection
isCollection( $path)
Definition: ezwebdavcontentbackend.php:583
eZWebDAVContentBackend\fetchContainerNodeInfo
fetchContainerNodeInfo( $fullPath, $site, $nodeName)
Definition: ezwebdavcontentbackend.php:1742
eZWebDAVContentBackend\virtualMediaFolderName
static virtualMediaFolderName()
Definition: ezwebdavcontentbackend.php:3172
eZWebDAVContentBackend\put
put(ezcWebdavPutRequest $request)
Definition: ezwebdavcontentbackend.php:835
eZWebDAVContentBackend\virtualContentFolderName
static virtualContentFolderName()
Definition: ezwebdavcontentbackend.php:3162
eZWebDAVContentBackend\moveRecursive
moveRecursive( $source, $destination, $depth=ezcWebdavRequest::DEPTH_INFINITY)
Definition: ezwebdavcontentbackend.php:1192
eZWebDAVContentBackend\setResourceContents
setResourceContents( $path, $content)
Definition: ezwebdavcontentbackend.php:867
eZWebDAVContentBackend\currentSiteFromPath
currentSiteFromPath( $path)
Definition: ezwebdavcontentbackend.php:1383
eZWebDAVContentBackend\copyContent
copyContent( $sourceSite, $destinationSite, $sourceVFolder, $destinationVFolder, $source, $destination)
Definition: ezwebdavcontentbackend.php:2550
eZWebDAVContentBackend\deleteContent
deleteContent( $currentSite, $virtualFolder, $target)
Definition: ezwebdavcontentbackend.php:2367
eZWebDAVContentBackend\VIRTUAL_MEDIA_FOLDER_NAME
const VIRTUAL_MEDIA_FOLDER_NAME
Definition: ezwebdavcontentbackend.php:40
eZWebDAVContentBackend\removeProperty
removeProperty( $path, ezcWebdavProperty $property)
Definition: ezwebdavcontentbackend.php:799
eZWebDAVContentBackend\fetchSiteListContent
fetchSiteListContent( $target, $depth, $properties)
Definition: ezwebdavcontentbackend.php:2022
eZWebDAVContentBackend\moveContent
moveContent( $sourceSite, $destinationSite, $sourceVFolder, $destinationVFolder, $source, $destination, $fullSource, $fullDestination)
Definition: ezwebdavcontentbackend.php:2811
eZWebDAVContentBackend\head
head(ezcWebdavHeadRequest $request)
Definition: ezwebdavcontentbackend.php:634
eZWebDAVContentBackend\createResource
createResource( $path, $content=null)
Definition: ezwebdavcontentbackend.php:853
eZWebDAVContentBackend\createFolder
createFolder( $parentNode, $target)
Definition: ezwebdavcontentbackend.php:2287
eZWebDAVContentBackend\VIRTUAL_CONTENT_FOLDER_NAME
const VIRTUAL_CONTENT_FOLDER_NAME
Definition: ezwebdavcontentbackend.php:35
eZWebDAVContentBackend\getContentNodeData
getContentNodeData( $result, $currentSite, $virtualFolder, $target, $fullPath)
Definition: ezwebdavcontentbackend.php:1650
eZWebDAVContentBackend\__construct
__construct()
Definition: ezwebdavcontentbackend.php:120
eZWebDAVContentBackend\$FolderClasses
$FolderClasses
Definition: ezwebdavcontentbackend.php:85
eZWebDAVContentBackend\copyRecursive
copyRecursive( $source, $destination, $depth=ezcWebdavRequest::DEPTH_INFINITY)
Definition: ezwebdavcontentbackend.php:1120
eZWebDAVContentBackend\splitFirstPathElement
splitFirstPathElement( $path, &$element)
Definition: ezwebdavcontentbackend.php:3019
eZWebDAVContentBackend\createCollection
createCollection( $target)
Definition: ezwebdavcontentbackend.php:2196
eZWebDAVContentBackend\nodeExists
nodeExists( $path)
Definition: ezwebdavcontentbackend.php:564
eZWebDAVContentBackend\appendLogEntry
static appendLogEntry( $logString, $label=false)
Definition: ezwebdavcontentbackend.php:3086
eZWebDAVContentBackend\putVirtualFolderData
putVirtualFolderData( $currentSite, $target, $tempFile)
Definition: ezwebdavcontentbackend.php:2413
eZWebDAVContentBackend\propPatch
propPatch(ezcWebdavPropPatchRequest $request)
Definition: ezwebdavcontentbackend.php:724
eZWebDAVContentBackend\move
move(ezcWebdavMoveRequest $request)
Definition: ezwebdavcontentbackend.php:1264
eZWebDAVContentBackend\internalNodePath
internalNodePath( $virtualFolder, $collection)
Definition: ezwebdavcontentbackend.php:2982
eZWebDAVContentBackend\DEFAULT_SIZE
const DEFAULT_SIZE
Definition: ezwebdavcontentbackend.php:60
eZWebDAVContentBackend\propFind
propFind(ezcWebdavPropFindRequest $request)
Definition: ezwebdavcontentbackend.php:673
eZWebDAVContentBackend\performDelete
performDelete( $target)
Definition: ezwebdavcontentbackend.php:977
eZWebDAVContentBackend\DEFAULT_MIMETYPE
const DEFAULT_MIMETYPE
Definition: ezwebdavcontentbackend.php:55
eZWebDAVContentBackend\storeUploadedFile
storeUploadedFile( $target, $contents)
Definition: ezwebdavcontentbackend.php:2916
eZWebDAVContentBackend\acquireLock
acquireLock( $readOnly=false)
Definition: ezwebdavcontentbackend.php:181
eZWebDAVContentBackend\mkcolVirtualFolder
mkcolVirtualFolder( $currentSite, $target)
Definition: ezwebdavcontentbackend.php:2219
eZWebDAVContentBackend\fetchParentNodeByTranslation
fetchParentNodeByTranslation( $nodePathString)
Definition: ezwebdavcontentbackend.php:2137
eZWebDAVContentBackend\WEBDAV_INI_FILE
const WEBDAV_INI_FILE
Definition: ezwebdavcontentbackend.php:45
eZWebDAVContentBackend\makeCollection
makeCollection(ezcWebdavMakeCollectionRequest $request)
Definition: ezwebdavcontentbackend.php:1288
eZWebDAVContentBackend\getPropertyStorage
getPropertyStorage( $path)
Definition: ezwebdavcontentbackend.php:548
eZWebDAVContentBackend\unlock
unlock()
Definition: ezwebdavcontentbackend.php:159
eZWebDAVContentBackend\getCollectionMembers
getCollectionMembers( $path, $depth=ezcWebdavRequest::DEPTH_INFINITY)
Definition: ezwebdavcontentbackend.php:303
eZWebDAVContentBackend\$cachedNodes
$cachedNodes
Definition: ezwebdavcontentbackend.php:99
eZWebDAVContentBackend\putContentData
putContentData( $currentSite, $virtualFolder, $target, $tempFile)
Definition: ezwebdavcontentbackend.php:2452
eZWebDAVContentBackend\$availableSites
$availableSites
Definition: ezwebdavcontentbackend.php:92
eZWebDAVContentBackend\mkcolContent
mkcolContent( $currentSite, $virtualFolder, $target)
Definition: ezwebdavcontentbackend.php:2255
eZWebDAVContentBackend\options
options(ezcWebdavOptionsRequest $request)
Definition: ezwebdavcontentbackend.php:1309
eZWebDAVContentBackend\isObjectFolder
isObjectFolder( $object, $class)
Definition: ezwebdavcontentbackend.php:2901
eZWebDAVContentBackend\getAllProperties
getAllProperties( $path)
Definition: ezwebdavcontentbackend.php:524
eZWebDAVContentBackend\$useLogging
static $useLogging
Definition: ezwebdavcontentbackend.php:115
eZWebDAVContentBackend\setProperty
setProperty( $path, ezcWebdavProperty $property)
Definition: ezwebdavcontentbackend.php:758
eZWebDAVContentBackend\$cachedProperties
$cachedProperties
Definition: ezwebdavcontentbackend.php:106
eZWebDAVContentBackend\lock
lock( $waitTime, $timeout)
Definition: ezwebdavcontentbackend.php:149
eZWebDAVContentBackend\getVirtualFolderCollection
getVirtualFolderCollection( $currentSite, $collection, $fullPath, $depth, $properties)
Definition: ezwebdavcontentbackend.php:1849
eZWebDAVContentBackend\splitLastPathElement
splitLastPathElement( $path, &$element)
Definition: ezwebdavcontentbackend.php:3057
eZWebDAVContentBackend\deleteVirtualFolder
deleteVirtualFolder( $currentSite, $target)
Definition: ezwebdavcontentbackend.php:2331
eZWebDAVContentBackend\recode
static recode( $string, $fromCharset, $toCharset, $stop=false)
Definition: ezwebdavcontentbackend.php:3133
eZWebDAVContentBackend\getNodeInfo
getNodeInfo( $requestUri, $source=null)
Definition: ezwebdavcontentbackend.php:359
eZWebDAVContentBackend\DIRECTORY_MIMETYPE
const DIRECTORY_MIMETYPE
Definition: ezwebdavcontentbackend.php:50
eZWebDAVContentBackend\fetchNodeByTranslation
fetchNodeByTranslation( $nodePathString)
Definition: ezwebdavcontentbackend.php:2085
eZWebDAVContentBackend\resetProperties
resetProperties( $path, ezcWebdavPropertyStorage $storage)
Definition: ezwebdavcontentbackend.php:815
eZWebDAVContentBackend\fetchNodeInfo
fetchNodeInfo( $target, &$node)
Definition: ezwebdavcontentbackend.php:1424
eZWebDAVContentBackend\encodeResponse
encodeResponse(ezcWebdavResponse $response)
Definition: ezwebdavcontentbackend.php:3151
eZWebDAVContentBackend\fileBasename
fileBasename( $name)
Definition: ezwebdavcontentbackend.php:2964
eZWebDAVContentBackend\copyObjectSameDirectory
copyObjectSameDirectory( $object, $newParentNode, $destinationName=null)
Definition: ezwebdavcontentbackend.php:2690
eZWebDAVContentBackend\performCopy
performCopy( $source, $destination, $depth=ezcWebdavRequest::DEPTH_INFINITY)
Definition: ezwebdavcontentbackend.php:1062
$ini
$ini
Definition: classes/admin/linklist.php:64
$item
$item
Definition: classes/admin/linklist.php:228
$result
$result
Definition: companysearch.php:94
$name
$name
Definition: companytypelist.php:194
file_exists
static file_exists( $inifilename)
Definition: eZPBINIFile.php:195
$version
$version
Definition: ezabout/user/datasupplier.php:29
$error
$error
Definition: ezarticle/admin/categoryedit.php:51
$db
$db
Definition: ezarticle/user/authorlist.php:53
$contents
$contents
Definition: ezarticle/user/extendedsearch.php:52
$fileName
if(eZObjectPermission::hasPermission( $file->id(), "filemanager_file", "r", $user)==false) $fileName
Definition: ezfilemanager/user/filedownload.php:43
$size
if($file_debug) $size
Definition: ezfilemanager/user/filedownload.php:165
$suffix
$suffix
Definition: ezfilemanager/user/filedownload.php:168
$file
$file
Definition: ezfilemanager/user/filedownload.php:35
$filePath
$filePath
Definition: ezfilemanager/user/filedownload.php:50
$content
$content
Definition: ezimagecatalogue/admin/filedownload.php:53
$dir
$dir
Definition: ezsitemanager/admin/filelist.php:87
$timestamp
$timestamp
Definition: ezstats/admin/cron.php:35
$element
if(! $parent) $element
Definition: folder.php:64
$sourceSite
$sourceSite
Definition: importnews.php:101
$response
while(!feof($socket)) $response
Definition: paypalnotify.php:196
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.