/** * Extract the information from a LOCK DAV response and create the * corresponding Lock object. * * @param \DOMElement $response * @param bool $sessionOwning whether the current session is owning the lock (aka * we created it in this request) * @param string $path the owning node path, if we created this node * * @return \Jackalope\Lock\Lock */ protected function generateLockFromDavResponse($response, $sessionOwning = false, $path = null) { $lock = new Lock(); $lockDom = $this->getRequiredDomElementByTagNameNS($response, self::NS_DAV, 'activelock', "No lock received"); // Check this is not a transaction lock $type = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'locktype', 'No lock type received'); if (!$type->childNodes->length) { $tagName = $type->childNodes->item(0)->localName; if ($tagName !== 'write') { throw new RepositoryException("Invalid lock type '{$tagName}'"); } } // Extract the lock scope $scopeDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'lockscope', 'No lock scope in the received lock'); if ($this->getRequiredDomElementByTagNameNS($scopeDom, self::NS_DCR, 'exclusive-session-scoped')) { $lock->setIsSessionScoped(true); } elseif ($this->getRequiredDomElementByTagNameNS($scopeDom, self::NS_DAV, 'exclusive')) { $lock->setIsSessionScoped(false); } else { // Unknown XML found in the <D:lockscope> tag throw new RepositoryException('Invalid lock scope received: ' . $response->saveHTML($scopeDom)); } // Extract the depth $depthDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'depth', 'No depth in the received lock'); $lock->setIsDeep($depthDom->textContent === 'infinity'); // Extract the owner $ownerDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'owner', 'No owner in the received lock'); $lock->setLockOwner($ownerDom->textContent); // Extract the lock token $tokenDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'href', 'No lock token in the received lock'); $lock->setLockToken($tokenDom->textContent); // Extract the timeout $timeoutDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'timeout', 'No lock timeout in the received lock'); $lock->setExpireTime($this->parseTimeout($timeoutDom->nodeValue)); $lock->setIsLockOwningSession($sessionOwning); if (null !== $path) { $lock->setNodePath($path); } else { throw new NotImplementedException('get the lock owning node or provide Lock with info so it can get it when requested'); // TODO: get the lock owning node // Note that $n->getLock()->getNode() (where $n is a locked node) will only // return $n if $n is the lock holder. If $n is in the subgraph of the lock // holder, $h, then this call will return $h. } return $lock; }