/Webdav/src/backends/file.php
PHP | 1306 lines | 544 code | 129 blank | 633 comment | 44 complexity | 8bf534bba0ea7d2f0a0ad0dcdcbb469d MD5 | raw file
- <?php
- /**
- * File containing the ezcWebdavFileBackend class.
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * @package Webdav
- * @version //autogentag//
- * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
- */
- /**
- * File system based backend.
- *
- * This backend serves WebDAV resources from a directory structure in the file
- * system. It simply handles directories as collection resources and files as
- * non-collection resources. The path to server resources from is defined
- * during construction.
- *
- * <code>
- * $backend = new ezcWebdavFileBackend(
- * 'directory/'
- * );
- * </code>
- *
- * Live properties are partly determined from the file systems itself (like
- * {@link ezcWebdavGetContentLengthProperty}), others need to be stored like
- * dead properties. This backend uses a special path for each resource to store
- * this information in its XML representation.
- *
- * @version //autogentag//
- * @package Webdav
- * @mainclass
- */
- class ezcWebdavFileBackend extends ezcWebdavSimpleBackend implements ezcWebdavLockBackend
- {
- /**
- * Options.
- *
- * @var ezcWebdavFileBackendOptions
- */
- protected $options;
- /**
- * Root directory to serve content from. All paths are seen relatively to this one.
- *
- * @var string
- */
- protected $root;
- /**
- * Keeps track of the lock level.
- *
- * Each time the lock() method is called, this counter is raised by 1. if
- * it was 0 before, the actual locking mechanism gets into action,
- * otherwise just the counter is raised. The lock is physically only freed,
- * if this counter is 0.
- *
- * This mechanism allows nested locking, as it is necessary, if the lock
- * plugin locks this backend external, but interal locking needs still to
- * be supported.
- *
- * @var int
- */
- protected $lockLevel = 0;
- /**
- * Names of live properties from the DAV: namespace which will be handled
- * live, and should not be stored like dead properties.
- *
- * @var array(int=>string)
- */
- protected $handledLiveProperties = array(
- 'getcontentlength',
- 'getlastmodified',
- 'creationdate',
- 'displayname',
- 'getetag',
- 'getcontenttype',
- 'resourcetype',
- 'supportedlock',
- 'lockdiscovery',
- );
- /**
- * Creates a new backend instance.
- *
- * Creates a new backend to server WebDAV content from the file system path
- * identified by $root. If the given path does not exist or is not a
- * directory, an exception will be thrown.
- *
- * @param string $root
- * @return void
- *
- * @throws ezcBaseFileNotFoundException
- * if the given $root does not exist or is not a directory.
- * @throws ezcBaseFilePermissionException
- * if the given $root is not readable.
- */
- public function __construct( $root )
- {
- if ( !is_dir( $root ) )
- {
- throw new ezcBaseFileNotFoundException( $root );
- }
- if ( !is_readable( $root ) )
- {
- throw new ezcBaseFilePermissionException( $root, ezcBaseFileException::READ );
- }
- $this->root = realpath( $root );
- $this->options = new ezcWebdavFileBackendOptions();
- }
- /**
- * Locks the backend.
- *
- * Tries to lock the backend. If the lock is already owned by this process,
- * locking is successful. If $timeout is reached before a lock could be
- * acquired, an {@link ezcWebdavLockTimeoutException} is thrown. Waits
- * $waitTime microseconds between attempts to lock the backend.
- *
- * @param int $waitTime
- * @param int $timeout
- * @return void
- */
- public function lock( $waitTime, $timeout )
- {
- // Check and raise lockLevel counter
- if ( $this->lockLevel > 0 )
- {
- // Lock already acquired
- ++$this->lockLevel;
- return;
- }
- $lockStart = microtime( true );
- $lockFileName = $this->root . '/' . $this->options->lockFileName;
- if ( is_file( $lockFileName ) && !is_writable( $lockFileName )
- || !is_file( $lockFileName ) && !is_writable(dirname( $lockFileName ) ) )
- {
- throw new ezcBaseFilePermissionException(
- $lockFileName,
- ezcBaseFileException::WRITE,
- 'Cannot be used as lock file.'
- );
- }
- // fopen in mode 'x' will only open the file, if it does not exist yet.
- // Even this is is expected it will throw a warning, if the file
- // exists, which we need to silence using the @
- while ( ( $fp = @fopen( $lockFileName, 'x' ) ) === false )
- {
- // This is untestable.
- if ( microtime( true ) - $lockStart > $timeout )
- {
- // Release timed out lock
- unlink( $lockFileName );
- $lockStart = microtime( true );
- }
- else
- {
- usleep( $waitTime );
- }
- }
- // Store random bit in file ... the microtime for example - might prove
- // useful some time.
- fwrite( $fp, microtime() );
- fclose( $fp );
- // Add first lock
- ++$this->lockLevel;
- }
- /**
- * Removes the lock.
- *
- * @return void
- */
- public function unlock()
- {
- if ( --$this->lockLevel === 0 )
- {
- // Remove the lock file
- $lockFileName = $this->root . '/' . $this->options->lockFileName;
- unlink( $lockFileName );
- }
- }
- /**
- * Property get access.
- * Simply returns a given property.
- *
- * @throws ezcBasePropertyNotFoundException
- * If a the value for the property propertys is not an instance of
- * @param string $name The name of the property to get.
- * @return mixed The property value.
- *
- * @ignore
- *
- * @throws ezcBasePropertyNotFoundException
- * if the given property does not exist.
- * @throws ezcBasePropertyPermissionException
- * if the property to be set is a write-only property.
- */
- public function __get( $name )
- {
- switch ( $name )
- {
- case 'options':
- return $this->$name;
- default:
- throw new ezcBasePropertyNotFoundException( $name );
- }
- }
- /**
- * Sets a property.
- * This method is called when an property is to be set.
- *
- * @param string $name The name of the property to set.
- * @param mixed $value The property value.
- * @return void
- * @ignore
- *
- * @throws ezcBasePropertyNotFoundException
- * if the given property does not exist.
- * @throws ezcBaseValueException
- * if the value to be assigned to a property is invalid.
- * @throws ezcBasePropertyPermissionException
- * if the property to be set is a read-only property.
- */
- public function __set( $name, $value )
- {
- switch ( $name )
- {
- case 'options':
- if ( ! $value instanceof ezcWebdavFileBackendOptions )
- {
- throw new ezcBaseValueException( $name, $value, 'ezcWebdavFileBackendOptions' );
- }
- $this->$name = $value;
- break;
- default:
- throw new ezcBasePropertyNotFoundException( $name );
- }
- }
- /**
- * Wait and get lock for complete directory tree.
- *
- * Acquire lock for the complete tree for read or write operations. This
- * does not implement any priorities for operations, or check if several
- * read operation may run in parallel. The plain locking should / could be
- * extended by something more sophisticated.
- *
- * If the tree already has been locked, the method waits until the lock can
- * be acquired.
- *
- * The optional second parameter $readOnly indicates wheather a read only
- * lock should be acquired. This may be used by extended implementations,
- * but it is not used in this implementation.
- *
- * @param bool $readOnly
- * @return void
- *
- * @todo The locking mechanism affects the ETag of the base collection. The
- * ETag is different on each request, which might result in problems
- * for clients that make extensive use of If-* headers. No client is
- * known so far, if problems occur here we need to find a solution
- * for this.
- */
- protected function acquireLock( $readOnly = false )
- {
- if ( $this->options->noLock )
- {
- return true;
- }
-
- try
- {
- $this->lock( $this->options->waitForLock, $this->options->lockTimeout );
- }
- catch ( ezcWebdavLockTimeoutException $e )
- {
- return false;
- }
- return true;
- }
- /**
- * Free lock.
- *
- * Frees the lock after the operation has been finished.
- *
- * @return void
- */
- protected function freeLock()
- {
- if ( $this->options->noLock )
- {
- return true;
- }
-
- $this->unlock();
- }
- /**
- * Returns the mime type of a resource.
- *
- * Return the mime type of the resource identified by $path. If a mime type
- * extension is available it will be used to read the real mime type,
- * otherwise the original mime type passed by the client when uploading the
- * file will be returned. If no mimetype has ever been associated with the
- * file, the method will just return 'application/octet-stream'.
- *
- * @param string $path
- * @return string
- */
- protected function getMimeType( $path )
- {
- // Check if extension pecl/fileinfo is usable.
- if ( $this->options->useMimeExts && ezcBaseFeatures::hasExtensionSupport( 'fileinfo' ) )
- {
- $fInfo = new fInfo( FILEINFO_MIME );
- $mimeType = $fInfo->file( $this->root . $path );
- // The documentation tells to do this, but it does not work with a
- // current version of pecl/fileinfo
- // $fInfo->close();
- return $mimeType;
- }
- // Check if extension ext/mime-magic is usable.
- if ( $this->options->useMimeExts &&
- ezcBaseFeatures::hasExtensionSupport( 'mime_magic' ) &&
- ( $mimeType = mime_content_type( $this->root . $path ) ) !== false )
- {
- return $mimeType;
- }
- // Check if some browser submitted mime type is available.
- $storage = $this->getPropertyStorage( $path );
- $properties = $storage->getAllProperties();
- if ( isset( $properties['DAV:']['getcontenttype'] ) )
- {
- return $properties['DAV:']['getcontenttype']->mime;
- }
- // Default to 'application/octet-stream' if nothing else is available.
- return 'application/octet-stream';
- }
- /**
- * Creates a new collection.
- *
- * Creates a new collection at the given $path.
- *
- * @param string $path
- * @return void
- */
- protected function createCollection( $path )
- {
- mkdir( $this->root . $path );
- chmod( $this->root . $path, $this->options->directoryMode );
- // This automatically creates the property storage
- $storage = $this->getPropertyStoragePath( $path . '/foo' );
- }
- /**
- * Creates a new resource.
- *
- * Creates a new resource at the given $path, optionally with the given
- * content. If $content is empty, an empty resource will be created.
- *
- * @param string $path
- * @param string $content
- * @return void
- */
- protected function createResource( $path, $content = null )
- {
- file_put_contents( $this->root . $path, $content );
- chmod( $this->root . $path, $this->options->fileMode );
- // This automatically creates the property storage if missing
- $storage = $this->getPropertyStoragePath( $path );
- }
- /**
- * Sets the contents of a resource.
- *
- * This method replaces the content of the resource identified by $path
- * with the submitted $content.
- *
- * @param string $path
- * @param string $content
- * @return void
- */
- protected function setResourceContents( $path, $content )
- {
- file_put_contents( $this->root . $path, $content );
- chmod( $this->root . $path, $this->options->fileMode );
- }
- /**
- * Returns the contents of a resource.
- *
- * This method returns the content of the resource identified by $path as a
- * string.
- *
- * @param string $path
- * @return string
- */
- protected function getResourceContents( $path )
- {
- return file_get_contents( $this->root . $path );
- }
- /**
- * Returns the storage path for a property.
- *
- * Returns the file systems path where properties are stored for the
- * resource identified by $path. This depends on the name of the resource.
- *
- * @param string $path
- * @return string
- */
- protected function getPropertyStoragePath( $path )
- {
- // Get storage path for properties depending on the type of the
- // resource.
- $storagePath = realpath( $this->root . dirname( $path ) )
- . '/' . $this->options->propertyStoragePath . '/'
- . basename( $path ) . '.xml';
- // Create property storage if it does not exist yet
- if ( !is_dir( dirname( $storagePath ) ) )
- {
- mkdir( dirname( $storagePath ), $this->options->directoryMode );
- }
- // Append name of namespace to property storage path
- return $storagePath;
- }
- /**
- * Returns the property storage for a resource.
- *
- * Returns the {@link ezcWebdavPropertyStorage} instance containing the
- * properties for the resource identified by $path.
- *
- * @param string $path
- * @return ezcWebdavBasicPropertyStorage
- */
- protected function getPropertyStorage( $path )
- {
- $storagePath = $this->getPropertyStoragePath( $path );
- // If no properties has been stored yet, just return an empty property
- // storage.
- if ( !is_file( $storagePath ) )
- {
- return new ezcWebdavBasicPropertyStorage();
- }
- // Create handler structure to read properties
- $handler = new ezcWebdavPropertyHandler(
- $xml = new ezcWebdavXmlTool()
- );
- $storage = new ezcWebdavBasicPropertyStorage();
- // Read document
- try
- {
- $doc = $xml->createDom( file_get_contents( $storagePath ) );
- }
- catch ( ezcWebdavInvalidXmlException $e )
- {
- throw new ezcWebdavFileBackendBrokenStorageException(
- "Could not open XML as DOMDocument: '{$storage}'."
- );
- }
- // Get property node from document
- $properties = $doc->getElementsByTagname( 'properties' )->item( 0 )->childNodes;
- // Extract and return properties
- $handler->extractProperties(
- $properties,
- $storage
- );
- return $storage;
- }
- /**
- * Stores properties for a resource.
- *
- * Creates a new property storage file and stores the properties given for
- * the resource identified by $path. This depends on the affected resource
- * and the actual properties in the property storage.
- *
- * @param string $path
- * @param ezcWebdavBasicPropertyStorage $storage
- * @return void
- */
- protected function storeProperties( $path, ezcWebdavBasicPropertyStorage $storage )
- {
- $storagePath = $this->getPropertyStoragePath( $path );
- // Create handler structure to read properties
- $handler = new ezcWebdavPropertyHandler(
- $xml = new ezcWebdavXmlTool()
- );
- // Create new dom document with property storage for one namespace
- $doc = new DOMDocument( '1.0' );
- $properties = $doc->createElement( 'properties' );
- $doc->appendChild( $properties );
- // Store and store properties
- $handler->serializeProperties(
- $storage,
- $properties
- );
- return $doc->save( $storagePath );
- }
- /**
- * Manually sets a property on a resource.
- *
- * Sets the given $propertyBackup for the resource identified by $path.
- *
- * @param string $path
- * @param ezcWebdavProperty $property
- * @return bool
- */
- public function setProperty( $path, ezcWebdavProperty $property )
- {
- // Check if property is a self handled live property and return an
- // error in this case.
- if ( ( $property->namespace === 'DAV:' ) &&
- in_array( $property->name, $this->handledLiveProperties, true ) &&
- ( $property->name !== 'getcontenttype' ) &&
- ( $property->name !== 'lockdiscovery' ) )
- {
- return false;
- }
- // Get namespace property storage
- $storage = $this->getPropertyStorage( $path );
- // Attach property to store
- $storage->attach( $property );
- // Store document back
- $this->storeProperties( $path, $storage );
- return true;
- }
- /**
- * Manually removes a property from a resource.
- *
- * Removes the given $property form the resource identified by $path.
- *
- * @param string $path
- * @param ezcWebdavProperty $property
- * @return bool
- */
- public function removeProperty( $path, ezcWebdavProperty $property )
- {
- // Live properties may not be removed.
- if ( $property instanceof ezcWebdavLiveProperty )
- {
- return false;
- }
- // Get namespace property storage
- $storage = $this->getPropertyStorage( $path );
- // Attach property to store
- $storage->detach( $property->name, $property->namespace );
- // Store document back
- $this->storeProperties( $path, $storage );
- return true;
- }
- /**
- * Resets the property storage for a resource.
- *
- * Discardes the current {@link ezcWebdavPropertyStorage} of the resource
- * identified by $path and replaces it with the given $properties.
- *
- * @param string $path
- * @param ezcWebdavPropertyStorage $storage
- * @return bool
- */
- public function resetProperties( $path, ezcWebdavPropertyStorage $storage )
- {
- $this->storeProperties( $path, $storage );
- }
- /**
- * Returns a property of a resource.
- *
- * Returns the property with the given $propertyName, from the resource
- * identified by $path. You may optionally define a $namespace to receive
- * the property from.
- *
- * @param string $path
- * @param string $propertyName
- * @param string $namespace
- * @return ezcWebdavProperty
- */
- public function getProperty( $path, $propertyName, $namespace = 'DAV:' )
- {
- $storage = $this->getPropertyStorage( $path );
- // Handle dead propreties
- if ( $namespace !== 'DAV:' )
- {
- $properties = $storage->getAllProperties();
- return $properties[$namespace][$propertyName];
- }
- // Handle live properties
- switch ( $propertyName )
- {
- case 'getcontentlength':
- $property = new ezcWebdavGetContentLengthProperty();
- $property->length = $this->getContentLength( $path );
- return $property;
- case 'getlastmodified':
- $property = new ezcWebdavGetLastModifiedProperty();
- $property->date = new ezcWebdavDateTime( '@' . filemtime( $this->root . $path ) );
- return $property;
- case 'creationdate':
- $property = new ezcWebdavCreationDateProperty();
- $property->date = new ezcWebdavDateTime( '@' . filectime( $this->root . $path ) );
- return $property;
- case 'displayname':
- $property = new ezcWebdavDisplayNameProperty();
- $property->displayName = urldecode( basename( $path ) );
- return $property;
- case 'getcontenttype':
- $property = new ezcWebdavGetContentTypeProperty(
- $this->getMimeType( $path )
- );
- return $property;
- case 'getetag':
- $property = new ezcWebdavGetEtagProperty();
- $property->etag = $this->getETag( $path );
- return $property;
- case 'resourcetype':
- $property = new ezcWebdavResourceTypeProperty();
- $property->type = $this->isCollection( $path ) ?
- ezcWebdavResourceTypeProperty::TYPE_COLLECTION :
- ezcWebdavResourceTypeProperty::TYPE_RESOURCE;
- return $property;
- case 'supportedlock':
- $property = new ezcWebdavSupportedLockProperty();
- return $property;
- case 'lockdiscovery':
- $property = new ezcWebdavLockDiscoveryProperty();
- return $property;
- default:
- // Handle all other live properties like dead properties
- $properties = $storage->getAllProperties();
- return $properties[$namespace][$propertyName];
- }
- }
- /**
- * Returns the content length.
- *
- * Returns the content length (filesize) of the resource identified by
- * $path.
- *
- * @param string $path
- * @return string The content length.
- */
- private function getContentLength( $path )
- {
- $length = ezcWebdavGetContentLengthProperty::COLLECTION;
- if ( !$this->isCollection( $path ) )
- {
- $length = (string) filesize( $this->root . $path );
- }
- return $length;
- }
- /**
- * Returns the etag representing the current state of $path.
- *
- * Calculates and returns the ETag for the resource represented by $path.
- * The ETag is calculated from the $path itself and the following
- * properties, which are concatenated and md5 hashed:
- *
- * <ul>
- * <li>getcontentlength</li>
- * <li>getlastmodified</li>
- * </ul>
- *
- * This method can be overwritten in custom backend implementations to
- * access the information needed directly without using the way around
- * properties.
- *
- * Custom backend implementations are encouraged to use the same mechanism
- * (or this method itself) to determine and generate ETags.
- *
- * @param mixed $path
- * @return void
- */
- protected function getETag( $path )
- {
- clearstatcache();
- return md5(
- $path
- . $this->getContentLength( $path )
- . date( 'c', filemtime( $this->root . $path ) )
- );
- }
- /**
- * Returns all properties for a resource.
- *
- * Returns all properties for the resource identified by $path as a {@link
- * ezcWebdavBasicPropertyStorage}.
- *
- * @param string $path
- * @return ezcWebdavPropertyStorage
- */
- public function getAllProperties( $path )
- {
- $storage = $this->getPropertyStorage( $path );
-
- // Add all live properties to stored properties
- foreach ( $this->handledLiveProperties as $property )
- {
- $storage->attach(
- $this->getProperty( $path, $property )
- );
- }
- return $storage;
- }
- /**
- * Recursively copy a file or directory.
- *
- * Recursively copy a file or directory in $source to the given
- * $destination. If a $depth is given, the operation will stop as soon as
- * the given recursion depth is reached. A depth of -1 means no limit,
- * while a depth of 0 means, that only the current file or directory will
- * be copied, without any recursion.
- *
- * Returns an empty array if no errors occured, and an array with the files
- * which caused errors otherwise.
- *
- * @param string $source
- * @param string $destination
- * @param int $depth
- * @return array
- */
- public function copyRecursive( $source, $destination, $depth = ezcWebdavRequest::DEPTH_INFINITY )
- {
- // Skip non readable files in source directory, or non writeable
- // destination directories.
- if ( !is_readable( $source ) || !is_writeable( dirname( $destination ) ) )
- {
- return array( $source );
- }
- // Copy
- if ( is_dir( $source ) )
- {
- mkdir( $destination );
- // To ignore umask, umask() should not be changed on multithreaded
- // servers...
- chmod( $destination, $this->options->directoryMode );
- }
- elseif ( is_file( $source ) )
- {
- copy( $source, $destination );
- chmod( $destination, $this->options->fileMode );
- }
- if ( ( $depth === ezcWebdavRequest::DEPTH_ZERO ) ||
- ( !is_dir( $source ) ) )
- {
- // Do not recurse (any more)
- return array();
- }
- // Recurse
- $dh = opendir( $source );
- $errors = array();
- while ( $file = readdir( $dh ) )
- {
- if ( ( $file === '.' ) ||
- ( $file === '..' ) )
- {
- continue;
- }
- $errors = array_merge(
- $errors,
- $this->copyRecursive(
- $source . '/' . $file,
- $destination . '/' . $file,
- $depth - 1
- )
- );
- }
- closedir( $dh );
- return $errors;
- }
- /**
- * Copies resources recursively from one path to another.
- *
- * Copies the resourced identified by $fromPath recursively to $toPath with
- * the given $depth, where $depth is one of {@link
- * ezcWebdavRequest::DEPTH_ZERO}, {@link ezcWebdavRequest::DEPTH_ONE},
- * {@link ezcWebdavRequest::DEPTH_INFINITY}.
- *
- * Returns an array with {@link ezcWebdavErrorResponse}s for all subtrees,
- * where the copy operation failed. Errors for subsequent resources in a
- * subtree should be ommitted.
- *
- * If an empty array is return, the operation has been completed
- * successfully.
- *
- * @param string $fromPath
- * @param string $toPath
- * @param int $depth
- * @return array(ezcWebdavErrorResponse)
- */
- protected function performCopy( $fromPath, $toPath, $depth = ezcWebdavRequest::DEPTH_INFINITY )
- {
- $errors = $this->copyRecursive( $this->root . $fromPath, $this->root . $toPath, $depth );
- // Transform errors
- foreach ( $errors as $nr => $error )
- {
- $errors[$nr] = new ezcWebdavErrorResponse(
- ezcWebdavResponse::STATUS_423,
- str_replace( $this->root, '', $error )
- );
- }
- // Copy dead properties
- $storage = $this->getPropertyStorage( $fromPath );
- $this->storeProperties( $toPath, $storage );
- // Updateable live properties are updated automagically, because they
- // are regenerated on request on base of the file they affect. So there
- // is no reason to keep them "alive".
- return $errors;
- }
- /**
- * Returns if everything below a path can be deleted recursively.
- *
- * Checks files and directories recursively and returns if everything can
- * be deleted. Returns an empty array if no errors occured, and an array
- * with the files which caused errors otherwise.
- *
- * @param string $source
- * @return array
- */
- public function checkDeleteRecursive( $source )
- {
- // Skip non readable files in source directory, or non writeable
- // destination directories.
- if ( !is_writeable( dirname( $source ) ) )
- {
- return array(
- new ezcWebdavErrorResponse(
- ezcWebdavResponse::STATUS_403,
- substr( $source, strlen( $this->root ) )
- ),
- );
- }
- if ( is_file( $source ) )
- {
- // For plain files the above checks should be sufficant
- return array();
- }
- // Recurse
- $dh = opendir( $source );
- $errors = array();
- while ( $file = readdir( $dh ) )
- {
- if ( ( $file === '.' ) ||
- ( $file === '..' ) )
- {
- continue;
- }
- $errors = array_merge(
- $errors,
- $this->checkDeleteRecursive( $source . '/' . $file )
- );
- }
- closedir( $dh );
- // Return errors
- return $errors;
- }
- /**
- * Deletes everything below a path.
- *
- * Deletes the resource identified by $path recursively. Returns an
- * instance of {@link ezcWebdavErrorResponse} if the deletion failed, and
- * null on success.
- *
- * @param string $path
- * @return ezcWebdavErrorResponse
- */
- protected function performDelete( $path )
- {
- $errors = $this->checkDeleteRecursive( $this->root . $path );
- // If an error will occur return the proper status. We return
- // multistatus in any case.
- if ( count( $errors ) )
- {
- return new ezcWebdavMultistatusResponse(
- $errors
- );
- }
- // Just delete otherwise
- if ( is_file( $this->root . $path ) )
- {
- unlink( $this->root . $path );
- }
- else
- {
- ezcBaseFile::removeRecursive( $this->root . $path );
- }
- // Finally empty property storage for removed node
- $storagePath = $this->getPropertyStoragePath( $path );
- if ( is_file( $storagePath ) )
- {
- unlink( $storagePath );
- }
- return null;
- }
- /**
- * Returns if a resource exists.
- *
- * Returns if a the resource identified by $path exists.
- *
- * @param string $path
- * @return bool
- */
- protected function nodeExists( $path )
- {
- return ( is_file( $this->root . $path ) || is_dir( $this->root . $path ) );
- }
- /**
- * Returns if resource is a collection.
- *
- * Returns if the resource identified by $path is a collection resource
- * (true) or a non-collection one (false).
- *
- * @param string $path
- * @return bool
- */
- protected function isCollection( $path )
- {
- return is_dir( $this->root . $path );
- }
- /**
- * Returns members of collection.
- *
- * Returns an array with the members of the collection identified by $path.
- * The returned array can contain {@link ezcWebdavCollection}, and {@link
- * ezcWebdavResource} instances and might also be empty, if the collection
- * has no members.
- *
- * @param string $path
- * @return array(ezcWebdavResource|ezcWebdavCollection)
- */
- protected function getCollectionMembers( $path )
- {
- $contents = array();
- $errors = array();
- $files = glob( $this->root . $path . '/*' );
- if ( $this->options->hideDotFiles === false )
- {
- $files = array_merge(
- $files,
- glob( $this->root . $path . '/.*' )
- );
- }
- foreach ( $files as $file )
- {
- // Skip files used for somethig else...
- if ( ( strpos( $file, '/' . $this->options->lockFileName ) !== false ) ||
- ( strpos( $file, '/' . $this->options->propertyStoragePath ) !== false ) )
- {
- continue;
- }
- $file = $path . '/' . basename( $file );
- if ( is_dir( $this->root . $file ) )
- {
- // Add collection without any children
- $contents[] = new ezcWebdavCollection( $file );
- }
- else
- {
- // Add files without content
- $contents[] = new ezcWebdavResource( $file );
- }
- }
- return $contents;
- }
- /**
- * Serves GET requests.
- *
- * The method receives a {@link ezcWebdavGetRequest} object containing all
- * relevant information obout the clients request and will return an {@link
- * ezcWebdavErrorResponse} instance on error or an instance of {@link
- * ezcWebdavGetResourceResponse} or {@link ezcWebdavGetCollectionResponse}
- * on success, depending on the type of resource that is referenced by the
- * request.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavGetRequest $request
- * @return ezcWebdavResponse
- */
- public function get( ezcWebdavGetRequest $request )
- {
- $this->acquireLock( true );
- $return = parent::get( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves HEAD requests.
- *
- * The method receives a {@link ezcWebdavHeadRequest} object containing all
- * relevant information obout the clients request and will return an {@link
- * ezcWebdavErrorResponse} instance on error or an instance of {@link
- * ezcWebdavHeadResponse} on success.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavHeadRequest $request
- * @return ezcWebdavResponse
- */
- public function head( ezcWebdavHeadRequest $request )
- {
- $this->acquireLock( true );
- $return = parent::head( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves PROPFIND requests.
- *
- * The method receives a {@link ezcWebdavPropFindRequest} object containing
- * all relevant information obout the clients request and will either
- * return an instance of {@link ezcWebdavErrorResponse} to indicate an error
- * or a {@link ezcWebdavPropFindResponse} on success. If the referenced
- * resource is a collection or if some properties produced errors, an
- * instance of {@link ezcWebdavMultistatusResponse} may be returned.
- *
- * The {@link ezcWebdavPropFindRequest} object contains a definition to
- * find one or more properties of a given collection or non-collection
- * resource.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavPropFindRequest $request
- * @return ezcWebdavResponse
- */
- public function propFind( ezcWebdavPropFindRequest $request )
- {
- $this->acquireLock( true );
- $return = parent::propFind( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves PROPPATCH requests.
- *
- * The method receives a {@link ezcWebdavPropPatchRequest} object
- * containing all relevant information obout the clients request and will
- * return an instance of {@link ezcWebdavErrorResponse} on error or a
- * {@link ezcWebdavPropPatchResponse} response on success. If the
- * referenced resource is a collection or if only some properties produced
- * errors, an instance of {@link ezcWebdavMultistatusResponse} may be
- * returned.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavPropPatchRequest $request
- * @return ezcWebdavResponse
- */
- public function propPatch( ezcWebdavPropPatchRequest $request )
- {
- $this->acquireLock();
- $return = parent::propPatch( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves PUT requests.
- *
- * The method receives a {@link ezcWebdavPutRequest} objects containing all
- * relevant information obout the clients request and will return an
- * instance of {@link ezcWebdavErrorResponse} on error or {@link
- * ezcWebdavPutResponse} on success.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavPutRequest $request
- * @return ezcWebdavResponse
- */
- public function put( ezcWebdavPutRequest $request )
- {
- $this->acquireLock();
- $return = parent::put( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves DELETE requests.
- *
- * The method receives a {@link ezcWebdavDeleteRequest} objects containing
- * all relevant information obout the clients request and will return an
- * instance of {@link ezcWebdavErrorResponse} on error or {@link
- * ezcWebdavDeleteResponse} on success.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavDeleteRequest $request
- * @return ezcWebdavResponse
- */
- public function delete( ezcWebdavDeleteRequest $request )
- {
- $this->acquireLock();
- $return = parent::delete( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves COPY requests.
- *
- * The method receives a {@link ezcWebdavCopyRequest} objects containing
- * all relevant information obout the clients request and will return an
- * instance of {@link ezcWebdavErrorResponse} on error or {@link
- * ezcWebdavCopyResponse} on success. If only some operations failed, this
- * method may return an instance of {@link ezcWebdavMultistatusResponse}.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavCopyRequest $request
- * @return ezcWebdavResponse
- */
- public function copy( ezcWebdavCopyRequest $request )
- {
- $this->acquireLock();
- $return = parent::copy( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves MOVE requests.
- *
- * The method receives a {@link ezcWebdavMoveRequest} objects containing
- * all relevant information obout the clients request and will return an
- * instance of {@link ezcWebdavErrorResponse} on error or {@link
- * ezcWebdavMoveResponse} on success. If only some operations failed, this
- * method may return an instance of {@link ezcWebdavMultistatusResponse}.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavMoveRequest $request
- * @return ezcWebdavResponse
- */
- public function move( ezcWebdavMoveRequest $request )
- {
- $this->acquireLock();
- $return = parent::move( $request );
- $this->freeLock();
- return $return;
- }
- /**
- * Serves MKCOL (make collection) requests.
- *
- * The method receives a {@link ezcWebdavMakeCollectionRequest} objects
- * containing all relevant information obout the clients request and will
- * return an instance of {@link ezcWebdavErrorResponse} on error or {@link
- * ezcWebdavMakeCollectionResponse} on success.
- *
- * This method acquires the internal lock of the backend, dispatches to
- * {@link ezcWebdavSimpleBackend} to perform the operation and releases the
- * lock afterwards.
- *
- * @param ezcWebdavMakeCollectionRequest $request
- * @return ezcWebdavResponse
- */
- public function makeCollection( ezcWebdavMakeCollectionRequest $request )
- {
- $this->acquireLock();
- $return = parent::makeCollection( $request );
- $this->freeLock();
- return $return;
- }
- }
- ?>