You are here

class CMISRepositoryWrapper in CMIS API 7

Same name and namespace in other branches
  1. 6.4 cmis_common/lib/cmis_repository_wrapper.php \CMISRepositoryWrapper
  2. 6.3 cmis_common/lib/cmis_repository_wrapper.php \CMISRepositoryWrapper

Hierarchy

Expanded class hierarchy of CMISRepositoryWrapper

File

cmis_common/lib/cmis_repository_wrapper.php, line 3

View source
class CMISRepositoryWrapper {

  // Handles --
  //   Workspace -- but only endpoints with a single repo
  //   Entry -- but only for objects
  //   Feeds -- but only for non-hierarchical feeds
  // Does not handle --
  //   -- Hierarchical Feeds
  //   -- Types
  //   -- Others?
  // Only Handles Basic Auth
  // Very Little Error Checking
  // Does not work against pre CMIS 1.0 Repos
  var $url;
  var $username;
  var $password;
  var $authenticated;
  var $workspace;
  var $last_request;
  static $namespaces = array(
    "cmis" => "http://docs.oasis-open.org/ns/cmis/core/200908/",
    "cmisra" => "http://docs.oasis-open.org/ns/cmis/restatom/200908/",
    "atom" => "http://www.w3.org/2005/Atom",
    "app" => "http://www.w3.org/2007/app",
  );
  function __construct($url, $username = null, $password = null, $options = null) {
    $this
      ->connect($url, $username, $password, $options);
  }
  static function getOpUrl($url, $options = null) {
    if (is_array($options) && count($options) > 0) {
      $needs_question = strstr($url, "?") === false;
      return $url . ($needs_question ? "?" : "&") . http_build_query($options);
    }
    else {
      return $url;
    }
  }
  function connect($url, $username, $password, $options) {

    // TODO: Make this work with cookies
    $this->url = $url;
    $this->username = $username;
    $this->password = $password;
    $this->auth_options = $options;
    $this->authenticated = false;
    $retval = $this
      ->doGet($this->url);
    if ($retval->code == 200 || $retval->code == 201) {
      $this->authenticated = true;
      $this->workspace = CMISRepositoryWrapper::extractWorkspace($retval->body);
    }
  }
  function doGet($url) {
    return $this
      ->doRequest($url);
  }
  function doDelete($url) {
    return $this
      ->doRequest($url, "DELETE");
  }
  function doPost($url, $content, $contentType, $charset = null) {
    return $this
      ->doRequest($url, "POST", $content, $contentType);
  }
  function doPut($url, $content, $contentType, $charset = null) {
    return $this
      ->doRequest($url, "PUT", $content, $contentType);
  }
  function doRequest($url, $method = "GET", $content = null, $contentType = null, $charset = null) {

    // Process the HTTP request
    // 'til now only the GET request has been tested
    // Does not URL encode any inputs yet
    if (is_array($this->auth_options)) {
      $url = CMISRepositoryWrapper::getOpUrl($url, $this->auth_options);
    }
    $session = curl_init($url);
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    if ($this->username) {
      curl_setopt($session, CURLOPT_USERPWD, $this->username . ":" . $this->password);
    }
    curl_setopt($session, CURLOPT_CUSTOMREQUEST, $method);
    if ($contentType) {
      $headers = array();
      $headers["Content-Type"] = $contentType;
      curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
    }
    if ($method == "POST" && is_resource($content) && get_resource_type($content) == 'stream') {
      curl_setopt($session, CURLOPT_PUT, true);
      curl_setopt($session, CURLOPT_CUSTOMREQUEST, 'POST');
      curl_setopt($session, CURLOPT_HTTPHEADER, array(
        "Content-Type: " . $contentType,
      ));
      curl_setopt($session, CURLOPT_INFILE, $content);
    }
    else {
      if ($content) {
        curl_setopt($session, CURLOPT_POSTFIELDS, $content);
      }
      if ($method == "POST") {
        curl_setopt($session, CURLOPT_HTTPHEADER, array(
          "Content-Type: " . $contentType,
        ));
        curl_setopt($session, CURLOPT_POST, true);
      }
    }

    //TODO: Make this storage optional
    $retval = new stdClass();
    $retval->url = $url;
    $retval->method = $method;
    $retval->content_sent = $content;
    $retval->content_type_sent = $contentType;
    $retval->body = curl_exec($session);
    $retval->code = curl_getinfo($session, CURLINFO_HTTP_CODE);
    $retval->content_type = curl_getinfo($session, CURLINFO_CONTENT_TYPE);
    $retval->content_length = curl_getinfo($session, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
    curl_close($session);
    $this->last_request = $retval;
    return $retval;
  }
  function getLastRequest() {
    return $this->last_request;
  }
  function getLastRequestBody() {
    return $this->last_request->body;
  }
  function getLastRequestCode() {
    return $this->last_request->code;
  }
  function getLastRequestContentType() {
    return $this->last_request->content_type;
  }
  function getLastRequestContentLength() {
    return $this->last_request->content_length;
  }
  function getLastRequestURL() {
    return $this->last_request->url;
  }
  function getLastRequestMethod() {
    return $this->last_request->method;
  }
  function getLastRequestContentTypeSent() {
    return $this->last_request->content_type_sent;
  }
  function getLastRequestContentSent() {
    return $this->last_request->content_sent;
  }

  // Static Utility Functions
  static function processTemplate($template, $values = array()) {

    // Fill in the blanks --
    $retval = $template;
    if (is_array($values)) {
      foreach ($values as $name => $value) {
        $retval = str_replace("{" . $name . "}", $value, $retval);
      }
    }

    // Fill in any unpoupated variables with ""
    return preg_replace("/{[a-zA-Z0-9_]+}/", "", $retval);
  }
  static function processTemplateAsStream($template, $values = array()) {

    // Set up our return stream, just as a temporary stream.
    $returnstream = fopen('php://temp', 'r+');
    $matches = array();
    while (preg_match("/{([a-zA-Z0-9_]+)}/", $template, $matches, PREG_OFFSET_CAPTURE)) {
      $token_start = $matches[0][1];
      $token = $matches[1][0];

      // Write everything up to the token into the return stream.
      if ($token_start > 0) {
        fwrite($returnstream, substr($template, 0, $token_start));
      }

      // Remove the token from the template.
      $template = substr($template, $token_start + strlen($token) + 2);

      // If we have a matching token, write that to the return string.
      if (isset($values[$token])) {
        if (is_resource($values[$token]) && get_resource_type($values[$token]) == 'stream') {
          stream_copy_to_stream($values[$token], $returnstream);
        }
        else {
          fwrite($returnstream, $values[$token]);
        }
      }
    }

    // Append the rest of the template to the return stream.
    if (!empty($template)) {
      fwrite($returnstream, $template);
    }

    // Finally rewind the stream, ready for someone else to use it.
    rewind($returnstream);
    return $returnstream;
  }
  static function doXQuery($xmldata, $xquery) {
    $doc = new DOMDocument();
    $doc
      ->loadXML($xmldata);
    return CMISRepositoryWrapper::doXQueryFromNode($doc, $xquery);
  }
  static function doXQueryFromNode($xmlnode, $xquery) {

    // Perform an XQUERY on a NODE
    // Register the 4 CMIS namespaces
    $xpath = new DomXPath($xmlnode);
    foreach (CMISRepositoryWrapper::$namespaces as $nspre => $nsuri) {
      $xpath
        ->registerNamespace($nspre, $nsuri);
    }
    return $xpath
      ->query($xquery);
  }
  static function getLinksArray($xmlnode) {

    // Gets the links of an object or a workspace
    // Distinguishes between the two "down" links
    //  -- the children link is put into the associative array with the "down" index
    //  -- the descendants link is put into the associative array with the "down-tree" index
    //  These links are distinquished by the mime type attribute, but these are probably the only two links that share the same rel ..
    //    so this was done as a one off
    $links = array();
    $link_nodes = $xmlnode
      ->getElementsByTagName("link");
    foreach ($link_nodes as $ln) {
      if ($ln->attributes
        ->getNamedItem("rel")->nodeValue == "down" && $ln->attributes
        ->getNamedItem("type")->nodeValue == "application/cmistree+xml") {

        //Descendents and Childredn share same "rel" but different document type
        $links["down-tree"] = $ln->attributes
          ->getNamedItem("href")->nodeValue;
      }
      else {
        $links[$ln->attributes
          ->getNamedItem("rel")->nodeValue] = $ln->attributes
          ->getNamedItem("href")->nodeValue;
      }
    }
    return $links;
  }
  static function extractObject($xmldata) {
    $doc = new DOMDocument();
    $doc
      ->loadXML($xmldata);
    return CMISRepositoryWrapper::extractObjectFromNode($doc);
  }
  static function extractObjectFromNode($xmlnode) {

    // Extracts the contents of an Object and organizes them into:
    //  -- Links
    //  -- Properties
    //  -- the Object ID
    // RRM -- NEED TO ADD ALLOWABLEACTIONS
    $retval = new stdClass();
    $retval->links = CMISRepositoryWrapper::getLinksArray($xmlnode);
    $retval->renditions = array();
    $retval->properties = array();
    $prop_nodes = $xmlnode
      ->getElementsByTagName("object")
      ->item(0)
      ->getElementsByTagName("properties")
      ->item(0)->childNodes;
    foreach ($prop_nodes as $pn) {
      if ($pn->attributes) {

        //supressing errors since PHP sometimes sees DOM elements as "non-objects"
        @($retval->properties[$pn->attributes
          ->getNamedItem("propertyDefinitionId")->nodeValue] = $pn
          ->getElementsByTagName("value")
          ->item(0)->nodeValue);
      }
    }
    $renditions = $xmlnode
      ->getElementsByTagName("object")
      ->item(0)
      ->getElementsByTagName("rendition");
    $renditionArray = array();

    // Add renditions to CMIS object
    $i = 0;
    if ($renditions->length > 0) {
      foreach ($renditions as $rendition) {
        $rend_nodes = $rendition->childNodes;
        foreach ($rend_nodes as $rend) {
          if ($rend->localName != NULL) {
            $renditionArray[$i][$rend->localName] = $rend->nodeValue;
          }
        }
        $i++;
      }
    }
    $retval->renditions = $renditionArray;
    $properties = $xmlnode
      ->getElementsByTagName("object")
      ->item(0)
      ->getElementsByTagName("properties")
      ->item(0);

    // hack in Alfresco Aspect Properties
    if ($properties
      ->getElementsByTagName("aspects")
      ->item(0)) {
      $alf_prop_nodes = $properties
        ->getElementsByTagName("aspects")
        ->item(0)
        ->getElementsByTagName("properties")
        ->item(0)->childNodes;
      foreach ($alf_prop_nodes as $pn) {
        if ($pn->attributes) {
          $item = $pn->attributes
            ->getNamedItem("propertyDefinitionId");
          if ($item) {
            $first = $pn
              ->getElementsByTagName("value")
              ->item(0);
            if ($first) {
              $retval->properties[$item->nodeValue] = $first->nodeValue;
            }
          }
        }
      }
    }
    $retval->uuid = $xmlnode
      ->getElementsByTagName("id")
      ->item(0)->nodeValue;
    $retval->id = $retval->properties["cmis:objectId"];
    return $retval;
  }
  static function extractTypeDef($xmldata) {
    $doc = new DOMDocument();
    $doc
      ->loadXML($xmldata);
    return CMISRepositoryWrapper::extractTypeDefFromNode($doc);
  }
  static function extractTypeDefFromNode($xmlnode) {

    // Extracts the contents of an Object and organizes them into:
    //  -- Links
    //  -- Properties
    //  -- the Object ID
    // RRM -- NEED TO ADD ALLOWABLEACTIONS
    $retval = new stdClass();
    $retval->links = CMISRepositoryWrapper::getLinksArray($xmlnode);
    $retval->properties = array();
    $retval->attributes = array();
    $result = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "//cmisra:type/*");
    foreach ($result as $node) {
      if (substr($node->nodeName, 0, 13) == "cmis:property" && substr($node->nodeName, -10) == "Definition") {
        $id = $node
          ->getElementsByTagName("id")
          ->item(0)->nodeValue;
        $cardinality = $node
          ->getElementsByTagName("cardinality")
          ->item(0)->nodeValue;
        $propertyType = $node
          ->getElementsByTagName("propertyType")
          ->item(0)->nodeValue;

        // Stop Gap for now
        $retval->properties[$id] = array(
          "cmis:propertyType" => $propertyType,
          "cmis:cardinality" => $cardinality,
        );
      }
      else {
        $retval->attributes[$node->nodeName] = $node->nodeValue;
      }
      $retval->id = $retval->attributes["cmis:id"];
    }

    /*
    *



    		$prop_nodes = $xmlnode->getElementsByTagName("object")->item(0)->getElementsByTagName("properties")->item(0)->childNodes;
    		foreach ($prop_nodes as $pn) {
    			if ($pn->attributes) {
    				$retval->properties[$pn->attributes->getNamedItem("propertyDefinitionId")->nodeValue] = $pn->getElementsByTagName("value")->item(0)->nodeValue;
    			}
    		}
           $retval->uuid=$xmlnode->getElementsByTagName("id")->item(0)->nodeValue;
           $retval->id=$retval->properties["cmis:objectId"];
    */
    return $retval;
  }
  static function extractObjectFeed($xmldata) {

    //Assumes only one workspace for now
    $doc = new DOMDocument();
    $doc
      ->loadXML($xmldata);
    return CMISRepositoryWrapper::extractObjectFeedFromNode($doc);
  }
  static function extractObjectFeedFromNode($xmlnode) {

    // Process a feed and extract the objects
    //   Does not handle hierarchy
    //   Provides two arrays
    //   -- one sequential array (a list)
    //   -- one hash table indexed by objectID
    $retval = new stdClass();
    $retval->objectList = array();
    $retval->objectsById = array();
    $result = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "//atom:entry");
    foreach ($result as $node) {
      $obj = CMISRepositoryWrapper::extractObjectFromNode($node);
      $retval->objectsById[$obj->id] = $obj;
      $retval->objectList[] =& $retval->objectsById[$obj->id];
    }
    return $retval;
  }
  static function extractWorkspace($xmldata) {

    //Assumes only one workspace for now
    $doc = new DOMDocument();
    $doc
      ->loadXML($xmldata);
    return CMISRepositoryWrapper::extractWorkspaceFromNode($doc);
  }
  static function extractWorkspaceFromNode($xmlnode) {

    // Assumes only one workspace for now
    // Load up the workspace object with arrays of
    //  links
    //  URI Templates
    //  Collections
    //  Capabilities
    //  General Repository Information
    $retval = new stdClass();
    $retval->links = CMISRepositoryWrapper::getLinksArray($xmlnode);
    $retval->uritemplates = array();
    $retval->collections = array();
    $retval->capabilities = array();
    $retval->repositoryInfo = array();
    $result = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "//cmisra:uritemplate");
    foreach ($result as $node) {
      $retval->uritemplates[$node
        ->getElementsByTagName("type")
        ->item(0)->nodeValue] = $node
        ->getElementsByTagName("template")
        ->item(0)->nodeValue;
    }
    $result = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "//app:collection");
    foreach ($result as $node) {
      $retval->collections[$node
        ->getElementsByTagName("collectionType")
        ->item(0)->nodeValue] = $node->attributes
        ->getNamedItem("href")->nodeValue;
    }
    $result = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "//cmis:capabilities/*");
    foreach ($result as $node) {
      $retval->capabilities[$node->nodeName] = $node->nodeValue;
    }
    $result = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "//cmisra:repositoryInfo/*");
    foreach ($result as $node) {
      if ($node->nodeName != "cmis:capabilities") {
        $retval->repositoryInfo[$node->nodeName] = $node->nodeValue;
      }
    }
    return $retval;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CMISRepositoryWrapper::$authenticated property
