blob: a372a2090590ab6d6feb99398baa3bbfa6c4f33a [file] [log] [blame]
<?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;
}
}
?>