|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // This is the eZWebDAVContentServer class. Manages WebDAV sessions. 00004 // 00005 // Created on: <15-Aug-2003 15:15:15 bh> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! 00032 \class eZWebDAVContentServer ezwebdavcontentserver.php 00033 \ingroup eZWebDAV 00034 \brief Provides access to eZ Publish kernel using WebDAV 00035 00036 */ 00037 00038 //include_once( 'lib/ezwebdav/classes/ezwebdavserver.php' ); 00039 //include_once( 'kernel/classes/ezcontentobjecttreenode.php' ); 00040 //include_once( "kernel/classes/datatypes/ezbinaryfile/ezbinaryfile.php" ); 00041 //include_once( "lib/ezutils/classes/ezmimetype.php" ); 00042 //include_once( 'lib/ezfile/classes/ezdir.php' ); 00043 //include_once( "kernel/classes/ezurlaliasml.php" ); 00044 //include_once( 'kernel/classes/datatypes/ezuser/ezuser.php' ); 00045 require_once( 'access.php' ); 00046 00047 class eZWebDAVContentServer extends eZWebDAVServer 00048 { 00049 const WEBDAV_INI_FILE = "webdav.ini"; 00050 const WEBDAV_AUTH_REALM = "eZ Publish WebDAV interface"; 00051 const WEBDAV_AUTH_FAILED = "Invalid username or password!"; 00052 const WEBDAV_INVALID_SITE = "Invalid site name specified!"; 00053 const WEBDAV_DISABLED = "WebDAV functionality is disabled!"; 00054 00055 /*! 00056 Initializes the eZWebDAVServer 00057 */ 00058 function eZWebDAVContentServer() 00059 { 00060 $this->eZWebDAVServer(); 00061 $this->User = eZUser::currentUser(); 00062 $this->FolderClasses = null; 00063 } 00064 00065 /*! 00066 \reimp 00067 Makes sure $this->User is reinitialized with the current user, 00068 then calls the $super->processClientRequest(). 00069 */ 00070 function processClientRequest() 00071 { 00072 $this->User = eZUser::currentUser(); 00073 eZWebDAVServer::processClientRequest(); 00074 } 00075 00076 /*! 00077 @{ 00078 */ 00079 00080 /*! 00081 \reimp 00082 Fetch the file from eZCluster if needed before send. 00083 */ 00084 function outputSendDataToClient( $output, $headers_only = false ) 00085 { 00086 if ( $output["file"] ) 00087 { 00088 $realPath = $output["file"]; 00089 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00090 $file = eZClusterFileHandler::instance( $realPath ); 00091 $file->fetch(); 00092 } 00093 $result = eZWebDAVServer::outputSendDataToClient($output,$headers_only); 00094 if ( $output["file"] && is_object( $file ) ) 00095 $file->deleteLocal(); 00096 return $result; 00097 } 00098 00099 /*! 00100 \reimp 00101 Restricts the allowed methods to only the subset that this server supports. 00102 */ 00103 function options( $target ) 00104 { 00105 // Only a few WebDAV operations are allowed for now. 00106 $options = array(); 00107 $options['methods'] = array( 'OPTIONS', 'PROPFIND', 'HEAD', 'GET', 'PUT', 'MKCOL', 'MOVE' ); 00108 // $options['versions'] = array( '1' ); 00109 00110 return $options; 00111 } 00112 00113 /*! 00114 \reimp 00115 Produces the collection content. Builds either the virtual start folder 00116 with the virtual content folder in it (and additional files). OR: if 00117 we're browsing within the content folder: it gets the content of the 00118 target/given folder. 00119 */ 00120 function getCollectionContent( $collection, $depth = false, $properties = false ) 00121 { 00122 $fullPath = $collection; 00123 $collection = $this->splitFirstPathElement( $collection, $currentSite ); 00124 00125 if ( !$currentSite ) 00126 { 00127 // Display the root which contains a list of sites 00128 $this->appendLogEntry( "Root: Fethcing site list", 'CS:getCollectionContent' ); 00129 $entries = $this->fetchSiteListContent( $depth, $properties ); 00130 return $entries; 00131 } 00132 00133 if ( !$this->userHasSiteAccess( $currentSite ) ) 00134 { 00135 $this->appendLogEntry( "No access to site '$currentSite'", 'CS:getCollectionContent' ); 00136 return eZWebDAVServer::FAILED_FORBIDDEN; 00137 } 00138 00139 return $this->getVirtualFolderCollection( $currentSite, $collection, $fullPath, $depth, $properties ); 00140 } 00141 00142 /*! 00143 \private 00144 Handles collections on the virtual folder level, if no virtual folder 00145 elements are accessed it lists the virtual folders. 00146 */ 00147 function getVirtualFolderCollection( $currentSite, $collection, $fullPath, $depth, $properties ) 00148 { 00149 $this->appendLogEntry( "Check virtual folder: site '$currentSite' in '$collection' ", 'CS:getVirtualFolderCollection' ); 00150 $this->setCurrentSite( $currentSite ); 00151 00152 if ( !$collection ) 00153 { 00154 // We are inside a site so we display the virtual folder for the site 00155 $this->appendLogEntry( "Virtual folder for '$currentSite'", 'CS:getVirtualFolderCollection' ); 00156 $entries = $this->fetchVirtualSiteContent( $currentSite, $depth, $properties ); 00157 return $entries; 00158 } 00159 00160 $collection = $this->splitFirstPathElement( $collection, $virtualFolder ); 00161 00162 if ( !in_array( $virtualFolder, $this->virtualFolderList() ) ) 00163 { 00164 $this->appendLogEntry( "Unknown virtual folder: '$virtualFolder' in site '$currentSite'", 'CS:getVirtualFolderCollection' ); 00165 return eZWebDAVServer::FAILED_NOT_FOUND; 00166 } 00167 00168 if ( !$this->userHasVirtualAccess( $currentSite, $virtualFolder ) ) 00169 { 00170 $this->appendLogEntry( "No access to virtual folder '$virtualFolder' in site '$currentSite'", 'CS:getVirtualFolderCollection' ); 00171 return eZWebDAVServer::FAILED_FORBIDDEN; 00172 } 00173 00174 return $this->getContentTreeCollection( $currentSite, $virtualFolder, $collection, $fullPath, $depth, $properties ); 00175 } 00176 00177 /*! 00178 \private 00179 Handles collections on the content tree level. 00180 Depending on the virtual folder we will generate a node path url and fetch 00181 the nodes for that path. 00182 */ 00183 function getContentTreeCollection( $currentSite, $virtualFolder, $collection, $fullPath, $depth, $properties ) 00184 { 00185 $this->appendLogEntry( "Content collection: from site '$currentSite' in '$virtualFolder' using path '$collection'", 'CS:getContentTreeCollection' ); 00186 $nodePath = $this->internalNodePath( $virtualFolder, $collection ); 00187 $node = $this->fetchNodeByTranslation( $nodePath ); 00188 00189 if ( !$node ) 00190 { 00191 $this->appendLogEntry( "Unknown node: $nodePath", 'CS:getContentTreeCollection' ); 00192 return eZWebDAVServer::FAILED_NOT_FOUND; 00193 } 00194 00195 // Can we list the children of the node? 00196 if ( !$node->canRead() ) 00197 { 00198 $this->appendLogEntry( "No access to content '$nodePath' in site '$currentSite'", 'CS:getContentTreeCollection' ); 00199 return eZWebDAVServer::FAILED_FORBIDDEN; 00200 } 00201 00202 $entries = $this->fetchContentList( $node, $nodePath, $depth, $properties ); 00203 return $entries; 00204 } 00205 00206 /*! 00207 \reimp 00208 Tries to figure out the filepath of the object being shown, 00209 if not we will pass the virtual url as the filepath. 00210 */ 00211 function get( $target ) 00212 { 00213 $result = array(); 00214 $result["data"] = false; 00215 $result["file"] = false; 00216 00217 $fullPath = $target; 00218 $target = $this->splitFirstPathElement( $target, $currentSite ); 00219 00220 if ( !$currentSite ) 00221 { 00222 // Sites are folders and have no data 00223 return eZWebDAVServer::FAILED_FORBIDDEN; 00224 } 00225 00226 if ( !$this->userHasSiteAccess( $currentSite ) ) 00227 { 00228 $this->appendLogEntry( "No access to site '$currentSite'", 'CS:get' ); 00229 return eZWebDAVServer::FAILED_FORBIDDEN; 00230 } 00231 00232 return $this->getVirtualFolderData( $result, $currentSite, $target, $fullPath ); 00233 } 00234 00235 /*! 00236 \private 00237 Handles data retrival on the virtual folder level. 00238 */ 00239 function getVirtualFolderData( $result, $currentSite, $target, $fullPath ) 00240 { 00241 $this->appendLogEntry( "current site: $currentSite", 'CS:get' ); 00242 $this->setCurrentSite( $currentSite ); 00243 00244 $target = $this->splitFirstPathElement( $target, $virtualFolder ); 00245 00246 if ( !$target ) 00247 { 00248 if ( !in_array( $virtualFolder, $this->virtualFileList() ) ) 00249 { 00250 return eZWebDAVServer::FAILED_NOT_FOUND; 00251 } 00252 00253 // We have reached the end of the path 00254 if ( $virtualFolder == basename( eZWebDAVContentServer::virtualInfoFileName() ) ) 00255 { 00256 $result["file"] = eZWebDAVContentServer::virtualInfoFileName(); 00257 00258 return $result; 00259 } 00260 00261 // The rest in the virtual folder does not have any data 00262 return eZWebDAVServer::FAILED_NOT_FOUND; 00263 } 00264 00265 if ( !$this->userHasVirtualAccess( $currentSite, $virtualFolder ) ) 00266 { 00267 $this->appendLogEntry( "No access to virtual folder '$virtualFolder' in site '$currentSite'", 'CS:get' ); 00268 return eZWebDAVServer::FAILED_FORBIDDEN; 00269 } 00270 00271 if ( !in_array( $virtualFolder, $this->virtualFolderList() ) ) 00272 { 00273 $this->appendLogEntry( "Unknown virtual folder: '$virtualFolder' in site '$currentSite'", 'CS:get' ); 00274 return eZWebDAVServer::FAILED_NOT_FOUND; 00275 } 00276 00277 if ( $virtualFolder == eZWebDAVContentServer::virtualContentFolderName() or 00278 $virtualFolder == eZWebDAVContentServer::virtualMediaFolderName() ) 00279 { 00280 return $this->getContentNodeData( $result, $currentSite, $virtualFolder, $target, $fullPath ); 00281 } 00282 return eZWebDAVServer::FAILED_NOT_FOUND; 00283 } 00284 00285 /*! 00286 \private 00287 Handles data retrival on the content tree level. 00288 */ 00289 function getContentNodeData( $result, $currentSite, $virtualFolder, $target, $fullPath ) 00290 { 00291 $this->appendLogEntry( "attempting to fetch node, target is: $target", 'CS:get' ); 00292 00293 // Attempt to fetch the node the client wants to get. 00294 $nodePath = $this->internalNodePath( $virtualFolder, $target ); 00295 $node = $this->fetchNodeByTranslation( $nodePath ); 00296 00297 // Proceed only if the node is valid: 00298 if ( $node == null ) 00299 { 00300 $this->appendLogEntry( "No node for: $nodePath", 'CS:get' ); 00301 return $result; 00302 } 00303 00304 // Can we fetch the contents of the node 00305 if ( !$node->canRead() ) 00306 { 00307 $this->appendLogEntry( "No access to get '$nodePath' in site '$currentSite'", 'CS:get' ); 00308 return eZWebDAVServer::FAILED_FORBIDDEN; 00309 } 00310 00311 $object = $node->attribute( 'object' ); 00312 00313 //include_once( 'kernel/classes/ezcontentupload.php' ); 00314 $upload = new eZContentUpload(); 00315 $info = $upload->objectFileInfo( $object ); 00316 if ( $info ) 00317 { 00318 $result['file'] = $info['filepath']; 00319 } 00320 00321 return $result; 00322 } 00323 00324 /*! 00325 \note Not implemented yet 00326 */ 00327 function head( $target ) 00328 { 00329 return eZWebDAVServer::FAILED_NOT_FOUND; 00330 } 00331 00332 /*! 00333 \reimp 00334 Tries to create/update an object at location \a $target with the file \a $tempFile. 00335 */ 00336 function put( $target, $tempFile ) 00337 { 00338 $fullPath = $target; 00339 $target = $this->splitFirstPathElement( $target, $currentSite ); 00340 00341 if ( !$currentSite ) 00342 { 00343 return eZWebDAVServer::FAILED_FORBIDDEN; 00344 } 00345 00346 if ( !$this->userHasSiteAccess( $currentSite ) ) 00347 { 00348 $this->appendLogEntry( "No access to site '$currentSite'", 'CS:put' ); 00349 return eZWebDAVServer::FAILED_FORBIDDEN; 00350 } 00351 00352 return $this->putVirtualFolderData( $currentSite, $target, $tempFile, $fullPath ); 00353 } 00354 00355 /*! 00356 \private 00357 Handles data storage on the content tree level. 00358 It will check if the target is below a content folder in which it calls putContentData(). 00359 */ 00360 function putVirtualFolderData( $currentSite, $target, $tempFile, $fullPath ) 00361 { 00362 $this->appendLogEntry( "current site is: $currentSite", 'CS:put' ); 00363 $this->setCurrentSite( $currentSite ); 00364 00365 $target = $this->splitFirstPathElement( $target, $virtualFolder ); 00366 00367 if ( !$target ) 00368 { 00369 // We have reached the end of the path 00370 // We do not allow 'put' operations for the virtual folder. 00371 return eZWebDAVServer::FAILED_FORBIDDEN; 00372 } 00373 00374 if ( !in_array( $virtualFolder, $this->virtualFolderList() ) ) 00375 { 00376 $this->appendLogEntry( "Unknown virtual folder: '$virtualFolder' in site '$currentSite'", 'CS:put' ); 00377 return eZWebDAVServer::FAILED_CONFLICT; 00378 } 00379 00380 if ( !$this->userHasVirtualAccess( $currentSite, $virtualFolder ) ) 00381 { 00382 $this->appendLogEntry( "No access to virtual folder '$virtualFolder' in site '$currentSite'", 'CS:put' ); 00383 return eZWebDAVServer::FAILED_FORBIDDEN; 00384 } 00385 00386 if ( $virtualFolder == eZWebDAVContentServer::virtualContentFolderName() or 00387 $virtualFolder == eZWebDAVContentServer::virtualMediaFolderName() ) 00388 { 00389 return $this->putContentData( $currentSite, $virtualFolder, $target, $tempFile, $fullPath ); 00390 } 00391 00392 return eZWebDAVServer::FAILED_FORBIDDEN; 00393 } 00394 00395 /*! 00396 \private 00397 Handles data storage on the content tree level. 00398 It will try to find the parent node of the wanted placement and 00399 create a new object with data from \a $tempFile. 00400 */ 00401 function putContentData( $currentSite, $virtualFolder, $target, $tempFile, $fullPath ) 00402 { 00403 $nodePath = $this->internalNodePath( $virtualFolder, $target ); 00404 00405 $this->appendLogEntry( "Inside virtual content folder", 'CS:put' ); 00406 00407 $parentNode = $this->fetchParentNodeByTranslation( $nodePath ); 00408 if ( $parentNode == null ) 00409 { 00410 // The node does not exist, so we cannot put the file 00411 $this->appendLogEntry( "Cannot put file $nodePath, not parent found", 'CS:put' ); 00412 return eZWebDAVServer::FAILED_CONFLICT; 00413 } 00414 00415 // Can we put content in the parent node 00416 if ( !$parentNode->canRead() ) 00417 { 00418 $this->appendLogEntry( "No access to put '$nodePath' in site '$currentSite'", 'CS:put' ); 00419 return eZWebDAVServer::FAILED_FORBIDDEN; 00420 } 00421 00422 $parentNodeID = $parentNode->attribute( 'node_id' ); 00423 00424 // We need the MIME-Type to figure out which content-class we will use 00425 $mimeInfo = eZMimeType::findByURL( $nodePath ); 00426 $mime = $mimeInfo['name']; 00427 00428 $webdavINI = eZINI::instance( eZWebDAVContentServer::WEBDAV_INI_FILE ); 00429 $defaultObjectType = $webdavINI->variable( 'PutSettings', 'DefaultClass' ); 00430 00431 $existingNode = $this->fetchNodeByTranslation( $nodePath ); 00432 //include_once( 'kernel/classes/ezcontentupload.php' ); 00433 00434 $upload = new eZContentUpload(); 00435 if ( !$upload->handleLocalFile( $result, $tempFile, $parentNodeID, $existingNode ) ) 00436 { 00437 foreach ( $result['errors'] as $error ) 00438 { 00439 $this->appendLogEntry( "Error: " . $error['description'], 'CS: put' ); 00440 } 00441 foreach ( $result['notices'] as $notice ) 00442 { 00443 $this->appendLogEntry( "Notice: " . $notice['description'], 'CS: put' ); 00444 } 00445 if ( $result['status'] == eZContentUpload::STATUS_PERMISSION_DENIED ) 00446 { 00447 return eZWebDAVServer::FAILED_FORBIDDEN; 00448 } 00449 else 00450 return eZWebDAVServer::FAILED_UNSUPPORTED; 00451 } 00452 00453 return eZWebDAVServer::OK_CREATED; 00454 } 00455 00456 /*! 00457 \reimp 00458 Tries to create a collection at \a $target. In our case this is a content-class 00459 of a given type (most likely a folder). 00460 */ 00461 function mkcol( $target ) 00462 { 00463 $fullPath = $target; 00464 $target = $this->splitFirstPathElement( $target, $currentSite ); 00465 00466 if ( !$currentSite ) 00467 { 00468 // Site list cannot get new entries 00469 return eZWebDAVServer::FAILED_FORBIDDEN; 00470 } 00471 00472 if ( !$this->userHasSiteAccess( $currentSite ) ) 00473 { 00474 $this->appendLogEntry( "No access to site '$currentSite'", 'CS:mkcol' ); 00475 return eZWebDAVServer::FAILED_FORBIDDEN; 00476 } 00477 00478 return $this->mkcolVirtualFolder( $currentSite, $target, $fullPath ); 00479 } 00480 00481 /*! 00482 \private 00483 Handles collection creation on the virtual folder level. 00484 It will check if the target is below a content folder in which it calls mkcolContent(). 00485 */ 00486 function mkcolVirtualFolder( $currentSite, $target, $fullPath ) 00487 { 00488 $this->setCurrentSite( $currentSite ); 00489 00490 $target = $this->splitFirstPathElement( $target, $virtualFolder ); 00491 00492 if ( !in_array( $virtualFolder, $this->virtualList() ) ) 00493 { 00494 $this->appendLogEntry( "Unknown virtual element: '$virtualFolder' in site '$currentSite'", 'CS:mkcol' ); 00495 return eZWebDAVServer::FAILED_NOT_FOUND; 00496 } 00497 00498 if ( !$target ) 00499 { 00500 // We have reached the end of the path 00501 // We do not allow 'mkcol' operations for the virtual folder. 00502 return eZWebDAVServer::FAILED_FORBIDDEN; 00503 } 00504 00505 if ( !$this->userHasVirtualAccess( $currentSite, $virtualFolder ) ) 00506 { 00507 $this->appendLogEntry( "No access to virtual folder '$virtualFolder' in site '$currentSite'", 'CS:mkcol' ); 00508 return eZWebDAVServer::FAILED_FORBIDDEN; 00509 } 00510 00511 if ( $virtualFolder == eZWebDAVContentServer::virtualContentFolderName() or 00512 $virtualFolder == eZWebDAVContentServer::virtualMediaFolderName() ) 00513 { 00514 return $this->mkcolContent( $currentSite, $virtualFolder, $target, $fullPath ); 00515 } 00516 00517 return eZWebDAVServer::FAILED_FORBIDDEN; 00518 } 00519 00520 /*! 00521 \private 00522 Handles collection creation on the content tree level. 00523 It will try to find the parent node of the wanted placement and 00524 create a new collection (folder etc.) as a child. 00525 */ 00526 function mkcolContent( $currentSite, $virtualFolder, $target, $fullPath ) 00527 { 00528 $nodePath = $this->internalNodePath( $virtualFolder, $target ); 00529 $node = $this->fetchNodeByTranslation( $nodePath ); 00530 if ( $node ) 00531 { 00532 return eZWebDAVServer::FAILED_EXISTS; 00533 } 00534 00535 $parentNode = $this->fetchParentNodeByTranslation( $nodePath ); 00536 $this->appendLogEntry( "Target is: $target", 'CS:mkcolContent' ); 00537 00538 if ( !$parentNode ) 00539 { 00540 return eZWebDAVServer::FAILED_NOT_FOUND; 00541 } 00542 00543 // Can we create a collection in the parent node 00544 if ( !$parentNode->canRead() ) 00545 { 00546 $this->appendLogEntry( "No access to mkcol '$nodePath' in site '$currentSite'", 'CS:mkcolContent' ); 00547 return eZWebDAVServer::FAILED_FORBIDDEN; 00548 } 00549 00550 return $this->createFolder( $parentNode, $nodePath ); 00551 } 00552 00553 /*! 00554 \reimp 00555 Removes the object from the node tree and leaves it in the trash. 00556 */ 00557 function delete( $target ) 00558 { 00559 $fullPath = $target; 00560 $target = $this->splitFirstPathElement( $target, $currentSite ); 00561 00562 if ( !$currentSite ) 00563 { 00564 // Cannot delete entries in site list 00565 return eZWebDAVServer::FAILED_FORBIDDEN; 00566 } 00567 00568 if ( !$this->userHasSiteAccess( $currentSite ) ) 00569 { 00570 $this->appendLogEntry( "No access to site '$currentSite'", 'CS:delete' ); 00571 return eZWebDAVServer::FAILED_FORBIDDEN; 00572 } 00573 00574 return $this->deleteVirtualFolder( $currentSite, $target, $fullPath ); 00575 } 00576 00577 /*! 00578 \private 00579 Handles deletion on the virtual folder level. 00580 It will check if the target is below a content folder in which it calls deleteContent(). 00581 */ 00582 function deleteVirtualFolder( $currentSite, $target, $fullPath ) 00583 { 00584 $this->appendLogEntry( "Target is: $target", 'CS:delete' ); 00585 $this->setCurrentSite( $currentSite ); 00586 00587 $target = $this->splitFirstPathElement( $target, $virtualFolder ); 00588 00589 if ( !in_array( $virtualFolder, $this->virtualList() ) ) 00590 { 00591 $this->appendLogEntry( "Unknown virtual element: '$virtualFolder' in site '$currentSite'", 'CS:deleteVirtualFolder' ); 00592 return eZWebDAVServer::FAILED_NOT_FOUND; 00593 } 00594 00595 if ( !$target ) 00596 { 00597 // We have reached the end of the path 00598 // We do not allow 'delete' operations for the virtual folder. 00599 return eZWebDAVServer::FAILED_FORBIDDEN; 00600 } 00601 00602 if ( !$this->userHasVirtualAccess( $currentSite, $virtualFolder ) ) 00603 { 00604 $this->appendLogEntry( "No access to virtual folder '$virtualFolder' in site '$currentSite'", 'CS:deleteVirtualFolder' ); 00605 return eZWebDAVServer::FAILED_FORBIDDEN; 00606 } 00607 00608 if ( $virtualFolder == eZWebDAVContentServer::virtualContentFolderName() or 00609 $virtualFolder == eZWebDAVContentServer::virtualMediaFolderName() ) 00610 { 00611 return $this->deleteContent( $currentSite, $virtualFolder, $target, $fullPath ); 00612 } 00613 00614 return eZWebDAVServer::FAILED_FORBIDDEN; 00615 } 00616 00617 /*! 00618 \private 00619 Handles deletion on the content tree level. 00620 It will try to find the node of the target \a $target 00621 and then try to remove it (ie. move to trash) if the user is allowed. 00622 */ 00623 function deleteContent( $currentSite, $virtualFolder, $target, $fullPath ) 00624 { 00625 $nodePath = $this->internalNodePath( $virtualFolder, $target ); 00626 $node = $this->fetchNodeByTranslation( $nodePath ); 00627 00628 if ( $node == null ) 00629 { 00630 $this->appendLogEntry( "Cannot delete node/object $nodePath, it does not exist", 'CS:deleteContent' ); 00631 return eZWebDAVServer::FAILED_NOT_FOUND; 00632 } 00633 00634 // Can we delete the node? 00635 if ( !$node->canRead() or 00636 !$node->canRemove() ) 00637 { 00638 $this->appendLogEntry( "No access to delete '$nodePath' in site '$currentSite'", 'CS:deleteContent' ); 00639 return eZWebDAVServer::FAILED_FORBIDDEN; 00640 } 00641 00642 $this->appendLogEntry( "Removing node: $nodePath", 'CS:deleteContent' ); 00643 $node->removeNodeFromTree( true ); 00644 return eZWebDAVServer::OK; 00645 } 00646 00647 /*! 00648 \reimp 00649 Moves the object \a $source to destination \a $destination. 00650 */ 00651 function move( $source, $destination ) 00652 { 00653 $fullSource = $source; 00654 $fullDestination = $destination; 00655 $source = $this->splitFirstPathElement( $source, $sourceSite ); 00656 $destination = $this->splitFirstPathElement( $destination, $destinationSite ); 00657 if ( $sourceSite != $destinationSite ) 00658 { 00659 // We do not support moving from one site to another yet 00660 // TODO: Check if the sites are using the same db, 00661 // if so allow the move as a simple object move 00662 // If not we will have to do an object export from 00663 // $sourceSite and import it in $destinationSite 00664 return eZWebDAVServer::FAILED_FORBIDDEN; 00665 } 00666 00667 if ( !$sourceSite or 00668 !$destinationSite ) 00669 { 00670 // Cannot move entries in site list 00671 return eZWebDAVServer::FAILED_FORBIDDEN; 00672 } 00673 00674 if ( !$this->userHasSiteAccess( $sourceSite ) ) 00675 { 00676 $this->appendLogEntry( "No access to site '$sourceSite'", 'CS:move' ); 00677 return eZWebDAVServer::FAILED_FORBIDDEN; 00678 } 00679 if ( !$this->userHasSiteAccess( $destinationSite ) ) 00680 { 00681 $this->appendLogEntry( "No access to site '$destinationSite'", 'CS:move' ); 00682 return eZWebDAVServer::FAILED_FORBIDDEN; 00683 } 00684 00685 return $this->moveVirtualFolder( $sourceSite, $destinationSite, 00686 $source, $destination, 00687 $fullSource, $fullDestination ); 00688 } 00689 00690 /*! 00691 \private 00692 Handles moving on the virtual folder level. 00693 It will check if the target is below a content folder in which it calls moveContent(). 00694 */ 00695 function moveVirtualFolder( $sourceSite, $destinationSite, 00696 $source, $destination, 00697 $fullSource, $fullDestination ) 00698 { 00699 $this->setCurrentSite( $sourceSite ); 00700 00701 $source = $this->splitFirstPathElement( $source, $sourceVFolder ); 00702 $destination = $this->splitFirstPathElement( $destination, $destinationVFolder ); 00703 00704 if ( !in_array( $sourceVFolder, $this->virtualList() ) ) 00705 { 00706 $this->appendLogEntry( "Unknown virtual element: '$sourceVFolder' in site '$sourceSite'", 'CS:moveVirtualFolder' ); 00707 return eZWebDAVServer::FAILED_NOT_FOUND; 00708 } 00709 00710 if ( !in_array( $destinationVFolder, $this->virtualList() ) ) 00711 { 00712 $this->appendLogEntry( "Unknown virtual element: '$destinationVFolder' in site '$destinationSite'", 'CS:moveVirtualFolder' ); 00713 return eZWebDAVServer::FAILED_NOT_FOUND; 00714 } 00715 00716 if ( !$source or 00717 !$destination ) 00718 { 00719 // We have reached the end of the path for source or destination 00720 // We do not allow 'move' operations for the virtual folder (from or to) 00721 return eZWebDAVServer::FAILED_FORBIDDEN; 00722 } 00723 00724 if ( !$this->userHasVirtualAccess( $sourceSite, $sourceVFolder ) ) 00725 { 00726 $this->appendLogEntry( "No access to virtual folder '$sourceVFolder' in site '$sourceSite'", 'CS:moveVirtualFolder' ); 00727 return eZWebDAVServer::FAILED_FORBIDDEN; 00728 } 00729 if ( !$this->userHasVirtualAccess( $destinationSite, $destinationVFolder ) ) 00730 { 00731 $this->appendLogEntry( "No access to virtual folder '$destinationVFolder' in site '$destinationSite'", 'CS:moveVirtualFolder' ); 00732 return eZWebDAVServer::FAILED_FORBIDDEN; 00733 } 00734 00735 if ( ( $sourceVFolder == eZWebDAVContentServer::virtualContentFolderName() or 00736 $sourceVFolder == eZWebDAVContentServer::virtualMediaFolderName() ) and 00737 ( $destinationVFolder == eZWebDAVContentServer::virtualContentFolderName() or 00738 $destinationVFolder == eZWebDAVContentServer::virtualMediaFolderName() ) ) 00739 { 00740 return $this->moveContent( $sourceSite, $destinationSite, 00741 $sourceVFolder, $destinationVFolder, 00742 $source, $destination, 00743 $fullSource, $fullDestination ); 00744 } 00745 00746 return eZWebDAVServer::FAILED_FORBIDDEN; 00747 } 00748 00749 /*! 00750 \private 00751 Handles moving on the content tree level. 00752 It will try to find the node of the target \a $source 00753 and then try to move it to \a $destination. 00754 */ 00755 function moveContent( $sourceSite, $destinationSite, 00756 $sourceVFolder, $destinationVFolder, 00757 $source, $destination, 00758 $fullSource, $fullDestination ) 00759 { 00760 $nodePath = $this->internalNodePath( $sourceVFolder, $source ); 00761 $destinationNodePath = $this->internalNodePath( $destinationVFolder, $destination ); 00762 00763 // Get rid of possible extensions, remove .jpeg .txt .html etc.. 00764 $source = $this->fileBasename( $source ); 00765 00766 $sourceNode = $this->fetchNodeByTranslation( $nodePath ); 00767 00768 if ( !$sourceNode ) 00769 { 00770 return eZWebDAVServer::FAILED_NOT_FOUND; 00771 } 00772 00773 // Can we move the node from $sourceNode 00774 if ( !$sourceNode->canMoveFrom() ) 00775 { 00776 $this->appendLogEntry( "No access to move the node '$sourceSite':'$nodePath'", 'CS:moveContent' ); 00777 return eZWebDAVServer::FAILED_FORBIDDEN; 00778 } 00779 00780 $object = $sourceNode->attribute( 'object' ); 00781 $classID = $object->attribute( 'contentclass_id' ); 00782 00783 // Get rid of possible extensions, remove .jpeg .txt .html etc.. 00784 $destination = $this->fileBasename( $destination ); 00785 00786 $destinationNode = $this->fetchNodeByTranslation( $destinationNodePath ); 00787 $this->appendLogEntry( "Destination: $destinationNodePath", 'CS:moveContent' ); 00788 00789 if ( $destinationNode ) 00790 { 00791 return eZWebDAVServer::FAILED_EXISTS; 00792 } 00793 00794 $destinationNode = $this->fetchParentNodeByTranslation( $destinationNodePath ); 00795 00796 if ( !$destinationNode ) 00797 { 00798 return eZWebDAVServer::FAILED_NOT_FOUND; 00799 } 00800 00801 // Can we move the node to $destinationNode 00802 if ( !$destinationNode->canMoveTo( $classID ) ) 00803 { 00804 $this->appendLogEntry( "No access to move the node '$sourceSite':'$nodePath' to '$destinationSite':'$destinationNodePath'", 'CS:moveContent' ); 00805 return eZWebDAVServer::FAILED_FORBIDDEN; 00806 } 00807 00808 $srcParentPath = $this->splitLastPathElement( $nodePath, $srcNodeName ); 00809 $dstParentPath = $this->splitLastPathElement( $destinationNodePath, $dstNodeName ); 00810 if ( $srcParentPath == $dstParentPath ) 00811 { 00812 if( !$object->rename( $dstNodeName ) ) 00813 { 00814 $this->appendLogEntry( "Unable to rename the node '$sourceSite':'$nodePath' to '$destinationSite':'$destinationNodePath'", 'CS:moveContent' ); 00815 return eZWebDAVServer::FAILED_FORBIDDEN; 00816 } 00817 } 00818 else 00819 { 00820 //include_once( 'kernel/classes/ezcontentobjecttreenodeoperations.php' ); 00821 if( !eZContentObjectTreeNodeOperations::move( $sourceNode->attribute( 'node_id' ), $destinationNode->attribute( 'node_id' ) ) ) 00822 { 00823 $this->appendLogEntry( "Unable to move the node '$sourceSite':'$nodePath' to '$destinationSite':'$destinationNodePath'", 'CS:moveContent' ); 00824 return eZWebDAVServer::FAILED_FORBIDDEN; 00825 } 00826 } 00827 00828 /* 00829 00830 // Todo: add lookup of the name setting for the current object 00831 $contentObjectID = $object->attribute( 'id' ); 00832 $contentObjectAttributes =& $object->contentObjectAttributes(); 00833 $contentObjectAttributes[0]->setAttribute( 'data_text', basename( $destination ) ); 00834 $contentObjectAttributes[0]->store(); 00835 00836 //include_once( 'lib/ezutils/classes/ezoperationhandler.php' ); 00837 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 'version' => 1 ) ); 00838 $object->store(); 00839 */ 00840 00841 return eZWebDAVServer::OK_CREATED; 00842 } 00843 00844 /*! 00845 @} 00846 */ 00847 00848 /*! 00849 Sets/changes the current site(access) to a \a $site. 00850 */ 00851 function setCurrentSite( $site ) 00852 { 00853 $access = array( 'name' => $site, 00854 'type' => EZ_ACCESS_TYPE_STATIC ); 00855 00856 $access = changeAccess( $access ); 00857 eZDebugSetting::writeDebug( 'kernel-siteaccess', $access, 'current siteaccess' ); 00858 00859 // Clear/flush global database instance. 00860 $nullVar = null; 00861 eZDB::setInstance( $nullVar ); 00862 } 00863 00864 /*! 00865 Checks if the current user has access rights to site \a $site. 00866 \return \c true if the user proper access. 00867 */ 00868 function userHasSiteAccess( $site ) 00869 { 00870 $result = $this->User->hasAccessTo( 'user', 'login' ); 00871 $accessWord = $result['accessWord']; 00872 00873 if ( $accessWord == 'limited' ) 00874 { 00875 //include_once( 'lib/ezutils/classes/ezsys.php' ); 00876 00877 $hasAccess = false; 00878 $policyChecked = false; 00879 foreach ( array_keys( $result['policies'] ) as $key ) 00880 { 00881 $policy =& $result['policies'][$key]; 00882 if ( isset( $policy['SiteAccess'] ) ) 00883 { 00884 $policyChecked = true; 00885 if ( in_array( eZSys::ezcrc32( $site ), $policy['SiteAccess'] ) ) 00886 { 00887 $hasAccess = true; 00888 break; 00889 } 00890 } 00891 if ( $hasAccess ) 00892 break; 00893 } 00894 if ( !$policyChecked ) 00895 $hasAccess = true; 00896 } 00897 else if ( $accessWord == 'yes' ) 00898 { 00899 $hasAccess = true; 00900 } 00901 else if ( $accessWord == 'no' ) 00902 { 00903 $hasAccess = false; 00904 } 00905 return $hasAccess; 00906 } 00907 00908 /*! 00909 Checks if the current user has access rights to virtual element \a virtual 00910 on site \a $site. 00911 \return \c true if the user proper access. 00912 */ 00913 function userHasVirtualAccess( $site, $virtual ) 00914 { 00915 $this->appendLogEntry( "Can access '$site' and '$virtual'", 'CS:userHasVirtualAccess' ); 00916 return true; 00917 } 00918 00919 /*! 00920 Detects a possible/valid site-name in start of a path. 00921 \return The name of the site that was detected or \c false if not site could be detected 00922 */ 00923 function currentSiteFromPath( $path ) 00924 { 00925 $this->appendLogEntry( "start path: $path", 'CS:currentSiteFromPath' ); 00926 00927 $indexDir = eZSys::indexDir(); 00928 00929 // Remove indexDir if used in non-virtualhost mode. 00930 if ( preg_match( "#^" . preg_quote( $indexDir ) . "(.+)$#", $path, $matches ) ) 00931 { 00932 $path = $matches[1]; 00933 } 00934 00935 $this->appendLogEntry( "indexdir: $path", 'CS:currentSiteFromPath' ); 00936 00937 // Get the list of available sites. 00938 $sites = $this->availableSites(); 00939 00940 foreach ( $sites as $site ) 00941 { 00942 // Check if given path starts with this site-name, if so: return it. 00943 if ( preg_match( "#^/" . preg_quote( $site ) . "(.*)$#", $path, $matches ) ) 00944 { 00945 $this->appendLogEntry( "site $site: $path", 'CS:currentSiteFromPath' ); 00946 return $site ; 00947 } 00948 } 00949 00950 $this->appendLogEntry( "no valid site was found..", 'CS:currentSiteFromPath' ); 00951 return false ; 00952 } 00953 00954 /*! 00955 \reimp 00956 Removes the www-dir and indexfile from the URL. 00957 */ 00958 function processURL( $url ) 00959 { 00960 $this->appendLogEntry( "start url: $url", 'CS:processURL' ); 00961 $indexDir = eZSys::indexDir(); 00962 $len = strlen( $indexDir ); 00963 00964 if ( $indexDir == substr( $url, 0, $len ) ) 00965 { 00966 $url = substr( $url, $len ); 00967 } 00968 00969 // Remove the starting / if there is one 00970 // the rest of the operation code expects this to not be present 00971 if ( strlen( $url ) > 0 and $url[0] == '/' ) 00972 $url = substr( $url, 1 ); 00973 00974 $this->appendLogEntry( "indexdir url: $url", 'CS:processURL' ); 00975 return $url; 00976 } 00977 00978 /*! 00979 \reimp 00980 */ 00981 function headers() 00982 { 00983 header( "WebDAV-Powered-By: eZ Publish" ); 00984 } 00985 00986 /*! 00987 Takes the first path element from \a $path and removes it from 00988 the path, the extracted part will be placed in \a $name. 00989 \return A string containing the rest of the path, 00990 the path will not contain a starting slash. 00991 \param $path A string defining a path of elements delimited by a slash, 00992 if the path starts with a slash it will be removed. 00993 \param[out] $element The name of the first path element without any slashes. 00994 00995 \code 00996 $path = '/path/to/item/'; 00997 $newPath = eZWebDAVContentServer::splitFirstPathElement( $path, $root ); 00998 print( $root ); // prints 'path', $newPath is now 'to/item/' 00999 $newPath = eZWebDAVContentServer::splitFirstPathElement( $newPath, $second ); 01000 print( $second ); // prints 'to', $newPath is now 'item/' 01001 $newPath = eZWebDAVContentServer::splitFirstPathElement( $newPath, $third ); 01002 print( $third ); // prints 'item', $newPath is now '' 01003 \endcode 01004 */ 01005 function splitFirstPathElement( $path, &$element ) 01006 { 01007 if ( $path[0] == '/' ) 01008 $path = substr( $path, 1 ); 01009 $pos = strpos( $path, '/' ); 01010 if ( $pos === false ) 01011 { 01012 $element = $path; 01013 $path = ''; 01014 } 01015 else 01016 { 01017 $element = substr( $path, 0, $pos ); 01018 $path = substr( $path, $pos + 1 ); 01019 } 01020 return $path; 01021 } 01022 01023 /*! 01024 Takes the last path element from \a $path and removes it from 01025 the path, the extracted part will be placed in \a $name. 01026 \return A string containing the rest of the path, 01027 the path will not contain the ending slash. 01028 \param $path A string defining a path of elements delimited by a slash, 01029 if the path ends with a slash it will be removed. 01030 \param[out] $element The name of the first path element without any slashes. 01031 01032 \code 01033 $path = '/path/to/item/'; 01034 $newPath = eZWebDAVContentServer::splitLastPathElement( $path, $root ); 01035 print( $root ); // prints 'item', $newPath is now '/path/to' 01036 $newPath = eZWebDAVContentServer::splitLastPathElement( $newPath, $second ); 01037 print( $second ); // prints 'to', $newPath is now '/path' 01038 $newPath = eZWebDAVContentServer::splitLastPathElement( $newPath, $third ); 01039 print( $third ); // prints 'path', $newPath is now '' 01040 \endcode 01041 */ 01042 function splitLastPathElement( $path, &$element ) 01043 { 01044 $len = strlen( $path ); 01045 if ( $len > 0 and $path[$len - 1] == '/' ) 01046 $path = substr( $path, 0, $len - 1 ); 01047 $pos = strrpos( $path, '/' ); 01048 if ( $pos === false ) 01049 { 01050 $element = $path; 01051 $path = ''; 01052 } 01053 else 01054 { 01055 $element = substr( $path, $pos + 1 ); 01056 $path = substr( $path, 0, $pos ); 01057 } 01058 return $path; 01059 } 01060 01061 /*! 01062 \private 01063 \return A path that corresponds to the internal path of nodes. 01064 */ 01065 function internalNodePath( $virtualFolder, $collection ) 01066 { 01067 // All root nodes needs to prepend their name to get the correct path 01068 // except for the content root which uses the path directly. 01069 if ( $virtualFolder == eZWebDAVContentServer::virtualMediaFolderName() ) 01070 { 01071 $nodePath = 'media'; 01072 if ( strlen( $collection ) > 0 ) 01073 $nodePath .= '/' . $collection; 01074 } 01075 else 01076 { 01077 $nodePath = $collection; 01078 } 01079 return $nodePath; 01080 } 01081 01082 /*! 01083 Attempts to fetch a possible/existing node by translating 01084 the inputted string/path to a node-number. 01085 */ 01086 function fetchNodeByTranslation( $nodePathString ) 01087 { 01088 // Get rid of possible extensions, remove .jpeg .txt .html etc.. 01089 $nodePathString = $this->fileBasename( $nodePathString ); 01090 01091 // Strip away last slash 01092 if ( strlen( $nodePathString ) > 0 and 01093 $nodePathString[strlen( $nodePathString ) - 1] == '/' ) 01094 { 01095 $nodePathString = substr( $nodePathString, 0, strlen( $nodePathString ) - 1 ); 01096 } 01097 01098 if ( strlen( $nodePathString ) > 0 ) 01099 { 01100 $nodePathString = eZURLAliasML::convertPathToAlias( $nodePathString ); 01101 } 01102 01103 // Attempt to get nodeID from the URL. 01104 $nodeID = eZURLAliasML::fetchNodeIDByPath( $nodePathString ); 01105 if ( $nodeID ) 01106 { 01107 $this->appendLogEntry( "NodeID: $nodeID", 'CS:fetchNodeByTranslation' ); 01108 } 01109 else 01110 { 01111 $this->appendLogEntry( "No nodeID", 'CS:fetchNodeByTranslation' ); 01112 return false; 01113 } 01114 01115 // Attempt to fetch the node. 01116 $node = eZContentObjectTreeNode::fetch( $nodeID ); 01117 01118 // Return the node. 01119 return $node; 01120 } 01121 01122 /*! 01123 \return The string \a $name without the final suffix (.jpg, .gif etc.) 01124 */ 01125 function fileBasename( $name ) 01126 { 01127 $pos = strrpos( $name, '.' ); 01128 if ( $pos !== false ) 01129 { 01130 $name = substr( $name, 0, $pos ); 01131 } 01132 return $name; 01133 } 01134 01135 /*! 01136 Attempts to fetch a possible node by translating 01137 the inputted string/path to a node-number. The last 01138 section of the path is removed before the actual 01139 translation: hence, the PARENT node is returned. 01140 */ 01141 function fetchParentNodeByTranslation( $nodePathString ) 01142 { 01143 // Strip extensions. E.g. .jpg 01144 $nodePathString = $this->fileBasename( $nodePathString ); 01145 01146 // Strip away last slash 01147 if ( strlen( $nodePathString ) > 0 and 01148 $nodePathString[strlen( $nodePathString ) - 1] == '/' ) 01149 { 01150 $nodePathString = substr( $nodePathString, 0, strlen( $nodePathString ) - 1 ); 01151 } 01152 01153 $nodePathString = $this->splitLastPathElement( $nodePathString, $element ); 01154 01155 if ( strlen( $nodePathString ) == 0 ) 01156 $nodePathString = '/'; 01157 01158 $nodePathString = eZURLAliasML::convertPathToAlias( $nodePathString ); 01159 01160 // Attempt to translate the URL to something like "/content/view/full/84". 01161 $translateResult = eZURLAliasML::translate( $nodePathString ); 01162 01163 // handle redirects 01164 while ( $nodePathString == 'error/301' ) 01165 { 01166 $nodePathString = $translateResult; 01167 01168 $translateResult = eZURLAliasML::translate( $nodePathString ); 01169 } 01170 01171 // Get the ID of the node (which is the last part of the translated path). 01172 if ( preg_match( "#^content/view/full/([0-9]+)$#", $nodePathString, $matches ) ) 01173 { 01174 $nodeID = $matches[1]; 01175 $this->appendLogEntry( "NodeID: $nodeID", 'CS:fetchParentNodeByTranslation' ); 01176 } 01177 else 01178 { 01179 $this->appendLogEntry( "Root node", 'CS:fetchParentNodeByTranslation' ); 01180 $nodeID = 2; 01181 } 01182 01183 // Attempt to fetch the node. 01184 $node = eZContentObjectTreeNode::fetch( $nodeID ); 01185 01186 // Return the node. 01187 return $node; 01188 } 01189 01190 /*! 01191 \return An array containing the names of all folders in the virtual root. 01192 */ 01193 function virtualFolderList() 01194 { 01195 return array( eZWebDAVContentServer::virtualContentFolderName(), eZWebDAVContentServer::virtualMediaFolderName() ); 01196 } 01197 01198 /*! 01199 \return An array containing the names of all folders in the virtual root. 01200 */ 01201 function virtualFolderInfoList() 01202 { 01203 return array( array( 'name' => eZWebDAVContentServer::virtualContentFolderName() ), 01204 array( 'name' => eZWebDAVContentServer::virtualMediaFolderName() ) ); 01205 } 01206 01207 /*! 01208 \return An array containing the names of all files in the virtual root. 01209 */ 01210 function virtualFileList() 01211 { 01212 return array( basename( eZWebDAVContentServer::virtualInfoFileName() ) ); 01213 } 01214 01215 /*! 01216 \return An array containing the names of all files in the virtual root. 01217 */ 01218 function virtualFileInfoList() 01219 { 01220 return array( array( 'name' => basename( eZWebDAVContentServer::virtualInfoFileName() ), 01221 'filepath' => eZWebDAVContentServer::virtualInfoFileName() ) ); 01222 } 01223 01224 /*! 01225 \return An array containing the names of all elements in the virtual root. 01226 */ 01227 function virtualList() 01228 { 01229 return array_merge( eZWebDAVContentServer::virtualFolderList(), 01230 eZWebDAVContentServer::virtualFileList() ); 01231 } 01232 01233 /*! 01234 \return An array containing the names of all elements in the virtual root. 01235 */ 01236 function virtualInfoList() 01237 { 01238 return array_merge( eZWebDAVContentServer::virtualFolderInfoList(), 01239 eZWebDAVContentServer::virtualFileInfoList() ); 01240 } 01241 01242 /*! 01243 Functions related to creation collections 01244 @{ 01245 */ 01246 01247 /*! 01248 Builds and returns the content of the virtual start fodler 01249 for a site. The virtual startfolder is an intermediate step 01250 between the site-list and actual content. This directory 01251 contains the "content" folder which leads to the site's 01252 actual content. 01253 */ 01254 function fetchVirtualSiteContent( $site, $depth, $properties ) 01255 { 01256 $this->appendLogEntry( "Script URL.." . eZSys::instance()->RequestURI, 'CS:fetchVirtualSiteContent' ); 01257 // Location of the info file. 01258 $infoFile = $_SERVER['DOCUMENT_ROOT'] . '/' . eZWebDAVContentServer::virtualInfoFileName(); 01259 01260 // Always add the current collection 01261 $contentEntry = array(); 01262 $contentEntry["name"] = eZSys::instance()->RequestURI; 01263 $contentEntry["size"] = 0; 01264 $contentEntry["mimetype"] = 'httpd/unix-directory'; 01265 $contentEntry["ctime"] = filectime( 'settings/siteaccess/' . $site ); 01266 $contentEntry["mtime"] = filemtime( 'settings/siteaccess/' . $site ); 01267 $contentEntry["href"] = eZSys::instance()->RequestURI; 01268 $entries[] = $contentEntry; 01269 01270 $defctime = $contentEntry['ctime']; 01271 $defmtime = $contentEntry['mtime']; 01272 01273 if ( $depth > 0 ) 01274 { 01275 $scriptURL = eZSys::instance()->RequestURI; 01276 if ( $scriptURL{strlen($scriptURL) - 1} != "/" ) 01277 $scriptURL .= "/"; 01278 01279 // Set up attributes for the virtual content folder: 01280 foreach ( $this->virtualInfoList() as $info ) 01281 { 01282 $name = $info['name']; 01283 $filepath = false; 01284 if ( isset( $info['filepath'] ) ) 01285 $filepath = $info['filepath']; 01286 $size = 0; 01287 if ( $filepath === false or file_exists( $filepath ) ) 01288 { 01289 $mimeType = 'httpd/unix-directory'; 01290 if ( $filepath !== false ) 01291 { 01292 $mimeInfo = eZMimeType::findByFileContents( $filepath ); 01293 $mimeType = $mimeInfo['name']; 01294 $ctime = filectime( $filepath ); 01295 $mtime = filemtime( $filepath ); 01296 $size = filesize( $filepath ); 01297 } 01298 else 01299 { 01300 $ctime = $defctime; 01301 $mtime = $defmtime; 01302 } 01303 01304 $entry = array(); 01305 $entry["name"] = $name; 01306 $entry["size"] = $size; 01307 $entry["mimetype"] = $mimeType; 01308 $entry["ctime"] = $ctime; 01309 $entry["mtime"] = $mtime; 01310 $entry["href"] = $scriptURL . $name; 01311 $entries[] = $entry; 01312 } 01313 } 01314 } 01315 01316 return $entries; 01317 } 01318 01319 /*! 01320 Builds a content-list of available sites and returns it. 01321 */ 01322 function fetchSiteListContent( $depth, $properties ) 01323 { 01324 // At the end: we'll return an array of entry-arrays. 01325 $entries = array(); 01326 01327 // An entry consists of several attributes (name, size, etc). 01328 $contentEntry = array(); 01329 $entries = array(); 01330 01331 // Set up attributes for the virtual site-list folder: 01332 $contentEntry["name"] = '/'; 01333 $contentEntry["href"] = eZSys::instance()->RequestURI; 01334 $contentEntry["size"] = 0; 01335 $contentEntry["mimetype"] = 'httpd/unix-directory'; 01336 $contentEntry["ctime"] = filectime( 'var' ); 01337 $contentEntry["mtime"] = filemtime( 'var' ); 01338 01339 $entries[] = $contentEntry; 01340 01341 if ( $depth > 0 ) 01342 { 01343 // Get list of available sites. 01344 $sites = $this->availableSites(); 01345 01346 // For all available sites: 01347 foreach ( $sites as $site ) 01348 { 01349 // Set up attributes for the virtual site-list folder: 01350 $contentEntry["name"] = eZSys::instance()->RequestURI . $site; 01351 $contentEntry["size"] = 0; 01352 $contentEntry["mimetype"] = 'httpd/unix-directory'; 01353 $contentEntry["ctime"] = filectime( 'settings/siteaccess/' . $site ); 01354 $contentEntry["mtime"] = filemtime( 'settings/siteaccess/' . $site ); 01355 01356 if ( eZSys::instance()->RequestURI == '/' ) 01357 { 01358 $contentEntry["href"] = $contentEntry["name"]; 01359 } 01360 else 01361 { 01362 $contentEntry["href"] = eZSys::instance()->RequestURI . $contentEntry["name"]; 01363 } 01364 01365 $entries[] = $contentEntry; 01366 } 01367 } 01368 01369 return $entries; 01370 } 01371 01372 /*! 01373 Gets and returns the content of an actual node. 01374 List of other nodes belonging to the target node 01375 (one level below it) will be returned. 01376 */ 01377 function fetchContentList( &$node, $target, $depth, $properties ) 01378 { 01379 // We'll return an array of entries (which is an array of attributes). 01380 $entries = array(); 01381 01382 if ( $depth == 1 ) 01383 { 01384 // Get all the children of the target node. 01385 $subTree = $node->subTree( array ( 'Depth' => 1 ) ); 01386 01387 // Build the entries array by going through all the 01388 // nodes in the subtree and getting their attributes: 01389 foreach ( $subTree as $someNode ) 01390 { 01391 $entries[] = $this->fetchNodeInfo( $someNode ); 01392 } 01393 } 01394 01395 // Always include the information about the current level node 01396 $thisNodeInfo = array(); 01397 $thisNodeInfo = $this->fetchNodeInfo( $node ); 01398 $thisNodeInfo["href"] = eZSys::instance()->RequestURI; 01399 $entries[] = $thisNodeInfo; 01400 01401 // Return the content of the target. 01402 return $entries; 01403 } 01404 01405 /*! 01406 \return \c true if the object \a $object should always be considered a folder. 01407 */ 01408 function isObjectFolder( $object, &$class ) 01409 { 01410 $classIdentifier = $class->attribute( 'identifier' ); 01411 if ( $this->FolderClasses === null ) 01412 { 01413 $webdavINI = eZINI::instance( eZWebDAVContentServer::WEBDAV_INI_FILE ); 01414 $folderClasses = array(); 01415 if ( $webdavINI->hasGroup( 'GeneralSettings' ) and 01416 $webdavINI->hasVariable( 'GeneralSettings', 'FolderClasses' ) ) 01417 { 01418 $folderClasses = $webdavINI->variable( 'GeneralSettings', 'FolderClasses' ); 01419 } 01420 $this->FolderClasses = $folderClasses; 01421 } 01422 return in_array( $classIdentifier, $this->FolderClasses ); 01423 } 01424 01425 /*! 01426 Gathers information about a given node (specified as parameter). 01427 */ 01428 function fetchNodeInfo( &$node ) 01429 { 01430 // When finished, we'll return an array of attributes/properties. 01431 $entry = array(); 01432 01433 // Grab settings from the ini file: 01434 $webdavINI = eZINI::instance( eZWebDAVContentServer::WEBDAV_INI_FILE ); 01435 $iniSettings = $webdavINI->variable( 'DisplaySettings', 'FileAttribute' ); 01436 01437 $classIdentifier = $node->attribute( 'class_identifier' ); 01438 01439 $object = $node->attribute( 'object' ); 01440 01441 // By default, everything is displayed as a folder: 01442 // Trim the name of the node, it is in some cases whitespace in eZ Publish 01443 $entry["name"] = trim( $node->attribute( 'name' ) ); 01444 $entry["size"] = 0; 01445 $entry["mimetype"] = 'httpd/unix-directory'; 01446 $entry["ctime"] = $object->attribute( 'published' ); 01447 $entry["mtime"] = $object->attribute( 'modified' ); 01448 01449 //include_once( 'kernel/classes/ezcontentupload.php' ); 01450 $upload = new eZContentUpload(); 01451 $info = $upload->objectFileInfo( $object ); 01452 $suffix = ''; 01453 $class = $object->contentClass(); 01454 $isObjectFolder = $this->isObjectFolder( $object, $class ); 01455 01456 if ( $isObjectFolder ) 01457 { 01458 // We do nothing, the default is to see it as a folder 01459 } 01460 else if ( $info ) 01461 { 01462 $filePath = $info['filepath']; 01463 $entry["mimetype"] = false; 01464 $entry["size"] = false; 01465 if ( isset( $info['filesize'] ) ) 01466 $entry['size'] = $info['filesize']; 01467 if ( isset( $info['mime_type'] ) ) 01468 $entry['mimetype'] = $info['mime_type']; 01469 01470 // Fill in information from the actual file if they are missing. 01471 $file = eZClusterFileHandler::instance( $filePath ); 01472 if ( !$entry['size'] and $file->exists() ) 01473 { 01474 $entry["size"] = $file->size(); 01475 } 01476 if ( !$entry['mimetype'] ) 01477 { 01478 $mimeInfo = eZMimeType::findByURL( $filePath ); 01479 $entry["mimetype"] = $mimeInfo['name']; 01480 $suffix = $mimeInfo['suffix']; 01481 if ( strlen( $suffix ) > 0 ) 01482 $entry["name"] .= '.' . $suffix; 01483 } 01484 else 01485 { 01486 // eZMimeType returns first suffix in its list 01487 // this could be another one than the original file extension 01488 // so let's try to get the suffix from the file path first 01489 $suffix = eZFile::suffix( $filePath ); 01490 if ( !$suffix ) 01491 { 01492 $mimeInfo = eZMimeType::findByName( $entry['mimetype'] ); 01493 $suffix = $mimeInfo['suffix']; 01494 } 01495 if ( strlen( $suffix ) > 0 ) 01496 $entry["name"] .= '.' . $suffix; 01497 } 01498 01499 if ( $file->exists() ) 01500 { 01501 $entry["ctime"] = $file->mtime(); 01502 $entry["mtime"] = $file->mtime(); 01503 } 01504 } 01505 else 01506 { 01507 // Here we only show items as folders if they have 01508 // is_container set to true, otherwise it's an unknown binary file 01509 if ( !$class->attribute( 'is_container' ) ) 01510 { 01511 $entry['mimetype'] = 'application/octet-stream'; 01512 } 01513 } 01514 01515 $scriptURL = eZSys::instance()->RequestURI; 01516 if ( strlen( $scriptURL ) > 0 and $scriptURL[ strlen( $scriptURL ) - 1 ] != "/" ) 01517 $scriptURL .= "/"; 01518 01519 $trimmedScriptURL = trim( $scriptURL, '/' ); 01520 $scriptURLParts = explode( '/', $trimmedScriptURL ); 01521 01522 $siteAccess = $scriptURLParts[0]; 01523 $virtualFolder = $scriptURLParts[1]; 01524 01525 $startURL = '/' . $siteAccess . '/' . $virtualFolder . '/'; 01526 01527 // Set the href attribute (note that it doesn't just equal the name). 01528 if ( !isset( $entry['href'] ) ) 01529 { 01530 if ( strlen( $suffix ) > 0 ) 01531 $suffix = '.' . $suffix; 01532 01533 $alias = $node->urlAlias(); 01534 if ( $virtualFolder == eZWebDAVContentServer::virtualMediaFolderName() ) 01535 { 01536 // remove the real media node url alias, the virtual media folder is already in $startURL 01537 $aliasParts = explode( '/', $alias ); 01538 array_shift( $aliasParts ); 01539 $alias = implode( '/', $aliasParts ); 01540 } 01541 $entry["href"] = $startURL . $alias . $suffix; 01542 } 01543 // Return array of attributes/properties (name, size, mime, times, etc.). 01544 return $entry; 01545 } 01546 01547 /*! 01548 @} 01549 */ 01550 01551 /*! 01552 Creates a new folder under the given target node. 01553 */ 01554 function createFolder( $parentNode, $target ) 01555 { 01556 // Grab settings from the ini file: 01557 $webdavINI = eZINI::instance( eZWebDAVContentServer::WEBDAV_INI_FILE ); 01558 $folderClassID = $webdavINI->variable( 'FolderSettings', 'FolderClass' ); 01559 $languageCode = eZContentObject::defaultLanguage(); 01560 01561 $contentObject = eZContentObject::createWithNodeAssignment( $parentNode, $folderClassID, $languageCode ); 01562 if ( $contentObject ) 01563 { 01564 $db = eZDB::instance(); 01565 $db->begin(); 01566 $version = $contentObject->version( 1 ); 01567 $version->setAttribute( 'status', eZContentObjectVersion::STATUS_DRAFT ); 01568 $version->store(); 01569 01570 $contentObjectID = $contentObject->attribute( 'id' ); 01571 $contentObjectAttributes = $version->contentObjectAttributes(); 01572 01573 $contentObjectAttributes[0]->setAttribute( 'data_text', basename( $target ) ); 01574 $contentObjectAttributes[0]->store(); 01575 $db->commit(); 01576 01577 //include_once( 'lib/ezutils/classes/ezoperationhandler.php' ); 01578 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 01579 'version' => 1 ) ); 01580 return eZWebDAVServer::OK_CREATED; 01581 } 01582 else 01583 { 01584 $this->appendLogEntry( "Not allowed", 'CS:createFolder' ); 01585 return eZWebDAVServer::FAILED_FORBIDDEN; 01586 } 01587 } 01588 01589 /*! 01590 Gets and returns a list of the available sites (from site.ini). 01591 */ 01592 function availableSites() 01593 { 01594 // The site list is an array of strings. 01595 $siteList = array(); 01596 01597 // Grab the sitelist from the ini file. 01598 $webdavINI = eZINI::instance(); 01599 $siteList = $webdavINI->variable( 'SiteSettings', 'SiteList' ); 01600 01601 // Return the site list. 01602 return $siteList ; 01603 } 01604 01605 static function virtualContentFolderName() 01606 { 01607 return ezi18n( 'kernel/content', "Content" ); 01608 } 01609 01610 static function virtualMediaFolderName() 01611 { 01612 return ezi18n( 'kernel/content', "Media" ); 01613 } 01614 01615 static function virtualInfoFileName() 01616 { 01617 $infoFile = eZSys::varDirectory() . '/webdav/root/info.txt'; 01618 return $infoFile; 01619 } 01620 01621 /// \privatesection 01622 /// Contains an array with classes that are considered folder 01623 public $FolderClasses; 01624 } 01625 ?>