CMISRepositoryWrapper::$last_request property
CMISRepositoryWrapper::$namespaces static property
CMISRepositoryWrapper::$password property
CMISRepositoryWrapper::$url property
CMISRepositoryWrapper::$username property
CMISRepositoryWrapper::$workspace property
CMISRepositoryWrapper::connect function
CMISRepositoryWrapper::doDelete function
CMISRepositoryWrapper::doGet function
CMISRepositoryWrapper::doPost function
CMISRepositoryWrapper::doPut function
CMISRepositoryWrapper::doRequest function 1
CMISRepositoryWrapper::doXQuery static function
CMISRepositoryWrapper::doXQueryFromNode static function
CMISRepositoryWrapper::extractObject static function
CMISRepositoryWrapper::extractObjectFeed static function
CMISRepositoryWrapper::extractObjectFeedFromNode static function
CMISRepositoryWrapper::extractObjectFromNode static function
CMISRepositoryWrapper::extractTypeDef static function
CMISRepositoryWrapper::extractTypeDefFromNode static function
CMISRepositoryWrapper::extractWorkspace static function
CMISRepositoryWrapper::extractWorkspaceFromNode static function
CMISRepositoryWrapper::getLastRequest function
CMISRepositoryWrapper::getLastRequestBody function
CMISRepositoryWrapper::getLastRequestCode function
CMISRepositoryWrapper::getLastRequestContentLength function
CMISRepositoryWrapper::getLastRequestContentSent function
CMISRepositoryWrapper::getLastRequestContentType function
CMISRepositoryWrapper::getLastRequestContentTypeSent function
CMISRepositoryWrapper::getLastRequestMethod function
CMISRepositoryWrapper::getLastRequestURL function
CMISRepositoryWrapper::getLinksArray static function
CMISRepositoryWrapper::getOpUrl static function
CMISRepositoryWrapper::processTemplate static function
CMISRepositoryWrapper::processTemplateAsStream static function
CMISRepositoryWrapper::__construct function 1