Jackalope\Transport\Jackrabbit\Client::getRepositoryDescriptors PHP Method

getRepositoryDescriptors() public method

{@inheritDoc}
    public function getRepositoryDescriptors()
    {
        if (null == $this->descriptors) {
            $request = $this->getRequest(Request::REPORT, $this->server);
            $request->setBody($this->buildReportRequest('dcr:repositorydescriptors'));
            $dom = $request->executeDom();
            if ($dom->firstChild->localName != 'repositorydescriptors-report' || $dom->firstChild->namespaceURI != self::NS_DCR) {
                throw new RepositoryException('Error talking to the backend. ' . $dom->saveXML());
            }
            $descs = $dom->getElementsByTagNameNS(self::NS_DCR, 'descriptor');
            $this->descriptors = array();
            foreach ($descs as $desc) {
                $name = $desc->getElementsByTagNameNS(self::NS_DCR, 'descriptorkey')->item(0)->textContent;
                $values = array();
                $valuenodes = $desc->getElementsByTagNameNS(self::NS_DCR, 'descriptorvalue');
                foreach ($valuenodes as $value) {
                    $values[] = $value->textContent;
                }
                if ($valuenodes->length == 1) {
                    //there was one type and one value => this is a single value property
                    //TODO: is this the correct assumption? or should the backend tell us specifically?
                    $this->descriptors[$name] = $values[0];
                } else {
                    $this->descriptors[$name] = $values;
                }
            }
            // Supported by Jackrabbit, but not supported by this client
            $this->descriptors[RepositoryInterface::NODE_TYPE_MANAGEMENT_SAME_NAME_SIBLINGS_SUPPORTED] = false;
            $this->descriptors[RepositoryInterface::QUERY_CANCEL_SUPPORTED] = false;
            if (!isset($this->descriptors['jcr.repository.version'])) {
                throw new UnsupportedRepositoryOperationException("The backend at {$this->server} does not provide the jcr.repository.version descriptor");
            }
            if (!version_compare(self::VERSION, $this->descriptors['jcr.repository.version'], '<=')) {
                throw new UnsupportedRepositoryOperationException("The backend at {$this->server} is an unsupported version of jackrabbit: \"" . $this->descriptors['jcr.repository.version'] . '". Need at least "' . self::VERSION . '"');
            }
        }
        return $this->descriptors;
    }

