From: dongsheng Date: Fri, 19 Sep 2008 04:49:38 +0000 (+0000) Subject: MDL-16384, first draft of alfresco plugin X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=17e31bb097ee393b344c9876504f575a9fb3f429;p=moodle.git MDL-16384, first draft of alfresco plugin TODO: 1) Create a SOAP wrapper 2) Implement searching --- diff --git a/lang/en_utf8/repository_alfresco.php b/lang/en_utf8/repository_alfresco.php new file mode 100644 index 0000000000..710abc6c4c --- /dev/null +++ b/lang/en_utf8/repository_alfresco.php @@ -0,0 +1,8 @@ +_from = $from; + $this->_to = $to; + $this->_type = $type; + } + + public function getFrom() + { + return $this->_from; + } + + public function getTo() + { + return $this->_to; + } + + public function getType() + { + return $this->_type; + } +} + +?> diff --git a/lib/alfresco/Service/BaseObject.php b/lib/alfresco/Service/BaseObject.php new file mode 100755 index 0000000000..355021573c --- /dev/null +++ b/lib/alfresco/Service/BaseObject.php @@ -0,0 +1,147 @@ +$methodName(); + } + } + + public function __set($name, $value) + { + $methodName = $name; + $methodName[0] = strtoupper($methodName[0]); + $methodName = 'set' . $methodName; + + if (method_exists($this, $methodName) == true) + { + return $this->$methodName($value); + } + } + + protected function resultSetToNodes($session, $store, $resultSet) + { + $return = array(); + if (isset($resultSet->rows) == true) + { + if (is_array($resultSet->rows) == true) + { + foreach($resultSet->rows as $row) + { + $id = $row->node->id; + $return[] = $session->getNode($store, $id); + } + } + else + { + $id = $resultSet->rows->node->id; + $return[] = $session->getNode($store, $id); + } + } + + return $return; + } + + protected function resultSetToMap($resultSet) + { + $return = array(); + if (isset($resultSet->rows) == true) + { + if (is_array($resultSet->rows) == true) + { + foreach($resultSet->rows as $row) + { + $return[] = $this->columnsToMap($row->columns); + } + } + else + { + $return[] = $this->columnsToMap($resultSet->rows->columns); + } + + } + + return $return; + } + + private function columnsToMap($columns) + { + $return = array(); + + foreach ($columns as $column) + { + $return[$column->name] = $column->value; + } + + return $return; + } + + protected function remove_array_value($value, &$array) + { + if ($array != null) + { + if (in_array($value, $array) == true) + { + foreach ($array as $index=>$value2) + { + if ($value == $value2) + { + unset($array[$index]); + } + } + } + } + } + + protected function isContentData($value) + { + $index = strpos($value, "contentUrl="); + if ($index === false) + { + return false; + } + else + { + if ($index == 0) + { + return true; + } + else + { + return false; + } + } + } +} +?> \ No newline at end of file diff --git a/lib/alfresco/Service/ChildAssociation.php b/lib/alfresco/Service/ChildAssociation.php new file mode 100755 index 0000000000..d856ddd464 --- /dev/null +++ b/lib/alfresco/Service/ChildAssociation.php @@ -0,0 +1,76 @@ +_parent = $parent; + $this->_child = $child; + $this->_type = $type; + $this->_name = $name; + $this->_isPrimary = $isPrimary; + $this->_nthSibling = $nthSibling; + } + + public function getParent() + { + return $this->_parent; + } + + public function getChild() + { + return $this->_child; + } + + public function getType() + { + return $this->_type; + } + + public function getName() + { + return $this->_name; + } + + public function getIsPrimary() + { + return $this->_isPrimary; + } + + public function getNthSibling() + { + return $this->_nthSibling; + } +} +?> diff --git a/lib/alfresco/Service/ContentData.php b/lib/alfresco/Service/ContentData.php new file mode 100755 index 0000000000..0f49351e9c --- /dev/null +++ b/lib/alfresco/Service/ContentData.php @@ -0,0 +1,290 @@ +_node = $node; + $this->_property = $property; + $this->_mimetype = $mimetype; + $this->_encoding = $encoding; + if ($size != -1) + { + $this->size = $size; + } + $this->_isPopulated = false; + } + + public function setPropertyDetails($node, $property) + { + $this->_node = $node; + $this->_property = $property; + } + + public function __toString() + { + $this->populateContentData(); + } + + public function getNode() + { + return $this->_node; + } + + public function getProperty() + { + return $this->_property; + } + + public function getIsDirty() + { + return $this->_isDirty; + } + + public function getMimetype() + { + $this->populateContentData(); + return $this->_mimetype; + } + + public function setMimetype($mimetype) + { + $this->populateContentData(); + $this->_mimetype = $mimetype; + } + + public function getSize() + { + $this->populateContentData(); + return $this->_size; + } + + public function getEncoding() + { + $this->populateContentData(); + return $this->_encoding; + } + + public function setEncoding($encoding) + { + $this->populateContentData(); + $this->_encoding = $encoding; + } + + public function getUrl() + { + // TODO what should be returned if the content has been updated?? + + $this->populateContentData(); + $result = null; + if ($this->_url != null) + { + $result = $this->_url."?ticket=".$this->_node->session->ticket; + } + return $result; + } + + public function getGuestUrl() + { + // TODO what should be returned if the content has been updated?? + + $this->populateContentData(); + $result = null; + if ($this->_url != null) + { + $result = $this->_url."?guest=true"; + } + return $result; + } + + public function getContent() + { + $this->populateContentData(); + + $result = null; + if ($this->_isDirty == true) + { + if ($this->_newFileContent != null) + { + $handle = fopen($this->_newFileContent, "rb"); + $result = stream_get_contents($handle); + fclose($handle); + } + else if ($this->_newContent != null) + { + $result = $this->_newContent; + } + } + else + { + if ($this->getUrl() != null) + { + $handle = fopen($this->getUrl(), "rb"); + $result = stream_get_contents($handle); + fclose($handle); + } + } + return $result; + } + + public function setContent($content) + { + $this->populateContentData(); + $this->_isDirty = true; + $this->_newContent = $content; + } + + public function writeContentFromFile($fileName) + { + $this->populateContentData(); + $this->_isDirty = true; + $this->_newFileContent = $fileName; + } + + public function readContentToFile($fileName) + { + $handle = fopen($fileName, "wb"); + fwrite($handle, $this->getContent()); + fclose($handle); + } + + public function onBeforeSave(&$statements, $where) + { + if ($this->_isDirty == true) + { + // Check mimetype has been set + if ($this->_mimetype == null) + { + throw new Exception("A mime type for the content property ".$this->_property." on node ".$this->_node->__toString()." must be set"); + } + + // If a file has been specified then read content from there + //$content = null; + if ($this->_newFileContent != null) + { + // Upload the content to the repository + $contentData = upload_file($this->node->session, $this->_newFileContent, $this->_mimetype, $this->_encoding); + + // Set the content property value + $this->addStatement( + $statements, + "update", + array("property" => array( + "name" => $this->property, + "isMultiValue" => false, + "value" => $contentData)) + $where); + } + else + { + // Add the writeContent statement + $this->addStatement( + $statements, + "writeContent", + array( + "property" => $this->_property, + "content" => $this->_newContent, + "format" => array( + "mimetype" => $this->_mimetype, + "encoding" => $this->_encoding)) + + $where); + } + } + } + + public function onAfterSave() + { + $this->_isDirty = false; + $this->_isPopulated = false; + $this->_mimetype = null; + $this->__size = null; + $this->__encoding = null; + $this->__url = null; + $this->__newContent = null; + } + + private function populateContentData() + { + //echo "isPopulated:".$this->_isPopulated."; node:".$this->_node."; property:".$this->_property."
"; + if ($this->_isPopulated == false && $this->_node != null && $this->_property != null && $this->_node->isNewNode == false) + { + $result = $this->_node->session->contentService->read( array( + "items" => array( + "nodes" => array( + "store" => $this->_node->store->__toArray(), + "uuid" => $this->_node->id)), + "property" => $this->_property) ); + if (isset($result->content) == true) + { + if (isset($result->content->length) == true) + { + $this->_size = $result->content->length; + } + if (isset($result->content->format->mimetype) == true) + { + $this->_mimetype = $result->content->format->mimetype; + } + if (isset($result->content->format->encoding) == true) + { + $this->_encoding = $result->content->format->encoding; + } + if (isset($result->content->url) == true) + { + $this->_url = $result->content->url; + } + } + + $this->_isPopulated = true; + } + } + + private function addStatement(&$statements, $statement, $body) + { + $result = array(); + if (array_key_exists($statement, $statements) == true) + { + $result = $statements[$statement]; + } + $result[] = $body; + $statements[$statement] = $result; + } +} +?> diff --git a/lib/alfresco/Service/Functions.php b/lib/alfresco/Service/Functions.php new file mode 100755 index 0000000000..84a014feee --- /dev/null +++ b/lib/alfresco/Service/Functions.php @@ -0,0 +1,114 @@ +repository->host; + $port = $session->repository->port; + + // Get the IP address for the target host + $address = gethostbyname($host); + + // Create a TCP/IP socket + $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + if ($socket === false) + { + throw new Exception ("socket_create() failed: reason: " . socket_strerror(socket_last_error())); + } + + // Connect the socket to the repository + $result = socket_connect($socket, $address, $port); + if ($result === false) + { + throw new Exception("socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket))); + } + + // Write the request header onto the socket + $url = "/alfresco/upload/".urlencode($fileName)."?ticket=".$session->ticket; + if ($mimetype != null) + { + // Add mimetype if specified + $url .= "&mimetype=".$mimetype; + } + if ($encoding != null) + { + // Add encoding if specified + $url .= "&encoding=".$encoding; + } + $in = "PUT ".$url." HTTP/1.1\r\n". + "Content-Length: ".$fileSize."\r\n". + "Host: ".$address.":".$port."\r\n". + "Connection: Keep-Alive\r\n". + "\r\n"; + socket_write($socket, $in, strlen($in)); + + // Write the content found in the file onto the socket + $handle = fopen($filePath, "r"); + while (feof($handle) == false) + { + $content = fread($handle, 1024); + socket_write($socket, $content, strlen($content)); + } + fclose($handle); + + // Read the response + $recv = socket_read ($socket, 2048, PHP_BINARY_READ); + $index = strpos($recv, "contentUrl"); + if ($index !== false) + { + $result = substr($recv, $index); + } + + // Close the socket + socket_close($socket); + + return $result; + } +?> diff --git a/lib/alfresco/Service/Logger/Logger.php b/lib/alfresco/Service/Logger/Logger.php new file mode 100755 index 0000000000..f16bac1a8c --- /dev/null +++ b/lib/alfresco/Service/Logger/Logger.php @@ -0,0 +1,90 @@ +componentName = $componentName; + } + + public function isDebugEnabled() + { + return $this->isEnabled(DEBUG); + } + + public function debug($message) + { + $this->write(DEBUG, $message); + } + + public function isWarningEnabled() + { + return $this->isEnabled(WARNING); + } + + public function warning($message) + { + $this->write(WARNING, $message); + } + + public function isInformationEnabled() + { + return $this->isEnabled(INFORMATION); + } + + public function information($message) + { + $this->write(INFORMATION, $message); + } + + private function isEnabled($logLevel) + { + global $componentLogLevels, $defaultLogLevel; + + $logLevels = $defaultLogLevel; + if ($this->componentName != null && isset($componentLogLevels[$this->componentName]) == true) + { + $logLevels = $componentLogLevels[$this->componentName]; + } + + return in_array($logLevel, $logLevels); + } + + private function write($logLevel, $message) + { + global $logFile; + + $handle = fopen($logFile, "a"); + fwrite($handle, $logLevel." ".date("G:i:s d/m/Y")." - ".$message."\r\n"); + fclose($handle); + } + } +?> diff --git a/lib/alfresco/Service/Logger/LoggerConfig.php b/lib/alfresco/Service/Logger/LoggerConfig.php new file mode 100755 index 0000000000..566ea5b18a --- /dev/null +++ b/lib/alfresco/Service/Logger/LoggerConfig.php @@ -0,0 +1,44 @@ + $debugLevel + ); + + +?> diff --git a/lib/alfresco/Service/NamespaceMap.php b/lib/alfresco/Service/NamespaceMap.php new file mode 100755 index 0000000000..9ca8a583d6 --- /dev/null +++ b/lib/alfresco/Service/NamespaceMap.php @@ -0,0 +1,121 @@ + "http://www.alfresco.org/model/dictionary/1.0", + "sys" => "http://www.alfresco.org/model/system/1.0", + "cm" => "http://www.alfresco.org/model/content/1.0", + "app" => "http://www.alfresco.org/model/application/1.0", + "bpm" => "http://www.alfresco.org/model/bpm/1.0", + "wf" => "http://www.alfresco.org/model/workflow/1.0", + "fm" => "http://www.alfresco.org/model/forum/1.0", + "view" => "http://www.alfresco.org/view/repository/1.0", + "security" => "http://www.alfresco.org/model/security/1.0", + "wcm" => "http://www.alfresco.org/model/wcmmodel/1.0", + "wca" => "http://www.alfresco.org/model/wcmappmodel/1.0"); + + public function isShortName($shortName) + { + return ($shortName != $this->getFullName($shortName)); + } + + public function getFullName($shortName) + { + $result = $shortName; + + $index = strpos($shortName, NamespaceMap::DELIMITER); + if ($index !== false) + { + $prefix = substr($shortName, 0, $index); + + if (isset($this->namespaceMap[$prefix]) == true) + { + $url = $this->namespaceMap[$prefix]; + $name = substr($shortName, $index+1); + $name = str_replace("_", "-", $name); + if ($name != null && strlen($name) != 0) + { + $result = "{".$url."}".$name; + } + } + } + + return $result; + } + + public function getFullNames($fullNames) + { + $result = array(); + + foreach ($fullNames as $fullName) + { + $result[] = $this->getFullName($fullName); + } + return $result; + } + + public function getShortName($fullName) + { + $result = $fullName; + + $index = strpos($fullName, "}"); + if ($index !== false) + { + $url = substr($fullName, 1, $index-1); + $prefix = $this->lookupPrefix($url); + if ($prefix != null) + { + $name = substr($fullName, $index+1); + if ($name != null && strlen($name) != 0) + { + $name = str_replace("-", "_", $name); + $result = $prefix.NamespaceMap::DELIMITER.$name; + } + } + } + + return $result; + } + + private function lookupPrefix($value) + { + $result = null; + foreach($this->namespaceMap as $prefix => $url) + { + if ($url == $value) + { + $result = $prefix; + } + } + return $result; + } +} + +?> diff --git a/lib/alfresco/Service/Node.php b/lib/alfresco/Service/Node.php new file mode 100755 index 0000000000..4b6de64159 --- /dev/null +++ b/lib/alfresco/Service/Node.php @@ -0,0 +1,815 @@ +_session = $session; + $this->_store = $store; + $this->_id = $id; + $this->_isNewNode = false; + $this->addedChildren = array(); + $this->addedParents = array(); + $this->addedAssociations = array(); + } + + /** + * Util method to create a node from a web service node structure. + */ + public static function createFromWebServiceData($session, $webServiceNode) + { + $scheme = $webServiceNode->reference->store->scheme; + $address = $webServiceNode->reference->store->address; + $id = $webServiceNode->reference->uuid; + + $store = $session->getStore($address, $scheme); + $node = $session->getNode($store, $id); + $node->populateFromWebServiceNode($webServiceNode); + + return $node; + } + + public function setPropertyValues($properties) + { + // Check that the properties of the node have been populated + $this->populateProperties(); + + // Set the property values + foreach ($properties as $name=>$value) + { + $name = $this->expandToFullName($name); + $this->_properties[$name] = $value; + } + } + + public function setContent($property, $mimetype=null, $encoding=null, $content=null) + { + list($property) = $this->_session->namespaceMap->getFullNames(array($property)); + $contentData = new ContentData($this, $property, $mimetype, $encoding); + if ($content != null) + { + $contentData->content = $content; + } + $this->_properties[$property] = $contentData; + + return $contentData; + } + + public function hasAspect($aspect) + { + list($aspect) = $this->_session->namespaceMap->getFullNames(array($aspect)); + $this->populateProperties(); + return in_array($aspect, $this->_aspects); + } + + public function addAspect($aspect, $properties = null) + { + list($aspect) = $this->_session->namespaceMap->getFullNames(array($aspect)); + $this->populateProperties(); + + if (in_array($aspect, $this->_aspects) == false) + { + $this->_aspects[] = $aspect; + if ($properties != null) + { + foreach ($properties as $name=>$value) + { + $name = $this->_session->namespaceMap->getFullName($name); + $this->_properties[$name] = $value; + } + } + + $this->remove_array_value($aspect, $this->removedAspects); + $this->addedAspects[] = $aspect; + } + } + + public function removeAspect($aspect) + { + list($aspect) = $this->_session->namespaceMap->getFullNames(array($aspect)); + $this->populateProperties(); + + if (in_array($aspect, $this->_aspects) == true) + { + $this->remove_array_value($aspect, $this->_aspects); + $this->remove_array_value($aspect, $this->addedAspects); + $this->removedAspects[] = $aspect; + } + } + + public function createChild($type, $associationType, $associationName) + { + list($type, $associationType, $associationName) = $this->_session->namespaceMap->getFullNames(array($type, $associationType, $associationName)); + + $id = $this->_session->nextSessionId(); + $newNode = new Node($this->_session, $this->_store, $id); + $childAssociation = new ChildAssociation($this, $newNode, $associationType, $associationName, true); + + $newNode->_isNewNode = true; + + $newNode->_properties = array(); + $newNode->_aspects = array(); + $newNode->_properties = array(); + $newNode->_children = array(); + $newNode->origionalProperties = array(); + $newNode->addedAspects = array(); + $newNode->removedAspects = array(); + + $newNode->_type = $type; + $newNode->_parents = array(); + $newNode->addedParents = array($this->__toString() => $childAssociation); + $newNode->_primaryParent = $this; + + $this->addedChildren[$newNode->__toString()] = $childAssociation; + + $this->_session->addNode($newNode); + + return $newNode; + } + + public function addChild($node, $associationType, $associationName) + { + list($associationType, $associationName) = $this->_session->namespaceMap->getFullNames(array($associationType, $associationName)); + + $childAssociation = new ChildAssociation($this, $node, $associationType, $associationName, false); + $this->addedChildren[$node->__toString()] = $childAssociation; + $node->addedParents[$this->__toString()] = $childAssociation; + } + + public function removeChild($childAssociation) + { + + } + + public function addAssociation($to, $associationType) + { + list($associationType) = $this->_session->namespaceMap->getFullNames(array($associationType)); + + $association = new Association($this, $to, $associationType); + $this->addedAssociations[$to->__toString()] = $association; + } + + public function removeAssociation($association) + { + + } + + public function createVersion($description=null, $major=false) + { + // We can only create a version if there are no outstanding changes for this node + if ($this->isDirty() == true) + { + throw new Exception("You must save any outstanding modifications before a new version can be created."); + } + + // TODO implement major flag ... + + $client = WebServiceFactory::getAuthoringService($this->_session->repository->connectionUrl, $this->_session->ticket); + $result = $client->createVersion( + array("items" => array("nodes" => $this->__toArray()), + "comments" => array("name" => "description", "value" => $description), + "versionChildren" => false)); + + // Clear the properties and aspects + $this->_properties = null; + $this->_aspects = null; + + // Get the version details + // TODO get some of the other details too ... + $versionId = $result->createVersionReturn->versions->id->uuid; + $versionStoreScheme = $result->createVersionReturn->versions->id->store->scheme; + $versionStoreAddress = $result->createVersionReturn->versions->id->store->address; + + // Create the version object to return + return new Version($this->_session, new Store($this->_session, $versionStoreAddress, $versionStoreScheme), $versionId); + } + + private function isDirty() + { + $result = true; + if ($this->_isNewNode == false && + count($this->getModifiedProperties()) == 0 && + ($this->addedAspects == null || count($this->addedAspects) == 0) && + ($this->removedAssociations == null || count($this->removedAssociations) == 0) && + ($this->addedChildren == null || count($this->addedChildren) == 0) && + ($this->addedAssociations == null || count($this->addedAssociations) == 0)) + { + $result = false; + } + return $result; + } + + public function __get($name) + { + $fullName = $this->_session->namespaceMap->getFullName($name); + if ($fullName != $name) + { + $this->populateProperties(); + if (array_key_exists($fullName, $this->_properties) == true) + { + return $this->_properties[$fullName]; + } + else + { + return null; + } + } + else + { + return parent::__get($name); + } + } + + public function __set($name, $value) + { + $fullName = $this->_session->namespaceMap->getFullName($name); + if ($fullName != $name) + { + $this->populateProperties(); + $this->_properties[$fullName] = $value; + + // Ensure that the node and property details are stored on the contentData object + if ($value instanceof ContentData) + { + $value->setPropertyDetails($this, $fullName); + } + } + else + { + parent::__set($name, $value); + } + } + + /** + * toString method. Returns node as a node reference style string. + */ + public function __toString() + { + return Node::__toNodeRef($this->_store, $this->id); + } + + public static function __toNodeRef($store, $id) + { + return $store->scheme . "://" . $store->address . "/" . $id; + } + + public function __toArray() + { + return array("store" => $this->_store->__toArray(), + "uuid" => $this->_id); + } + + public function getSession() + { + return $this->_session; + } + + public function getStore() + { + return $this->_store; + } + + public function getId() + { + return $this->_id; + } + + public function getIsNewNode() + { + return $this->_isNewNode; + } + + public function getType() + { + $this->populateProperties(); + return $this->_type; + } + + public function getAspects() + { + $this->populateProperties(); + return $this->_aspects; + } + + public function getProperties() + { + $this->populateProperties(); + return $this->_properties; + } + + public function setProperties($properties) + { + $this->populateProperties(); + $this->_properties = $properties; + } + + /** + * Accessor for the versionHistory property. + * + * @return VersionHistory the versionHistory for the node, null is none + */ + public function getVersionHistory() + { + if ($this->_versionHistory == null) + { + $this->_versionHistory = new VersionHistory($this); + } + return $this->_versionHistory; + } + + public function getChildren() + { + if ($this->_children == null) + { + $this->populateChildren(); + } + return $this->_children + $this->addedChildren; + } + + public function getParents() + { + if ($this->_parents == null) + { + $this->populateParents(); + } + return $this->_parents + $this->addedParents; + } + + public function getPrimaryParent() + { + if ($this->_primaryParent == null) + { + $this->populateParents(); + } + return $this->_primaryParent; + } + + public function getAssociations() + { + if ($this->_associations == null) + { + $this->populateAssociations(); + } + return $this->_associations + $this->addedAssociations; + } + + /** Methods used to populate node details from repository */ + + private function populateProperties() + { + if ($this->_isNewNode == false && $this->_properties == null) + { + $result = $this->_session->repositoryService->get(array ( + "where" => array ( + "nodes" => array( + "store" => $this->_store->__toArray(), + "uuid" => $this->_id)))); + + $this->populateFromWebServiceNode($result->getReturn); + } + } + + private function populateFromWebServiceNode($webServiceNode) + { + $this->_type = $webServiceNode->type; + + // Get the aspects + $this->_aspects = array(); + $aspects = $webServiceNode->aspects; + if (is_array($aspects) == true) + { + foreach ($aspects as $aspect) + { + $this->_aspects[] = $aspect; + } + } + else + { + $this->_aspects[] = $aspects; + } + + // Set the property values + // NOTE: do we need to be concerned with identifying whether this is an array or not when there is + // only one property on a node + $this->_properties = array(); + foreach ($webServiceNode->properties as $propertyDetails) + { + $name = $propertyDetails->name; + $isMultiValue = $propertyDetails->isMultiValue; + $value = null; + if ($isMultiValue == false) + { + $value = $propertyDetails->value; + if ($this->isContentData($value) == true) + { + $value = new ContentData($this, $name); + } + } + else + { + $value = $propertyDetails->values; + } + $this->_properties[$name] = $value; + + } + + $this->origionalProperties = $this->_properties; + $this->addedAspects = array(); + $this->removedAspects = array(); + + } + + private function populateChildren() + { + // TODO should do some sort of limited pull here + $result = $this->_session->repositoryService->queryChildren(array("node" => $this->__toArray())); + $resultSet = $result->queryReturn->resultSet; + + $children = array(); + $map = $this->resultSetToMap($resultSet); + foreach($map as $value) + { + $id = $value["{http://www.alfresco.org/model/system/1.0}node-uuid"]; + $store_scheme = $value["{http://www.alfresco.org/model/system/1.0}store-protocol"]; + $store_address = $value["{http://www.alfresco.org/model/system/1.0}store-identifier"]; + $assoc_type = $value["associationType"]; + $assoc_name = $value["associationName"]; + $isPrimary = $value["isPrimary"]; + $nthSibling = $value["nthSibling"]; + + $child = $this->_session->getNode(new Store($this->_session, $store_address, $store_scheme), $id); + $children[$child->__toString()] = new ChildAssociation($this, $child, $assoc_type, $assoc_name, $isPrimary, $nthSibling); + } + + $this->_children = $children; + } + + private function populateAssociations() + { + // TODO should do some sort of limited pull here + $result = $this->_session->repositoryService->queryAssociated(array("node" => $this->__toArray(), + "association" => array("associationType" => null, + "direction" => null))); + $resultSet = $result->queryReturn->resultSet; + + $associations = array(); + $map = $this->resultSetToMap($resultSet); + foreach($map as $value) + { + $id = $value["{http://www.alfresco.org/model/system/1.0}node-uuid"]; + $store_scheme = $value["{http://www.alfresco.org/model/system/1.0}store-protocol"]; + $store_address = $value["{http://www.alfresco.org/model/system/1.0}store-identifier"]; + $assoc_type = $value["associationType"]; + + $to = $this->_session->getNode(new Store($this->_session, $store_address, $store_scheme), $id); + $associations[$to->__toString()] = new Association($this, $to, $assoc_type); + } + + $this->_associations = $associations; + } + + private function populateParents() + { + // TODO should do some sort of limited pull here + $result = $this->_session->repositoryService->queryParents(array("node" => $this->__toArray())); + $resultSet = $result->queryReturn->resultSet; + + $parents = array(); + $map = $this->resultSetToMap($resultSet); + foreach($map as $value) + { + $id = $value["{http://www.alfresco.org/model/system/1.0}node-uuid"]; + $store_scheme = $value["{http://www.alfresco.org/model/system/1.0}store-protocol"]; + $store_address = $value["{http://www.alfresco.org/model/system/1.0}store-identifier"]; + $assoc_type = $value["associationType"]; + $assoc_name = $value["associationName"]; + $isPrimary = $value["isPrimary"]; + $nthSibling = $value["nthSibling"]; + + $parent = $this->_session->getNode(new Store($this->_session, $store_address, $store_scheme), $id); + if ($isPrimary == "true" or $isPrimary == true) + { + $this->_primaryParent = $parent; + } + $parents[$parent->__toString()] = new ChildAssociation($parent, $this, $assoc_type, $assoc_name, $isPrimary, $nthSibling); + } + + $this->_parents = $parents; + } + + public function onBeforeSave(&$statements) + { + if ($this->_isNewNode == true) + { + $childAssociation = $this->addedParents[$this->_primaryParent->__toString()]; + + $parentArray = array(); + $parent = $this->_primaryParent; + if ($parent->_isNewNode == true) + { + $parentArray["parent_id"] = $parent->id; + $parentArray["associationType"] = $childAssociation->type; + $parentArray["childName"] = $childAssociation->name; + } + else + { + $parentArray["parent"] = array( + "store" => $this->_store->__toArray(), + "uuid" => $this->_primaryParent->_id, + "associationType" => $childAssociation->type, + "childName" => $childAssociation->name); + } + + $this->addStatement($statements, "create", + array("id" => $this->_id) + + $parentArray + + array( + "type" => $this->_type, + "property" => $this->getPropertyArray($this->_properties))); + } + else + { + // Add the update statement for the modified properties + $modifiedProperties = $this->getModifiedProperties(); + if (count($modifiedProperties) != 0) + { + $this->addStatement($statements, "update", array("property" => $this->getPropertyArray($modifiedProperties)) + $this->getWhereArray()); + } + + // TODO deal with any deleted properties + } + + // Update any modified content properties + if ($this->_properties != null) + { + foreach($this->_properties as $name=>$value) + { + if (($value instanceof ContentData) && $value->isDirty == true) + { + $value->onBeforeSave($statements, $this->getWhereArray()); + } + } + } + + // Add the addAspect statements + if ($this->addedAspects != null) + { + foreach($this->addedAspects as $aspect) + { + $this->addStatement($statements, "addAspect", array("aspect" => $aspect) + $this->getWhereArray()); + } + } + + // Add the removeAspect + if ($this->removedAspects != null) + { + foreach($this->removedAspects as $aspect) + { + $this->addStatement($statements, "removeAspect", array("aspect" => $aspect) + $this->getWhereArray()); + } + } + + // Add non primary children + foreach($this->addedChildren as $childAssociation) + { + if ($childAssociation->isPrimary == false) + { + + $assocDetails = array("associationType" => $childAssociation->type, "childName" => $childAssociation->name); + + $temp = array(); + if ($childAssociation->child->_isNewNode == true) + { + $temp["to_id"] = $childAssociation->child->_id; + $temp = $temp + $assocDetails; + } + else + { + $temp["to"] = array( + "store" => $this->_store->__toArray(), + "uuid" => $childAssociation->child->_id) + + $assocDetails; + } + $temp = $temp + $this->getWhereArray(); + $this->addStatement($statements, "addChild", $temp); + } + } + + // Add associations + foreach($this->addedAssociations as $association) + { + $temp = array("association" => $association->type); + $temp = $temp + $this->getPredicateArray("from", $this) + $this->getPredicateArray("to", $association->to); + $this->addStatement($statements, "createAssociation", $temp); + } + } + + private function addStatement(&$statements, $statement, $body) + { + $result = array(); + if (array_key_exists($statement, $statements) == true) + { + $result = $statements[$statement]; + } + $result[] = $body; + $statements[$statement] = $result; + } + + private function getWhereArray() + { + return $this->getPredicateArray("where", $this); + } + + private function getPredicateArray($label, $node) + { + if ($node->_isNewNode == true) + { + return array($label."_id" => $node->_id); + } + else + { + return array( + $label => array( + "nodes" => $node->__toArray() + )); + } + } + + private function getPropertyArray($properties) + { + $result = array(); + foreach ($properties as $name=>$value) + { + // Ignore content properties + if (($value instanceof ContentData) == false) + { + // TODO need to support multi values + $result[] = array( + "name" => $name, + "isMultiValue" => false, + "value" => $value); + } + } + return $result; + } + + private function getModifiedProperties() + { + $modified = $this->_properties; + $origional = $this->origionalProperties; + $result = array(); + if ($modified != null) + { + foreach ($modified as $key=>$value) + { + // Ignore content properties + if (($value instanceof ContentData) == false) + { + if (array_key_exists($key, $origional) == true) + { + // Check to see if the value have been modified + if ($value != $origional[$key]) + { + $result[$key] = $value; + } + } + else + { + $result[$key] = $value; + } + } + } + } + return $result; + } + + public function onAfterSave($idMap) + { + if (array_key_exists($this->_id, $idMap ) == true) + { + $uuid = $idMap[$this->_id]; + if ($uuid != null) + { + $this->_id = $uuid; + } + } + + if ($this->_isNewNode == true) + { + $this->_isNewNode = false; + + // Clear the properties and aspect + $this->_properties = null; + $this->_aspects = null; + } + + // Update any modified content properties + if ($this->_properties != null) + { + foreach($this->_properties as $name=>$value) + { + if (($value instanceof ContentData) && $value->isDirty == true) + { + $value->onAfterSave(); + } + } + } + + $this->origionalProperties = $this->_properties; + + if ($this->_aspects != null) + { + // Calculate the updated aspect list + if ($this->addedAspects != null) + { + $this->_aspects = $this->_aspects + $this->addedAspects; + } + if ($this->removedAspects != null) + { + foreach ($this->_aspects as $aspect) + { + if (in_array($aspect, $this->removedAspects) == true) + { + $this->remove_array_value($aspect, $this->_aspects); + } + } + } + } + $this->addedAspects = array(); + $this->removedAspects = array(); + + if ($this->_parents != null) + { + $this->_parents = $this->_parents + $this->addedParents; + } + $this->addedParents = array(); + + if ($this->_children != null) + { + $this->_children = $this->_children + $this->addedChildren; + } + $this->addedChildren = array(); + + if ($this->_associations != null) + { + $this->_associations = $this->_associations + $this->addedAssociations; + } + $this->addedAssociations = array(); + } +} +?> \ No newline at end of file diff --git a/lib/alfresco/Service/Repository.php b/lib/alfresco/Service/Repository.php new file mode 100755 index 0000000000..edc9fe29b2 --- /dev/null +++ b/lib/alfresco/Service/Repository.php @@ -0,0 +1,133 @@ +_connectionUrl = $connectionUrl; + $parts = parse_url($connectionUrl); + $this->_host = $parts["host"]; + $this->_port = $parts["port"]; + } + + public function getConnectionUrl() + { + return $this->_connectionUrl; + } + + public function getHost() + { + return $this->_host; + } + + public function getPort() + { + return $this->_port; + } + + public function authenticate($userName, $password) + { + // TODO need to handle exceptions! + + $authenticationService = WebServiceFactory::getAuthenticationService($this->_connectionUrl); + $result = $authenticationService->startSession(array ( + "username" => $userName, + "password" => $password + )); + + // Get the ticket and sessionId + $ticket = $result->startSessionReturn->ticket; + $sessionId = $result->startSessionReturn->sessionid; + + // Store the session id for later use + if ($sessionId != null) + { + $sessionIds = null; + if (isset($_SESSION["sessionIds"]) == false) + { + $sessionIds = array(); + } + else + { + $sessionIds = $_SESSION["sessionIds"]; + } + $sessionIds[$ticket] = $sessionId; + $_SESSION["sessionIds"] = $sessionIds; + } + + return $ticket; + } + + public function createSession($ticket=null) + { + $session = null; + + if ($ticket == null) + { + // TODO get ticket from some well known location ie: the $_SESSION + } + else + { + // TODO would be nice to be able to check that the ticket is still valid! + + // Create new session + $session = new Session($this, $ticket); + } + + return $session; + } + + /** + * For a given ticket, returns the realated session id, null if one can not be found. + */ + public static function getSessionId($ticket) + { + $result = null; + if (isset($_SESSION["sessionIds"]) == true) + { + $result = $_SESSION["sessionIds"][$ticket]; + } + return $result; + + } + +} + + ?> diff --git a/lib/alfresco/Service/Session.php b/lib/alfresco/Service/Session.php new file mode 100755 index 0000000000..4baf57c1d8 --- /dev/null +++ b/lib/alfresco/Service/Session.php @@ -0,0 +1,277 @@ +nodeCache = array(); + + $this->_repository = $repository; + $this->_ticket = $ticket; + + $this->repositoryService = WebServiceFactory::getRepositoryService($this->_repository->connectionUrl, $this->_ticket); + $this->contentService = WebServiceFactory::getContentService($this->_repository->connectionUrl, $this->_ticket); + } + + /** + * Creates a new store in the current respository + * + * @param $address the address of the new store + * @param $scheme the scheme of the new store, default value of 'workspace' + * @return Store the new store + */ + public function createStore($address, $scheme="workspace") + { + // Create the store + $result = $this->repositoryService->createStore(array( + "scheme" => $scheme, + "address" => $address)); + $store = new Store($this, $result->createStoreReturn->address, $result->createStoreReturn->scheme); + + // Add to the cached list if its been populated + if (isset($this->_stores) == true) + { + $this->_stores[] = $store; + } + + // Return the newly created store + return $store; + } + + /** + * Get the store + * + * @param $address the address of the store + * @param $scheme the scheme of the store. The default it 'workspace' + * @return Store the store + */ + public function getStore($address, $scheme="workspace") + { + return new Store($this, $address, $scheme); + } + + /** + * Get the store from it string representation (eg: workspace://SpacesStore) + * + * @param $value the stores string representation + * @return Store the store + */ + public function getStoreFromString($value) + { + list($scheme, $address) = split("://", $value); + return new Store($this, $address, $scheme); + } + + public function getNode($store, $id) + { + $node = $this->getNodeImpl($store, $id); + if ($node == null) + { + $node = new Node($this, $store, $id); + $this->addNode($node); + } + return $node; + } + + public function getNodeFromString($value) + { + // TODO + throw Exception("getNode($value) no yet implemented"); + } + + /** + * Adds a new node to the session. + */ + public function addNode($node) + { + $this->nodeCache[$node->__toString()] = $node; + } + + private function getNodeImpl($store, $id) + { + $result = null; + $nodeRef = $store->scheme . "://" . $store->address . "/" . $id; + if (array_key_exists($nodeRef, $this->nodeCache) == true) + { + $result = $this->nodeCache[$nodeRef]; + } + return $result; + } + + /** + * Commits all unsaved changes to the repository + */ + public function save($debug=false) + { + // Build the update statements from the node cache + $statements = array(); + foreach ($this->nodeCache as $node) + { + $node->onBeforeSave($statements); + } + + if ($debug == true) + { + var_dump($statements); + echo ("

