/**
  * Creates a lock-null resource.
  *
  * In case a LOCK request is issued on a resource, that does not exists, a
  * so-called lock-null resource is created. This resource must support some
  * of the WebDAV requests, but not all. In case an MKCOL or PUT request is
  * issued to such a resource, it is switched to be a real resource. In case
  * the lock is released, all null-lock resources in it are removed.
  * 
  * @param ezcWebdavLockRequest $request 
  * @return ezcWebdavResponse
  */
 protected function createLockNullResource(ezcWebdavLockRequest $request)
 {
     $backend = ezcWebdavServer::getInstance()->backend;
     // Check parent directory for locks and other violations
     $violation = $this->tools->checkViolations(new ezcWebdavLockCheckInfo(dirname($request->requestUri), ezcWebdavRequest::DEPTH_ZERO, $request->getHeader('If'), $request->getHeader('Authorization'), ezcWebdavAuthorizer::ACCESS_WRITE));
     if ($violation !== null) {
         return $this->createLockError($violation);
     }
     // Create lock null resource
     $putReq = new ezcWebdavPutRequest($request->requestUri, '');
     ezcWebdavLockTools::cloneRequestHeaders($request, $putReq, array('If'));
     $putReq->setHeader('Content-Length', '0');
     $putReq->validateHeaders();
     $putRes = $backend->put($putReq);
     if (!$putRes instanceof ezcWebdavPutResponse) {
         return $this->createLockError($putRes);
     }
     // Attention, recursion!
     $res = $this->acquireLock($request);
     if ($res->status !== ezcWebdavResponse::STATUS_200) {
         return $res;
     }
     $res->status = ezcWebdavResponse::STATUS_201;
     return $res;
 }
Beispiel #2
0
 /**
  * Performs unlocking.
  *
  * Performs a PROPFIND request with the $depth of the lock with $token on
  * the given $path (which must be the lock base). All affected resources
  * get the neccessary properties updated to reflect the change. Lock null
  * resources in the lock are removed.
  * 
  * @param ezcWebdavUnlockRequest $request
  * @param string $token 
  * @param int $depth 
  * @return ezcWebdavResponse
  */
 protected function performUnlock(ezcWebdavUnlockRequest $request, $token, $depth)
 {
     $path = $request->requestUri;
     $backend = ezcWebdavServer::getInstance()->backend;
     // Find alle resources affected by the unlock, including affected properties
     $propFindReq = new ezcWebdavPropFindRequest($path);
     $propFindReq->prop = new ezcWebdavBasicPropertyStorage();
     $propFindReq->prop->attach(new ezcWebdavLockDiscoveryProperty());
     ezcWebdavLockTools::cloneRequestHeaders($request, $propFindReq);
     $propFindReq->setHeader('Depth', $depth);
     $propFindReq->validateHeaders();
     $propFindMultistatusRes = $backend->propFind($propFindReq);
     // Remove lock information for the lock identified by $token from each affected resource
     foreach ($propFindMultistatusRes->responses as $propFindRes) {
         // Takes properties to be updated
         $changeProps = new ezcWebdavFlaggedPropertyStorage();
         foreach ($propFindRes->responses as $propStatRes) {
             if ($propStatRes->status === ezcWebdavResponse::STATUS_200) {
                 // Remove affected active lock part from lockdiscovery property
                 if ($propStatRes->storage->contains('lockdiscovery')) {
                     $lockDiscoveryProp = clone $propStatRes->storage->get('lockdiscovery');
                     foreach ($lockDiscoveryProp->activeLock as $id => $activeLock) {
                         if ($activeLock->token == $token) {
                             $lockDiscoveryProp->activeLock->offsetUnset($id);
                             $changeProps->attach($lockDiscoveryProp, ezcWebdavPropPatchRequest::SET);
                             break;
                         }
                     }
                 }
             }
         }
         // Perform the PROPPATCH
         if (count($changeProps) > 0) {
             $propPatchReq = new ezcWebdavPropPatchRequest($propFindRes->node->path);
             $propPatchReq->updates = $changeProps;
             ezcWebdavLockTools::cloneRequestHeaders($request, $propPatchReq);
             $propPatchReq->validateHeaders();
             $propPatchRes = $backend->propPatch($propPatchReq);
             if (!$propPatchRes instanceof ezcWebdavPropPatchResponse) {
                 throw new ezcWebdavInconsistencyException("Lock token {$token} could not be unlocked on resource {$propFindRes->node->path}.");
             }
         }
     }
     return new ezcWebdavUnlockResponse(ezcWebdavResponse::STATUS_204);
 }
