registerXPathNamespace('cmis', $namespaces['cmis']); $cmis_object = $xml->workspace->children($namespaces['cmis']); $repository = $cmis_object->repositoryInfo; // Determine repository CMIS version foreach (array('cmisVersionSupported', 'cmisVersionsSupported') as $property_name) { if (isset($repository->$property_name)) { $cmis_version = (string)$repository->$property_name; return $cmis_version; } } } throw new CMISException(t('Unable to auto-discovery supported CMIS version.')); } return $cmis_version; } /** * Returns a list with known xml namespaces * * @return array */ function cmis_alfresco_utils_get_namespaces($cmis_version = NULL) { $namespaces = array( 'D' => 'http://www.w3.org/2005/Atom', 'alf' => 'http://www.alfresco.org', 'app' => 'http://www.w3.org/2007/app', 'opensearch' => 'http://a9.com/-/spec/opensearch/1.1/', 'relevance' => 'http://a9.com/-/opensearch/extensions/relevance/1.0/' ); $cmis_version = empty($cmis_version)?_cmis_alfresco_utils_cmis_version_autodiscovery():$cmis_version; if ($cmis_version >= '0.6') { $namespaces['cmis'] = 'http://docs.oasis-open.org/ns/cmis/core/200901'; } else { $namespaces['cmis'] = 'http://www.cmis.org/2008/05'; } return $namespaces; } /** * Shortcut for cmis_alfresco_utils_get_namespaces * * @param $ns * @return string */ function cmis_alfresco_utils_ns($ns) { $namespaces = cmis_alfresco_utils_get_namespaces(); return $namespaces[$ns]; } /** * Returns a list of known property types * */ function _cmis_alfresco_utils_known_property_types() { return array('Id', 'Boolean', 'String', 'Integer', 'DateTime'); } /** * Process CMIS XML. * * @param $xml CMIS response XML. * @param $xpath xpath expression. */ function cmis_alfresco_utils_get_CMIS_xml($xml, $xpath = NULL) { try { $cmis_service = new SimpleXMLElement($xml); } catch (Exception $e) { cmis_error_handler('cmis_alfresco_utils_get_CMIS_xml', $e); throw new CMISException(t('Unable to process xml.')); } foreach (cmis_alfresco_utils_get_namespaces() as $ns => $namespace) { $cmis_service->registerXPathNamespace($ns, $namespace); } if ($xpath) { return $cmis_service->xpath($xpath); } return $cmis_service; } /** * Resolves objectId from various formats. * * Known formats: * - url: http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore/Company%20Home * - path: Company Home/path to file * - noderef: workspace://SpacesStore/91298612309871e * - id: 91298612309871esdf * * @todo Review objectId handling. * * @param $objectId * @return array */ function cmis_alfresco_objectId($objectId) { // probably is already resolved ("instanceof" would have been more appropriate) if (is_array($objectId)) { return $objectId; } // unable to resolve node if (!is_string($objectId)) { return FALSE; } $parts = parse_url($objectId); if (substr($parts['scheme'], 0, 4) == 'http') { // @todo lookup id by path $parts['url'] = $objectId; return $parts; } if (in_array($parts['scheme'], array ('workspace', 'archive', 'user', 'system', 'avm'))) { $parts['noderef'] = $objectId; $parts['noderef_url'] = $parts['scheme'] .'/'. $parts['host'] . $parts['path']; return $parts; } if ($parts['scheme'] == 'urn') { // Assuming that comes from workspace://SpacesStore/ // @todo Review this assumption $tmp_parts = parse_url($parts['path']); $parts['path'] = $tmp_parts['path']; $parts['noderef'] = 'workspace://SpacesStore/'. $parts['path']; $parts['scheme'] = 'workspace'; $parts['host'] = 'SpacesStore'; $parts['noderef_url'] = 'workspace/SpacesStore/'. $parts['path']; return $parts; } if ($parts['path'][0] == '/' && empty ($parts['scheme'])) { // Assuming that id looks like "/Company Home/path/to/object" if (substr($parts['path'], -1) == '/') { $parts['path'] = substr_replace($parts['path'], '', -1); } $response = cmis_alfresco_invoke_service('/api/path/workspace/SpacesStore'. $parts['path']); $object_info = cmis_alfresco_utils_get_CMIS_xml($response, '//D:entry'); if (false != $object_info) { return cmis_alfresco_objectId((string) $object_info[0]->id); } else { return FALSE; } } // unknown format watchdog('cmis_alfresco_objectId', 'Unable to resolve objectId: '. $objectId); return FALSE; } /** * Utility function for returning CMIS objects from cmis response(ie. getChildren, query, getDescendants) * * @param $entries * @return array */ function _cmis_alfresco_getEntries($entries) { $result = array(); foreach ($entries as $entry) { $cmis_object = _cmis_alfresco_utils_entry($entry); $cmis_object->properties = array(); $cmis_element = $entry->children(cmis_alfresco_utils_ns('cmis')); foreach (_cmis_alfresco_utils_known_property_types() as $type) { $property_tag = 'property'. $type; foreach ($cmis_element->object->properties->$property_tag as $property) { $attrs = $property->attributes(cmis_alfresco_utils_ns('cmis')); $cmis_object->properties[(string) $attrs->name] = _cmis_alfresco_utils_cast($property->value, $type); } } $cmis_object->type = $cmis_object->properties['BaseType']; if ($cmis_object->type == 'document') { $cmis_object->size = $cmis_object->properties['ContentStreamLength']; $cmis_object->contentMimeType = $cmis_object->properties['ContentStreamMimeType']; $cmis_object->versionSeriesCheckedOutBy = $cmis_object->properties['VersionSeriesCheckedOutBy']; } $result[] = $cmis_object; } return $result; } /** * Utility function for returning a common entry object from a feed entry * * @param $xml_element * @return stdClass */ function _cmis_alfresco_utils_entry($xml_element) { $entry = new stdClass(); $tmp_objectId = cmis_alfresco_objectId((string) $xml_element->id); $entry->id = $tmp_objectId['noderef']; $entry->title = (string) $xml_element->title; $entry->summary = (string) $xml_element->summary; $entry->updated = date_create($xml_element->updated); $entry->author = (string) $xml_element->author->name; return $entry; } /** * Utility function form casting cmis properties * * @param $value * @param $type * @return mixed */ function _cmis_alfresco_utils_cast($value, $type) { $return = NULL; switch ($type) { case 'Integer': $return = (int) $value; break; case 'Boolean': $return = (bool) $value; break; case 'String': case 'Id': $return = (string) $value; break; case 'DateTime': $return = date_create((string) $value); break; default: $return = $value; } return $return; } /** * Utility function for encoding cmis properties * * @param $propertyCollection * @return string */ function _cmis_alfresco_utils_properties_to_xml($propertyCollection = array()) { $properties_xml = ''; foreach ($propertyCollection as $key => $value) { $property_type = gettype($value); switch ($property_type) { case 'integer': case 'boolean': case 'string': $properties_xml .= ''; $properties_xml .= ''. $value .''; $properties_xml .= ''; break; default: watchdog('_cmis_alfresco_utils_properties_to_xml', 'Unable to map property "@property" of type "@property_type" for destination object "@objectId"', array('@property' => $key, '@property_type' => $property_type, '@objectId' => $objectId), WATCHDOG_ERROR); drupal_set_message(t('Unable to map property "@property" of type "@property_type" for destination object "@objectId"', array('@property' => $key, '@property_type' => $property_type, '@objectId' => $objectId)), 'error'); } } return $properties_xml; }