"); + } + + if (count($statements) > 0) + { + // Make the web service call + $result = $this->repositoryService->update(array("statements" => $statements)); + //var_dump($result); + + // Update the state of the updated nodes + foreach ($this->nodeCache as $node) + { + $node->onAfterSave($this->getIdMap($result)); + } + } + } + + /** + * Clears the current session by emptying the node cache. + * + * WARNING: all unsaved changes will be lost when clearing the session. + */ + public function clear() + { + // Clear the node cache + $this->nodeCache = array(); + } + + private function getIdMap($result) + { + $return = array(); + $statements = $result->updateReturn; + if (is_array($statements) == true) + { + foreach ($statements as $statement) + { + if ($statement->statement == "create") + { + $id = $statement->sourceId; + $uuid = $statement->destination->uuid; + $return[$id] = $uuid; + } + } + } + else + { + if ($statements->statement == "create") + { + $id = $statements->sourceId; + $uuid = $statements->destination->uuid; + $return[$id] = $uuid; + } + } + return $return; + } + + public function query($store, $query, $language='lucene') + { + // TODO need to support paged queries + $result = $this->repositoryService->query(array( + "store" => $store->__toArray(), + "query" => array( + "language" => $language, + "statement" => $query), + "includeMetaData" => false)); + + // TODO for now do nothing with the score and the returned data + $resultSet = $result->queryReturn->resultSet; + return $this->resultSetToNodes($this, $store, $resultSet); + } + + public function getTicket() + { + return $this->_ticket; + } + + public function getRepository() + { + return $this->_repository; + } + + public function getNamespaceMap() + { + if ($this->_namespaceMap == null) + { + $this->_namespaceMap = new NamespaceMap(); + } + return $this->_namespaceMap; + } + + public function getStores() + { + if (isset ($this->_stores) == false) + { + $this->_stores = array (); + $results = $this->repositoryService->getStores(); + + foreach ($results->getStoresReturn as $result) + { + $this->_stores[] = new Store($this, $result->address, $result->scheme); + } + } + + return $this->_stores; + } + + /** Want these methods to be package scope some how! **/ + + public function nextSessionId() + { + $sessionId = "session".$this->_ticket.$this->idCount; + $this->idCount ++; + return $sessionId; + } +} +?> \ No newline at end of file diff --git a/lib/alfresco/Service/SpacesStore.php b/lib/alfresco/Service/SpacesStore.php new file mode 100755 index 0000000000..5764f46a1d --- /dev/null +++ b/lib/alfresco/Service/SpacesStore.php @@ -0,0 +1,54 @@ +scheme . "://" . $this->address; + } + + public function getCompanyHome() + { + if ($this->_companyHome == null) + { + $nodes = $this->_session->query($this, 'PATH:"app:company_home"'); + $this->_companyHome = $nodes[0]; + } + return $this->_companyHome; + } +} +?> \ No newline at end of file diff --git a/lib/alfresco/Service/Store.php b/lib/alfresco/Service/Store.php new file mode 100755 index 0000000000..fa72978c4b --- /dev/null +++ b/lib/alfresco/Service/Store.php @@ -0,0 +1,81 @@ +_session = $session; + $this->_address = $address; + $this->_scheme = $scheme; + } + + public function __toString() + { + return $this->scheme . "://" . $this->address; + } + + public function __toArray() + { + return array( + "scheme" => $this->_scheme, + "address" => $this->_address); + } + + public function getAddress() + { + return $this->_address; + } + + public function getScheme() + { + return $this->_scheme; + } + + public function getRootNode() + { + if (isset ($this->_rootNode) == false) + { + $result = $this->_session->repositoryService->get( + array( + "where" => array( + "store" => $this->__toArray()))); + + $this->_rootNode = Node::createFromWebServiceData($this->_session, $result->getReturn); + } + + return $this->_rootNode; + } +} +?> \ No newline at end of file diff --git a/lib/alfresco/Service/Version.php b/lib/alfresco/Service/Version.php new file mode 100755 index 0000000000..cd1fd85b6e --- /dev/null +++ b/lib/alfresco/Service/Version.php @@ -0,0 +1,200 @@ +_session = $session; + $this->_store = $store; + $this->_id = $id; + $this->_description = $description; + $this->_major = $major; + $this->_properties = null; + $this->_aspects = null; + $this->_type = null; + } + + /** + * __get override. + * + * If called with a valid property short name, the frozen value of that property is returned. + * + * @return String the appropriate property value, null if none found + */ + public function __get($name) + { + $fullName = $this->_session->namespaceMap->getFullName($name); + if ($fullName != $name) + { + $this->populateProperties(); + if (array_key_exists($fullName, $this->_properties) == true) + { + return $this->_properties[$fullName]; + } + else + { + return null; + } + } + else + { + return parent::__get($name); + } + } + + /** + * Gets session + * + * @return Session the session + */ + public function getSession() + { + return $this->_session; + } + + /** + * Get the frozen nodes store + * + * @return Store the store + */ + public function getStore() + { + return $this->_store; + } + + public function getId() + { + return $this->_id; + } + + public function getDescription() + { + return $this->_description; + } + + public function getMajor() + { + return $this->_major; + } + + public function getType() + { + return $this->_type; + } + + public function getProperties() + { + return $this->_properties; + } + + public function getAspects() + { + return $this->_aspects; + } + + private function populateProperties() + { + if ($this->_properties == null) + { + $result = $this->_session->repositoryService->get(array ( + "where" => array ( + "nodes" => array( + "store" => $this->_store->__toArray(), + "uuid" => $this->_id)))); + + $this->populateFromWebServiceNode($result->getReturn); + } + } + + private function populateFromWebServiceNode($webServiceNode) + { + $this->_type = $webServiceNode->type; + + // Get the aspects + $this->_aspects = array(); + $aspects = $webServiceNode->aspects; + if (is_array($aspects) == true) + { + foreach ($aspects as $aspect) + { + $this->_aspects[] = $aspect; + } + } + else + { + $this->_aspects[] = $aspects; + } + + // Set the property values + $this->_properties = array(); + foreach ($webServiceNode->properties as $propertyDetails) + { + $name = $propertyDetails->name; + $isMultiValue = $propertyDetails->isMultiValue; + $value = null; + if ($isMultiValue == false) + { + $value = $propertyDetails->value; + if ($this->isContentData($value) == true) + { + $value = new ContentData($this, $name); + } + } + else + { + $value = $propertyDetails->values; + } + + $this->_properties[$name] = $value; + } + } + } +?> diff --git a/lib/alfresco/Service/VersionHistory.php b/lib/alfresco/Service/VersionHistory.php new file mode 100755 index 0000000000..c590611345 --- /dev/null +++ b/lib/alfresco/Service/VersionHistory.php @@ -0,0 +1,80 @@ +_node = $node; + $this->populateVersionHistory(); + } + + /** + * Get the node that this version history relates to + */ + public function getNode() + { + return $this->_node; + } + + /** + * Get a list of the versions in the version history + */ + public function getVersions() + { + return $this->_versions; + } + + /** + * Populate the version history + */ + private function populateVersionHistory() + { + // Use the web service API to get the version history for this node + $client = WebServiceFactory::getAuthoringService($this->_node->session->repository->connectionUrl, $this->_node->session->ticket); + $result = $client->getVersionHistory(array("node" => $this->_node->__toArray())); + //var_dump($result); + + // TODO populate the version history from the result of the web service call + } + } +?> diff --git a/lib/alfresco/Service/WebService/AlfrescoWebService.php b/lib/alfresco/Service/WebService/AlfrescoWebService.php new file mode 100755 index 0000000000..e79cae1b20 --- /dev/null +++ b/lib/alfresco/Service/WebService/AlfrescoWebService.php @@ -0,0 +1,117 @@ + true, 'exceptions' => true), $ticket = null) + { + // Store the current ticket + $this->ticket = $ticket; + + // Call the base class + parent::__construct($wsdl, $options); + } + + public function __call($function_name, $arguments=array()) + { + return $this->__soapCall($function_name, $arguments); + } + + public function __soapCall($function_name, $arguments=array(), $options=array(), $input_headers=array(), $output_headers=array()) + { + if (isset($this->ticket)) + { + // Automatically add a security header + $input_headers[] = new SoapHeader($this->securityExtNS, "Security", null, 1); + + // Set the JSESSION cookie value + $sessionId = Al_Repository::getSessionId($this->ticket); // Moodle + if ($sessionId != null) + { + $this->__setCookie("JSESSIONID", $sessionId); + } + } + + return parent::__soapCall($function_name, $arguments, $options, $input_headers, $output_headers); + } + + public function __doRequest($request, $location, $action, $version) + { + // If this request requires authentication we have to manually construct the + // security headers. + if (isset($this->ticket)) + { + $dom = new DOMDocument("1.0"); + $dom->loadXML($request); + + $securityHeader = $dom->getElementsByTagName("Security"); + + if ($securityHeader->length != 1) + { + throw new Exception("Expected length: 1, Received: " . $securityHeader->length . ". No Security Header, or more than one element called Security!"); + } + + $securityHeader = $securityHeader->item(0); + + // Construct Timestamp Header + $timeStamp = $dom->createElementNS($this->wsUtilityNS, "Timestamp"); + $createdDate = date("Y-m-d\TH:i:s\Z", mktime(date("H")+24, date("i"), date("s"), date("m"), date("d"), date("Y"))); + $expiresDate = date("Y-m-d\TH:i:s\Z", mktime(date("H")+25, date("i"), date("s"), date("m"), date("d"), date("Y"))); + $created = new DOMElement("Created", $createdDate, $this->wsUtilityNS); + $expires = new DOMElement("Expires", $expiresDate, $this->wsUtilityNS); + $timeStamp->appendChild($created); + $timeStamp->appendChild($expires); + + // Construct UsernameToken Header + $userNameToken = $dom->createElementNS($this->securityExtNS, "UsernameToken"); + $userName = new DOMElement("Username", "username", $this->securityExtNS); + $passWord = $dom->createElementNS($this->securityExtNS, "Password"); + $typeAttr = new DOMAttr("Type", $this->passwordType); + $passWord->appendChild($typeAttr); + $passWord->appendChild($dom->createTextNode($this->ticket)); + $userNameToken->appendChild($userName); + $userNameToken->appendChild($passWord); + + // Construct Security Header + $securityHeader->appendChild($timeStamp); + $securityHeader->appendChild($userNameToken); + + // Save the XML Request + $request = $dom->saveXML(); + } + + return parent::__doRequest($request, $location, $action, $version); + } +} + +?> diff --git a/lib/alfresco/Service/WebService/WebServiceFactory.php b/lib/alfresco/Service/WebService/WebServiceFactory.php new file mode 100755 index 0000000000..acc6aa96d9 --- /dev/null +++ b/lib/alfresco/Service/WebService/WebServiceFactory.php @@ -0,0 +1,63 @@ + \ No newline at end of file diff --git a/repository/alfresco/icon.png b/repository/alfresco/icon.png new file mode 100644 index 0000000000..807974998b Binary files /dev/null and b/repository/alfresco/icon.png differ diff --git a/repository/alfresco/repository.class.php b/repository/alfresco/repository.class.php new file mode 100755 index 0000000000..05918dfcb6 --- /dev/null +++ b/repository/alfresco/repository.class.php @@ -0,0 +1,160 @@ +libdir . '/soaplib.php'); +require_once($CFG->libdir . '/alfresco/Service/Repository.php'); +require_once($CFG->libdir . '/alfresco/Service/Session.php'); +require_once($CFG->libdir . '/alfresco/Service/SpacesStore.php'); +require_once($CFG->libdir . '/alfresco/Service/Node.php'); + +class repository_alfresco extends repository { + private $repo = null; + private $ticket = null; + private $sess = null; + private $store = null; + + public function __construct($repositoryid, $context = SITEID, $options = array()) { + global $SESSION, $CFG; + parent::__construct ($repositoryid, $context, $options); + $this->repo = new Al_Repository($this->alfresco_url); + $this->sess_name = 'alfresco_ticket_'.$this->id; + $this->username = optional_param('al_username', '', PARAM_RAW); + $this->password = optional_param('al_password', '', PARAM_RAW); + if ( empty($SESSION->{$this->sess_name}) && + !empty($this->username) && !empty($this->password)) { + $this->ticket = $this->repo->authenticate($this->username, $this->password); + $SESSION->{$this->sess_name} = $this->ticket; + } else { + $this->ticket = $SESSION->{$this->sess_name}; + } + $this->sess = $this->repo->createSession($this->ticket); + $this->store = new SpacesStore($this->sess); + $this->current_node = null; + } + public function print_login() { + if ($this->options['ajax']) { + $user_field->label = get_string('username', 'repository_alfresco').': '; + $user_field->id = 'alfresco_username'; + $user_field->type = 'text'; + $user_field->name = 'al_username'; + + $passwd_field->label = get_string('password', 'repository_alfresco').': '; + $passwd_field->id = 'alfresco_password'; + $passwd_field->type = 'password'; + $passwd_field->name = 'al_password'; + + $ret = array(); + $ret['login'] = array($user_field, $passwd_field); + return $ret; + } + } + + public function logout() { + global $SESSION; + unset($SESSION->{$this->sess_name}); + return $this->print_login(); + } + + public function check_login() { + global $SESSION; + return !empty($SESSION->{$this->sess_name}); + } + + private function get_url($node) { + $result = null; + if ($node->type == "{http://www.alfresco.org/model/content/1.0}content") { + $contentData = $node->cm_content; + if ($contentData != null) { + $result = $contentData->getUrl(); + } + } else { + $result = "index.php?". + "&uuid=".$node->id. + "&name=".$node->cm_name. + "&path=".'Company Home'; + } + return $result; + } + + public function get_listing($uuid = '', $search = '') { + global $CFG; + + $ret = array(); + $ret['manage'] = $CFG->wwwroot .'/files/index.php'; // temporary + $ret['dynload'] = true; + $ret['list'] = array(); + $ret['path'] = array(array('name'=>'Root', 'path'=>'')); + + if (empty($uuid)) { + $this->current_node = $this->store->companyHome; + } else { + $this->current_node = $this->sess->getNode($this->store, $uuid); + } + $folder_filter = "{http://www.alfresco.org/model/content/1.0}folder"; + $file_filter = "{http://www.alfresco.org/model/content/1.0}content"; + foreach ($this->current_node->children as $child) + { + if ($child->child->type == $folder_filter) + { + $ret['list'][] = array('title'=>$child->child->cm_name, + 'path'=>$child->child->id, + 'thumbnail'=>$CFG->pixpath.'/f/folder.gif', + 'children'=>array()); + } elseif ($child->child->type == $file_filter) { + $ret['list'][] = array('title'=>$child->child->cm_name, + 'thumbnail' => $CFG->pixpath .'/f/'. mimeinfo("icon", $child->child->cm_name), + 'source'=>$child->child->id); + } + } + return $ret; + } + + public function get_file($uuid, $file = '') { + global $CFG; + $node = $this->sess->getNode($this->store, $uuid); + $url = $this->get_url($node); + if (!file_exists($CFG->dataroot.'/repository/download')) { + mkdir($CFG->dataroot.'/repository/download/', 0777, true); + } + if(is_dir($CFG->dataroot.'/repository/download')) { + $dir = $CFG->dataroot.'/repository/download/'; + } + + if (empty($file)) { + $file = $photo_id.'_'.time().'.jpg'; + } + if (file_exists($dir.$file)) { + $file = uniqid('m').$file; + } + $fp = fopen($dir.$file, 'w'); + $c = new curl; + $c->download(array(array('url'=>$url, 'file'=>$fp))); + return $dir.$file; + } + + public function print_search() { + parent::print_search(); + return true; + } + + public function search($search_text) { + global $CFG; + $ret = array(); + $ret['list'] = array(); + return $ret; + } + + public static function get_instance_option_names() { + return array('alfresco_url'); + } + + public function instance_config_form(&$mform) { + $mform->addElement('text', 'alfresco_url', get_string('alfresco_url', 'repository_alfresco'), array('size' => '40')); + $mform->addRule('alfresco_url', get_string('required'), 'required', null, 'client'); + } +} +?>