Usage Example

 /**
  * Handles errors caused by singleRequest and multiRequest
  *
  * For transport level errors, tries to figure out what went wrong to
  * throw the most appropriate exception.
  *
  * @param curl   $curl
  * @param string $response the response body
  * @param int    $httpCode the http response code
  *
  * @throws NoSuchWorkspaceException if it was not possible to reach the server (resolve host or connect)
  * @throws ItemNotFoundException    if the object was not found
  * @throws RepositoryException      on any other error.
  * @throws PathNotFoundException    if the path was not found (server returned 404 without xml response)
  */
 protected function handleError(curl $curl, $response, $httpCode)
 {
     // first: check if the backend is too old for us
     if (!self::$versionChecked) {
         // avoid endless loops.
         self::$versionChecked = true;
         try {
             // getting the descriptors triggers a version check
             $this->client->getRepositoryDescriptors();
         } catch (\Exception $e) {
             if ($e instanceof \PHPCR\UnsupportedRepositoryOperationException) {
                 throw $e;
             }
             //otherwise ignore exception here as to not confuse what happened
         }
     }
     switch ($curl->errno()) {
         case CURLE_COULDNT_RESOLVE_HOST:
         case CURLE_COULDNT_CONNECT:
             $info = $curl->getinfo();
             throw new NoSuchWorkspaceException($curl->error() . ' "' . $info['url'] . '"');
         case CURLE_RECV_ERROR:
             throw new RepositoryException(sprintf('CURLE_RECV_ERROR (errno 56) encountered. This has been known to happen intermittently with ' . 'some versions of libcurl (see https://github.com/jackalope/jackalope-jackrabbit/issues/89). ' . 'You can use the "jackalope.jackrabbit_force_http_version_10" option to force HTTP 1.0 as a workaround'));
     }
     // use XML error response if it's there
     if (substr($response, 0, 2) === '<?') {
         $dom = new DOMDocument();
         $dom->loadXML($response);
         $err = $dom->getElementsByTagNameNS(Client::NS_DCR, 'exception');
         if ($err->length > 0) {
             $err = $err->item(0);
             $errClass = $err->getElementsByTagNameNS(Client::NS_DCR, 'class')->item(0)->textContent;
             $errMsg = $err->getElementsByTagNameNS(Client::NS_DCR, 'message')->item(0)->textContent;
             $exceptionMsg = 'HTTP ' . $httpCode . ': ' . $errMsg;
             switch ($errClass) {
                 case 'javax.jcr.NoSuchWorkspaceException':
                     throw new NoSuchWorkspaceException($exceptionMsg);
                 case 'javax.jcr.nodetype.NoSuchNodeTypeException':
                     throw new NoSuchNodeTypeException($exceptionMsg);
                 case 'javax.jcr.ItemNotFoundException':
                     throw new ItemNotFoundException($exceptionMsg);
                 case 'javax.jcr.nodetype.ConstraintViolationException':
                     throw new ConstraintViolationException($exceptionMsg);
                 case 'javax.jcr.ReferentialIntegrityException':
                     throw new ReferentialIntegrityException($exceptionMsg);
                     //TODO: Two more errors needed for Transactions. How does the corresponding Jackrabbit response look like?
                     // javax.transaction.RollbackException => \PHPCR\Transaction\RollbackException
                     // java.lang.SecurityException => \PHPCR\AccessDeniedException
                     //TODO: map more errors here?
                 //TODO: Two more errors needed for Transactions. How does the corresponding Jackrabbit response look like?
                 // javax.transaction.RollbackException => \PHPCR\Transaction\RollbackException
                 // java.lang.SecurityException => \PHPCR\AccessDeniedException
                 //TODO: map more errors here?
                 default:
                     // try to generically "guess" the right exception class name
                     $class = substr($errClass, strlen('javax.jcr.'));
                     $class = explode('.', $class);
                     array_walk($class, function (&$ns) {
                         $ns = ucfirst(str_replace('nodetype', 'NodeType', $ns));
                     });
                     $class = '\\PHPCR\\' . implode('\\', $class);
                     if (class_exists($class)) {
                         throw new $class($exceptionMsg);
                     }
                     throw new RepositoryException($exceptionMsg . " ({$errClass})");
             }
         }
     }
     if (401 == $httpCode) {
         throw new LoginException("HTTP 401 Unauthorized\n" . $this->getShortErrorString());
     }
     if (404 == $httpCode) {
         throw new PathNotFoundException("HTTP 404 Path Not Found: {$this->method} \n" . $this->getShortErrorString());
     }
     if (405 == $httpCode) {
         throw new HTTPErrorException("HTTP 405 Method Not Allowed: {$this->method} \n" . $this->getShortErrorString(), 405);
     }
     if (412 == $httpCode) {
         throw new LockException("Unable to lock the non-lockable node '" . reset($this->uri) . "\n" . $this->getShortErrorString());
     }
     if ($httpCode >= 500) {
         $msg = "HTTP {$httpCode} Error from backend on: {$this->method} \n" . $this->getLongErrorString($curl, $response);
         try {
             $workspaceUri = array($this->client->getWorkSpaceUri());
             if (!$this->errorHandlingMode && ($workspaceUri !== $this->uri || self::GET !== $this->method)) {
                 $this->errorHandlingMode = true;
                 $this->setUri($workspaceUri);
                 $this->setMethod(self::GET);
                 $this->executeDom();
             }
         } catch (PathNotFoundException $e) {
             $msg = "Error likely caused by incorrect server URL configuration '" . reset($this->uri) . "' resulted in:\n{$msg}";
         }
         $this->errorHandlingMode = false;
         throw new RepositoryException($msg);
     }
     $curlError = $curl->error();
     $msg = "Unexpected error: \nCURL Error: {$curlError} \nResponse (HTTP {$httpCode}): {$this->method} \n" . $this->getLongErrorString($curl, $response);
     throw new RepositoryException($msg);
 }