Beispiel #3
0
 /**
  * Handles responses to the COPY request.
  * 
  * This method reacts on the response generated by the backend for a COPY
  * request. It takes care to release all locks that existed on the source
  * URI from the newly created destination and to add all necessary locks to
  * it, indicated by its parent.
  *
  * Returns null, if no errors occured, an {@link ezcWebdavErrorResponse}
  * otherwise.
  *
  * @param ezcWebdavResponse $response ezcWebdavCopyResponse
  * @return ezcWebdavResponse|null
  */
 public function generatedResponse(ezcWebdavResponse $response)
 {
     if (!$response instanceof ezcWebdavCopyResponse) {
         return null;
     }
     $backend = ezcWebdavServer::getInstance()->backend;
     // Backend successfully performed request, update with LOCK from parent
     $request = $this->request;
     $source = $request->requestUri;
     $dest = $request->getHeader('Destination');
     $destParent = dirname($dest);
     $paths = $this->sourcePaths;
     $lockDiscovery = isset($this->lockDiscoveryProp) ? clone $this->lockDiscoveryProp : new ezcWebdavLockDiscoveryProperty();
     // Update active locks to reflect new resources
     foreach ($lockDiscovery->activeLock as $id => $activeLock) {
         if ($activeLock->depth !== ezcWebdavRequest::DEPTH_INFINITY) {
             unset($lockDiscovery->activeLock[$id]);
             continue;
         }
         if ($activeLock->baseUri === null) {
             $activeLock->baseUri = $destParent;
             $activeLock->lastAccess = null;
         }
     }
     // Perform lock updates
     foreach ($paths as $path) {
         $newPath = str_replace($source, $dest, $path);
         $propPatchReq = new ezcWebdavPropPatchRequest($newPath);
         $propPatchReq->updates->attach($lockDiscovery, ezcWebdavPropPatchRequest::SET);
         ezcWebdavLockTools::cloneRequestHeaders($request, $propPatchReq);
         $propPatchReq->validateHeaders();
         $propPatchRes = $backend->propPatch($propPatchReq);
         if (!$propPatchRes instanceof ezcWebdavPropPatchResponse) {
             throw new ezcWebdavInconsistencyException("Could not set lock on resource {$newPath}.");
         }
     }
     return null;
 }
Beispiel #4
0
 /**
  * Updates the lock properties on the target.
  *
  * Performs the neccessary PROPPATCH requests to update the lock properties
  * on the target (parent is locked or was lock null before).
  */
 protected function updateLockProperties()
 {
     if (!$this->isParentProp) {
         // No need to update
         return null;
     }
     $lockDiscoveryProp = $this->lockDiscoveryProp !== null ? clone $this->lockDiscoveryProp : new ezcWebdavLockDiscoveryProperty();
     $destParent = dirname($this->request->requestUri);
     foreach ($lockDiscoveryProp->activeLock as $id => $activeLock) {
         if ($activeLock->depth !== ezcWebdavRequest::DEPTH_INFINITY) {
             unset($lockDiscoveryProp->activeLock[$id]);
             continue;
         }
         if ($activeLock->baseUri === null) {
             $activeLock->baseUri = $destParent;
             $activeLock->lastAccess = null;
         }
     }
     $propPatchReq = new ezcWebdavPropPatchRequest($this->request->requestUri);
     ezcWebdavLockTools::cloneRequestHeaders($this->request, $propPatchReq);
     $propPatchReq->validateHeaders();
     $propPatchReq->updates->attach($lockDiscoveryProp, ezcWebdavPropPatchRequest::SET);
     $propPatchRes = ezcWebdavServer::getInstance()->backend->propPatch($propPatchReq);
     if (!$propPatchRes instanceof ezcWebdavPropPatchResponse) {
         throw new ezcWebdavInconsistencyException('Could not patch lock properties on newly created resource/collection.');
     }
 }
 /**
  * Generates the requests to update the locks.
  *
  * This method generates a PROPPATCH request for each <lockinfo> property
  * in {@link $lockBaseProperties} and returns all of them in an array.
  * 
  * @return array(ezcWebdavPropPatchRequest)
  */
 protected function generateRequests()
 {
     $requests = array();
     foreach ($this->pathsToUpdate as $path => $dummy) {
         $propPatch = new ezcWebdavPropPatchRequest($path);
         $propPatch->updates->attach($this->lockDiscoveryProperties[$path], ezcWebdavPropPatchRequest::SET);
         ezcWebdavLockTools::cloneRequestHeaders($this->issuingRequest, $propPatch);
         $requests[] = $propPatch;
     }
     return $requests;
 }