]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-16384, first draft of alfresco plugin
authordongsheng <dongsheng>
Fri, 19 Sep 2008 04:49:38 +0000 (04:49 +0000)
committerdongsheng <dongsheng>
Fri, 19 Sep 2008 04:49:38 +0000 (04:49 +0000)
TODO:
1) Create a SOAP wrapper
2) Implement searching

21 files changed:
lang/en_utf8/repository_alfresco.php [new file with mode: 0644]
lib/alfresco/README_MOODLE.txt [new file with mode: 0644]
lib/alfresco/Service/Association.php [new file with mode: 0755]
lib/alfresco/Service/BaseObject.php [new file with mode: 0755]
lib/alfresco/Service/ChildAssociation.php [new file with mode: 0755]
lib/alfresco/Service/ContentData.php [new file with mode: 0755]
lib/alfresco/Service/Functions.php [new file with mode: 0755]
lib/alfresco/Service/Logger/Logger.php [new file with mode: 0755]
lib/alfresco/Service/Logger/LoggerConfig.php [new file with mode: 0755]
lib/alfresco/Service/NamespaceMap.php [new file with mode: 0755]
lib/alfresco/Service/Node.php [new file with mode: 0755]
lib/alfresco/Service/Repository.php [new file with mode: 0755]
lib/alfresco/Service/Session.php [new file with mode: 0755]
lib/alfresco/Service/SpacesStore.php [new file with mode: 0755]
lib/alfresco/Service/Store.php [new file with mode: 0755]
lib/alfresco/Service/Version.php [new file with mode: 0755]
lib/alfresco/Service/VersionHistory.php [new file with mode: 0755]
lib/alfresco/Service/WebService/AlfrescoWebService.php [new file with mode: 0755]
lib/alfresco/Service/WebService/WebServiceFactory.php [new file with mode: 0755]
repository/alfresco/icon.png [new file with mode: 0644]
repository/alfresco/repository.class.php [new file with mode: 0755]

diff --git a/lang/en_utf8/repository_alfresco.php b/lang/en_utf8/repository_alfresco.php
new file mode 100644 (file)
index 0000000..710abc6
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+$string['configplugin'] = 'Alfresco configuration';
+$string['notitle'] = 'notitle';
+$string['repositoryname'] = 'Alfresco Repository';
+$string['repositorydesc'] = 'A plug-in for Alfresco CMS';
+$string['username'] = 'User name';
+$string['password'] = 'Password';
+$string['alfresco_url'] = 'Alfresco URL';
diff --git a/lib/alfresco/README_MOODLE.txt b/lib/alfresco/README_MOODLE.txt
new file mode 100644 (file)
index 0000000..4a97f96
--- /dev/null
@@ -0,0 +1,17 @@
+@VERSION $Id$
+
+== CHANGELOG ==
+
+Alfresco PHP Libarary was modified by Moodle, because of class name conflict.
+See, Service/Repository.php & Service/WebService/AlfrescoWebService.php
+All the changes are marked as "Moodle"
+
+== Alfresco PHP Libarary ==
+
+Installation and developer documentation for the Alfresco PHP Library can be found on the Alfresco Wiki.
+
+== Documentation Links ==
+
+Installation Instructions - http://wiki.alfresco.com/wiki/Alfresco_PHP_Library_Installation_Instructions
+MediaWiki Integration Installation Instructions - http://wiki.alfresco.com/wiki/Alfresco_MediaWiki_Installation_Instructions
+PHP API Documentation - http://wiki.alfresco.com/wiki/Alfresco_PHP_API
diff --git a/lib/alfresco/Service/Association.php b/lib/alfresco/Service/Association.php
new file mode 100755 (executable)
index 0000000..9892d9f
--- /dev/null
@@ -0,0 +1,57 @@
+<?php\r
+\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+class Association extends BaseObject\r
+{\r
+       private $_from;\r
+       private $_to;\r
+       private $_type;\r
+       \r
+       public function __construct($from, $to, $type)\r
+       {\r
+               $this->_from = $from;\r
+               $this->_to = $to;\r
+               $this->_type = $type;   \r
+       }\r
+       \r
+       public function getFrom()\r
+       {\r
+               return $this->_from;\r
+       }\r
+       \r
+       public function getTo()\r
+       {\r
+               return $this->_to;\r
+       }\r
+       \r
+       public function getType()\r
+       {\r
+               return $this->_type;\r
+       }\r
+}\r
+\r
+?>\r
diff --git a/lib/alfresco/Service/BaseObject.php b/lib/alfresco/Service/BaseObject.php
new file mode 100755 (executable)
index 0000000..3550215
--- /dev/null
@@ -0,0 +1,147 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005-2007 Alfresco Software Limited.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+class BaseObject\r
+{\r
+       public function __get($name)\r
+       {       \r
+               $methodName = $name;\r
+               $methodName[0] = strtoupper($methodName[0]);\r
+               $methodName = 'get' . $methodName;\r
+               \r
+               if (method_exists($this, $methodName) == true)\r
+               {\r
+                   return $this->$methodName();                        \r
+               }\r
+       }\r
+       \r
+       public function __set($name, $value)\r
+       {\r
+               $methodName = $name;\r
+               $methodName[0] = strtoupper($methodName[0]);\r
+               $methodName = 'set' . $methodName;\r
+               \r
+               if (method_exists($this, $methodName) == true)\r
+               {\r
+                       return $this->$methodName($value);\r
+               }       \r
+       }\r
+       \r
+       protected function resultSetToNodes($session, $store, $resultSet)\r
+       {\r
+               $return = array();              \r
+        if (isset($resultSet->rows) == true)\r
+        {\r
+                       if (is_array($resultSet->rows) == true)\r
+                       {               \r
+                               foreach($resultSet->rows as $row)\r
+                               {\r
+                                       $id = $row->node->id;\r
+                                       $return[] = $session->getNode($store, $id);                             \r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $id = $resultSet->rows->node->id;\r
+                               $return[] = $session->getNode($store, $id);\r
+                       }\r
+        }\r
+               \r
+               return $return;\r
+       }\r
+       \r
+       protected function resultSetToMap($resultSet)\r
+       {\r
+               $return = array();      \r
+        if (isset($resultSet->rows) == true)\r
+        {        \r
+                       if (is_array($resultSet->rows) == true)\r
+                       {\r
+                               foreach($resultSet->rows as $row)\r
+                               {\r
+                                       $return[] = $this->columnsToMap($row->columns);                         \r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $return[] = $this->columnsToMap($resultSet->rows->columns);\r
+                       }\r
+\r
+        }\r
+               \r
+               return $return; \r
+       }\r
+       \r
+       private function columnsToMap($columns)\r
+       {\r
+               $return = array();              \r
+      \r
+               foreach ($columns as $column)\r
+               {\r
+                       $return[$column->name] = $column->value;\r
+               }\r
+               \r
+               return $return; \r
+       }\r
+       \r
+       protected function remove_array_value($value, &$array)\r
+       {\r
+               if ($array != null)\r
+               {\r
+                       if (in_array($value, $array) == true)\r
+                       {\r
+                               foreach ($array as $index=>$value2)\r
+                               {\r
+                                       if ($value == $value2)\r
+                                       {\r
+                                               unset($array[$index]);\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       } \r
+       \r
+       protected function isContentData($value)\r
+       {               \r
+               $index = strpos($value, "contentUrl=");\r
+               if ($index === false)\r
+               {\r
+                       return false;\r
+               }       \r
+               else\r
+               {       \r
+                       if ($index == 0)\r
+                       {       \r
+                               return true;\r
+                       }\r
+                       else\r
+                       {\r
+                               return false;\r
+                       }\r
+               }\r
+       }\r
+}\r
+?>
\ No newline at end of file
diff --git a/lib/alfresco/Service/ChildAssociation.php b/lib/alfresco/Service/ChildAssociation.php
new file mode 100755 (executable)
index 0000000..d856ddd
--- /dev/null
@@ -0,0 +1,76 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+class ChildAssociation extends BaseObject\r
+{\r
+       private $_parent;\r
+       private $_child;\r
+       private $_type;\r
+       private $_name;\r
+       private $_isPrimary;\r
+       private $_nthSibling;\r
+       \r
+       public function __construct($parent, $child, $type, $name, $isPrimary=false, $nthSibling=0)\r
+       {\r
+               $this->_parent = $parent;\r
+               $this->_child = $child;\r
+               $this->_type = $type;\r
+               $this->_name = $name;\r
+               $this->_isPrimary = $isPrimary;\r
+               $this->_nthSibling = $nthSibling;\r
+       }\r
+       \r
+       public function getParent()\r
+       {\r
+               return $this->_parent;\r
+       }\r
+       \r
+       public function getChild()\r
+       {\r
+               return $this->_child;\r
+       }\r
+       \r
+       public function getType()\r
+       {\r
+               return $this->_type;\r
+       }\r
+       \r
+       public function getName()\r
+       {\r
+               return $this->_name;\r
+       }\r
+       \r
+       public function getIsPrimary()\r
+       {\r
+               return $this->_isPrimary;\r
+       }\r
+       \r
+       public function getNthSibling()\r
+       {\r
+               return $this->_nthSibling;\r
+       }\r
+}\r
+?>\r
diff --git a/lib/alfresco/Service/ContentData.php b/lib/alfresco/Service/ContentData.php
new file mode 100755 (executable)
index 0000000..0f49351
--- /dev/null
@@ -0,0 +1,290 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+require_once("Functions.php");\r
+\r
+class ContentData extends BaseObject\r
+{      \r
+       private $_isPopulated = false;\r
+       private $_isDirty = false;\r
+       \r
+       private $_node;\r
+       private $_property;\r
+       \r
+       private $_mimetype;\r
+       private $_size;\r
+       private $_encoding;     \r
+       private $_url;\r
+       private $_newContent;\r
+       private $_newFileContent;\r
+       \r
+       public function __construct($node, $property, $mimetype=null, $encoding=null, $size=-1)\r
+       {\r
+               $this->_node = $node;\r
+               $this->_property = $property;\r
+               $this->_mimetype = $mimetype;\r
+               $this->_encoding = $encoding;\r
+               if ($size != -1)\r
+               {\r
+                       $this->size = $size;\r
+               }               \r
+               $this->_isPopulated = false;\r
+       }       \r
+       \r
+       public function setPropertyDetails($node, $property)\r
+       {\r
+               $this->_node = $node;\r
+               $this->_property = $property;\r
+       }\r
+       \r
+       public function __toString()\r
+       {\r
+               $this->populateContentData();\r
+       }\r
+       \r
+       public function getNode()\r
+       {\r
+               return $this->_node;\r
+       }\r
+       \r
+       public function getProperty()\r
+       {\r
+               return $this->_property;\r
+       }\r
+       \r
+       public function getIsDirty()\r
+       {\r
+               return $this->_isDirty;\r
+       }\r
+       \r
+       public function getMimetype()\r
+       {\r
+               $this->populateContentData();\r
+               return $this->_mimetype;\r
+       }\r
+       \r
+       public function setMimetype($mimetype)\r
+       {\r
+               $this->populateContentData();\r
+               $this->_mimetype = $mimetype;\r
+       }\r
+       \r
+       public function getSize()\r
+       {\r
+               $this->populateContentData();\r
+               return $this->_size;\r
+       }\r
+       \r
+       public function getEncoding()\r
+       {\r
+               $this->populateContentData();\r
+               return $this->_encoding;\r
+       }\r
+       \r
+       public function setEncoding($encoding)\r
+       {\r
+               $this->populateContentData();\r
+               $this->_encoding = $encoding;\r
+       }\r
+       \r
+       public function getUrl()\r
+       {\r
+               // TODO what should be returned if the content has been updated??\r
+               \r
+               $this->populateContentData();\r
+               $result = null;\r
+               if ($this->_url != null)\r
+               {       \r
+                       $result = $this->_url."?ticket=".$this->_node->session->ticket;\r
+               }\r
+               return $result;\r
+       }\r
+       \r
+       public function getGuestUrl()\r
+       {\r
+               // TODO what should be returned if the content has been updated??\r
+               \r
+               $this->populateContentData();   \r
+               $result = null;\r
+               if ($this->_url != null)\r
+               {       \r
+                       $result = $this->_url."?guest=true";\r
+               }\r
+               return $result;\r
+       }\r
+       \r
+       public function getContent()\r
+       {\r
+               $this->populateContentData();\r
+               \r
+               $result = null;                 \r
+               if ($this->_isDirty == true)\r
+               {\r
+                       if ($this->_newFileContent != null)\r
+                       {\r
+                               $handle = fopen($this->_newFileContent, "rb");\r
+                               $result = stream_get_contents($handle);\r
+                               fclose($handle);        \r
+                       }\r
+                       else if ($this->_newContent != null)\r
+                       {\r
+                               $result = $this->_newContent;   \r
+                       }       \r
+               }\r
+               else\r
+               {\r
+                       if ($this->getUrl() != null)\r
+                       {\r
+                               $handle = fopen($this->getUrl(), "rb");\r
+                               $result = stream_get_contents($handle);\r
+                               fclose($handle);        \r
+                       }\r
+               }\r
+               return $result;\r
+       }\r
+       \r
+       public function setContent($content)\r
+       {\r
+               $this->populateContentData();\r
+               $this->_isDirty = true;\r
+               $this->_newContent = $content;                  \r
+       }\r
+       \r
+       public function writeContentFromFile($fileName)\r
+       {\r
+               $this->populateContentData();\r
+               $this->_isDirty = true;\r
+               $this->_newFileContent = $fileName;             \r
+       }\r
+       \r
+       public function readContentToFile($fileName)\r
+       {\r
+               $handle = fopen($fileName, "wb");\r
+               fwrite($handle, $this->getContent());\r
+               fclose($handle);        \r
+       }\r
+       \r
+       public function onBeforeSave(&$statements, $where)\r
+       {\r
+               if ($this->_isDirty == true)\r
+               {\r
+                       // Check mimetype has been set\r
+                       if ($this->_mimetype == null)\r
+                       {\r
+                               throw new Exception("A mime type for the content property ".$this->_property." on node ".$this->_node->__toString()." must be set");\r
+                       }\r
+                       \r
+                       // If a file has been specified then read content from there\r
+                       //$content = null;\r
+                       if ($this->_newFileContent != null)\r
+                       {\r
+                               // Upload the content to the repository\r
+                               $contentData = upload_file($this->node->session, $this->_newFileContent, $this->_mimetype, $this->_encoding);\r
+                               \r
+                               // Set the content property value\r
+                               $this->addStatement(\r
+                                       $statements, \r
+                                       "update", \r
+                                       array("property" => array(\r
+                                                               "name" => $this->property,\r
+                                                               "isMultiValue" => false,\r
+                                                               "value" => $contentData)) + $where);    \r
+                       }\r
+                       else\r
+                       {\r
+                               // Add the writeContent statement\r
+                               $this->addStatement(\r
+                                               $statements, \r
+                                               "writeContent", \r
+                                               array(\r
+                                                       "property" => $this->_property,\r
+                                                       "content" => $this->_newContent,\r
+                                                       "format" => array(\r
+                                                               "mimetype" => $this->_mimetype,\r
+                                                               "encoding" => $this->_encoding)) + \r
+                                                       $where); \r
+                       } \r
+               }\r
+       }\r
+       \r
+       public function onAfterSave()\r
+       {\r
+               $this->_isDirty = false;\r
+               $this->_isPopulated = false;\r
+               $this->_mimetype = null;\r
+               $this->__size = null;\r
+               $this->__encoding = null;       \r
+               $this->__url = null;\r
+               $this->__newContent = null;\r
+       }\r
+       \r
+       private function populateContentData()\r
+       {\r
+               //echo "isPopulated:".$this->_isPopulated."; node:".$this->_node."; property:".$this->_property."<br>";\r
+               if ($this->_isPopulated == false && $this->_node != null && $this->_property != null && $this->_node->isNewNode == false)\r
+               {                       \r
+                       $result = $this->_node->session->contentService->read( array(\r
+                                                                                                                               "items" => array(\r
+                                                                                                                                       "nodes" => array(\r
+                                                                                                                                               "store" => $this->_node->store->__toArray(),\r
+                                                                                                                                               "uuid" => $this->_node->id)),                   \r
+                                                                                                                               "property" => $this->_property) );\r
+                       if (isset($result->content) == true)\r
+                       {                                                                               \r
+                               if (isset($result->content->length) == true)\r
+                               {                                                                                                                               \r
+                                       $this->_size = $result->content->length;\r
+                               }\r
+                               if (isset($result->content->format->mimetype) == true)\r
+                               {                                                                                                                               \r
+                                       $this->_mimetype = $result->content->format->mimetype;\r
+                               }\r
+                               if (isset($result->content->format->encoding) == true)\r
+                               {\r
+                                       $this->_encoding = $result->content->format->encoding;\r
+                               }\r
+                               if (isset($result->content->url) == true)\r
+                               {\r
+                                       $this->_url = $result->content->url;\r
+                               }\r
+                       }                                                                                                                       \r
+                       \r
+                       $this->_isPopulated = true;\r
+               }\r
+       }\r
+       \r
+       private function addStatement(&$statements, $statement, $body)\r
+       {               \r
+               $result = array();      \r
+               if (array_key_exists($statement, $statements) == true)  \r
+               {\r
+                       $result = $statements[$statement];\r
+               }\r
+               $result[] = $body;\r
+               $statements[$statement] = $result;\r
+       }\r
+}\r
+?>\r
diff --git a/lib/alfresco/Service/Functions.php b/lib/alfresco/Service/Functions.php
new file mode 100755 (executable)
index 0000000..84a014f
--- /dev/null
@@ -0,0 +1,114 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
\r
+ require_once("Repository.php");\r
+ require_once("Session.php");\r
\r
+ /**\r
+  * Uploads a file into content store and returns the content data string which\r
+  * can be used to populate a content property.\r
+  * \r
+  * @param $session the session\r
+  * @param $filePath the file location\r
+  * @return String the content data that can be used to update the content property\r
+  */\r
+ function upload_file($session, $filePath, $mimetype=null, $encoding=null)\r
+ {\r
+       $result = null;\r
+       \r
+       // Check for the existance of the file\r
+       if (file_exists($filePath) == false)\r
+       {\r
+               throw new Exception("The file ".$filePath."does no exist.");\r
+       }\r
+       \r
+       // Get the file name and size\r
+       $fileName = basename($filePath);\r
+       $fileSize = filesize($filePath);\r
+               \r
+       // Get the address and the       \r
+       $host = $session->repository->host; \r
+       $port = $session->repository->port;\r
+       \r
+       // Get the IP address for the target host\r
+       $address = gethostbyname($host);\r
+       \r
+       // Create a TCP/IP socket\r
+       $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);\r
+       if ($socket === false) \r
+       {\r
+           throw new Exception ("socket_create() failed: reason: " . socket_strerror(socket_last_error()));\r
+       }       \r
+       \r
+       // Connect the socket to the repository\r
+       $result = socket_connect($socket, $address, $port);\r
+       if ($result === false) \r
+       {\r
+           throw new Exception("socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)));\r
+       } \r
+       \r
+       // Write the request header onto the socket\r
+       $url = "/alfresco/upload/".urlencode($fileName)."?ticket=".$session->ticket;\r
+       if ($mimetype != null)\r
+       {\r
+               // Add mimetype if specified\r
+               $url .= "&mimetype=".$mimetype;\r
+       }\r
+       if ($encoding != null)\r
+       {\r
+               // Add encoding if specified\r
+               $url .= "&encoding=".$encoding;\r
+       }\r
+       $in = "PUT ".$url." HTTP/1.1\r\n".\r
+                     "Content-Length: ".$fileSize."\r\n".\r
+                     "Host: ".$address.":".$port."\r\n".\r
+                     "Connection: Keep-Alive\r\n".\r
+                     "\r\n";           \r
+       socket_write($socket, $in, strlen($in));\r
+       \r
+       // Write the content found in the file onto the socket\r
+       $handle = fopen($filePath, "r");\r
+       while (feof($handle) == false)\r
+       {\r
+               $content = fread($handle, 1024);\r
+               socket_write($socket, $content, strlen($content));              \r
+       }               \r
+       fclose($handle);\r
+       \r
+       // Read the response\r
+       $recv = socket_read ($socket, 2048, PHP_BINARY_READ);\r
+       $index = strpos($recv, "contentUrl");\r
+       if ($index !== false)\r
+       {\r
+               $result = substr($recv, $index);        \r
+       }\r
+       \r
+       // Close the socket\r
+       socket_close($socket);\r
+               \r
+       return $result;\r
+ } \r
+?>\r
diff --git a/lib/alfresco/Service/Logger/Logger.php b/lib/alfresco/Service/Logger/Logger.php
new file mode 100755 (executable)
index 0000000..f16bac1
--- /dev/null
@@ -0,0 +1,90 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
\r
+ require_once "LoggerConfig.php";\r
\r
+ class Logger\r
+ {     \r
+       private $componentName;\r
+       \r
+       public function __construct($componentName = null)\r
+       {\r
+               $this->componentName = $componentName;\r
+       }       \r
+       \r
+       public function isDebugEnabled()\r
+       {\r
+               return $this->isEnabled(DEBUG);\r
+       }\r
+       \r
+       public function debug($message)\r
+       {\r
+               $this->write(DEBUG, $message);  \r
+       }\r
+       \r
+       public function isWarningEnabled()\r
+       {\r
+               return $this->isEnabled(WARNING);\r
+       }\r
+       \r
+       public function warning($message)\r
+       {\r
+               $this->write(WARNING, $message);        \r
+       }\r
+       \r
+       public function isInformationEnabled()\r
+       {\r
+               return $this->isEnabled(INFORMATION);           \r
+       }\r
+       \r
+       public function information($message)\r
+       {\r
+               $this->write(INFORMATION, $message);    \r
+       }\r
+       \r
+       private function isEnabled($logLevel)\r
+       {\r
+               global $componentLogLevels, $defaultLogLevel;\r
+               \r
+               $logLevels = $defaultLogLevel;\r
+               if ($this->componentName != null && isset($componentLogLevels[$this->componentName]) == true)\r
+               {\r
+                       $logLevels = $componentLogLevels[$this->componentName];\r
+               }\r
+               \r
+               return in_array($logLevel, $logLevels);\r
+       }\r
+       \r
+       private function write($logLevel, $message)\r
+       {\r
+               global $logFile;\r
+               \r
+               $handle = fopen($logFile, "a");\r
+               fwrite($handle, $logLevel." ".date("G:i:s d/m/Y")." - ".$message."\r\n");\r
+               fclose($handle);\r
+       }\r
+ }\r
+?>\r
diff --git a/lib/alfresco/Service/Logger/LoggerConfig.php b/lib/alfresco/Service/Logger/LoggerConfig.php
new file mode 100755 (executable)
index 0000000..566ea5b
--- /dev/null
@@ -0,0 +1,44 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
\r
+define("DEBUG", "Debug");\r
+define("WARNING", "Warning");\r
+define("INFO", "Information");\r
+\r
+$debugLevel = array(DEBUG, WARNING, INFO);\r
+$warningLevel = array(WARNING, INFO);\r
+$infoLevel = array(INFO);\r
+$noneLevel = array();\r
+\r
+$defaultLogLevel = $infoLevel;\r
+\r
+$logFile = "c:/work/AlfrescoPHPLog.txt"; \r
+$componentLogLevels = array(\r
+                                                               "integration.mediawiki.ExternalStoreAlfresco" => $debugLevel\r
+                                                       );\r
\r
\r
+?>\r
diff --git a/lib/alfresco/Service/NamespaceMap.php b/lib/alfresco/Service/NamespaceMap.php
new file mode 100755 (executable)
index 0000000..9ca8a58
--- /dev/null
@@ -0,0 +1,121 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+class NamespaceMap\r
+{\r
+       const DELIMITER = "_";\r
+       \r
+       private $namespaceMap = array(\r
+               "d" => "http://www.alfresco.org/model/dictionary/1.0",\r
+               "sys" => "http://www.alfresco.org/model/system/1.0",\r
+               "cm" => "http://www.alfresco.org/model/content/1.0",\r
+               "app" => "http://www.alfresco.org/model/application/1.0",\r
+               "bpm" => "http://www.alfresco.org/model/bpm/1.0",\r
+               "wf" => "http://www.alfresco.org/model/workflow/1.0",\r
+               "fm" => "http://www.alfresco.org/model/forum/1.0",\r
+               "view" => "http://www.alfresco.org/view/repository/1.0",\r
+               "security" => "http://www.alfresco.org/model/security/1.0",\r
+               "wcm" => "http://www.alfresco.org/model/wcmmodel/1.0",\r
+               "wca" => "http://www.alfresco.org/model/wcmappmodel/1.0");\r
+       \r
+       public function isShortName($shortName)\r
+       {\r
+               return ($shortName != $this->getFullName($shortName));\r
+       }\r
+               \r
+       public function getFullName($shortName)\r
+       {\r
+               $result = $shortName;\r
+               \r
+               $index = strpos($shortName, NamespaceMap::DELIMITER);\r
+               if ($index !== false)\r
+               {\r
+                       $prefix = substr($shortName, 0, $index);\r
+                                               \r
+                       if (isset($this->namespaceMap[$prefix]) == true)        \r
+                       {\r
+                               $url = $this->namespaceMap[$prefix];\r
+                               $name = substr($shortName, $index+1);\r
+                               $name = str_replace("_", "-", $name);\r
+                               if ($name != null && strlen($name) != 0)\r
+                               {\r
+                                       $result = "{".$url."}".$name;\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               return $result;\r
+       }\r
+       \r
+       public function getFullNames($fullNames)\r
+       {\r
+               $result = array();\r
+               \r
+               foreach ($fullNames as $fullName)\r
+               {\r
+                       $result[] = $this->getFullName($fullName);                      \r
+               }               \r
+               return $result;\r
+       }\r
+       \r
+       public function getShortName($fullName)\r
+       {\r
+               $result = $fullName;\r
+               \r
+               $index = strpos($fullName, "}");\r
+               if ($index !== false)\r
+               {\r
+                       $url = substr($fullName, 1, $index-1);\r
+                       $prefix = $this->lookupPrefix($url);\r
+                       if ($prefix != null)\r
+                       {\r
+                               $name = substr($fullName, $index+1);\r
+                               if ($name != null && strlen($name) != 0)\r
+                               {                                       \r
+                                       $name = str_replace("-", "_", $name);                   \r
+                                       $result = $prefix.NamespaceMap::DELIMITER.$name;\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               return $result; \r
+       }\r
+       \r
+       private function lookupPrefix($value)\r
+       {\r
+               $result = null;\r
+               foreach($this->namespaceMap as $prefix => $url)\r
+               {\r
+                       if ($url == $value)\r
+                       {\r
+                               $result = $prefix;\r
+                       }\r
+               }\r
+               return $result;\r
+       } \r
+}\r
+\r
+?>\r
diff --git a/lib/alfresco/Service/Node.php b/lib/alfresco/Service/Node.php
new file mode 100755 (executable)
index 0000000..4b6de64
--- /dev/null
@@ -0,0 +1,815 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+require_once 'Store.php';\r
+require_once 'ChildAssociation.php';\r
+require_once 'Association.php';\r
+require_once 'NamespaceMap.php';\r
+require_once 'ContentData.php';\r
+require_once 'VersionHistory.php';\r
+require_once 'Version.php';\r
+\r
+class Node extends BaseObject \r
+{\r
+       private $_session;\r
+       private $_store;\r
+       private $_id;\r
+       private $_type;\r
+       private $_aspects;\r
+       private $_properties;\r
+       private $_children;\r
+       private $_parents;\r
+       private $_primaryParent;\r
+       private $_isNewNode;\r
+       private $_associations;\r
+       private $_versionHistory;       \r
+       private $origionalProperties;\r
+       private $addedAspects;\r
+       private $removedAspects;\r
+       private $addedChildren;\r
+       private $addedParents;\r
+       private $addedAssociations;\r
+       private $removedAssociations;\r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       public function __construct($session, $store, $id) \r
+       {\r
+               $this->_session = $session;\r
+               $this->_store = $store;\r
+               $this->_id = $id;       \r
+               $this->_isNewNode = false;\r
+               $this->addedChildren = array();\r
+               $this->addedParents = array();\r
+               $this->addedAssociations = array();\r
+       }\r
+\r
+    /**\r
+     * Util method to create a node from a web service node structure.\r
+     */\r
+       public static function createFromWebServiceData($session, $webServiceNode) \r
+       {\r
+               $scheme = $webServiceNode->reference->store->scheme;\r
+               $address = $webServiceNode->reference->store->address;\r
+               $id = $webServiceNode->reference->uuid;\r
+\r
+               $store = $session->getStore($address, $scheme);\r
+               $node = $session->getNode($store, $id);\r
+       $node->populateFromWebServiceNode($webServiceNode);\r
+       \r
+               return $node;\r
+       }\r
+       \r
+       public function setPropertyValues($properties)\r
+       {\r
+               // Check that the properties of the node have been populated\r
+               $this->populateProperties();\r
+               \r
+               // Set the property values\r
+               foreach ($properties as $name=>$value)\r
+               {\r
+                       $name = $this->expandToFullName($name);\r
+                       $this->_properties[$name] = $value;\r
+               }               \r
+       }\r
+       \r
+       public function setContent($property, $mimetype=null, $encoding=null, $content=null)\r
+       {\r
+               list($property) = $this->_session->namespaceMap->getFullNames(array($property));\r
+               $contentData = new ContentData($this, $property, $mimetype, $encoding);\r
+               if ($content != null)\r
+               {\r
+                       $contentData->content = $content;\r
+               }\r
+               $this->_properties[$property] = $contentData;\r
+               \r
+               return $contentData;\r
+       }\r
+       \r
+       public function hasAspect($aspect)\r
+       {\r
+               list($aspect) = $this->_session->namespaceMap->getFullNames(array($aspect));\r
+               $this->populateProperties();\r
+               return in_array($aspect, $this->_aspects);\r
+       }\r
+       \r
+       public function addAspect($aspect, $properties = null)\r
+       {\r
+               list($aspect) = $this->_session->namespaceMap->getFullNames(array($aspect));            \r
+               $this->populateProperties();\r
+               \r
+               if (in_array($aspect, $this->_aspects) == false)\r
+               {\r
+                       $this->_aspects[] = $aspect;\r
+                       if ($properties != null)\r
+                       {\r
+                               foreach ($properties as $name=>$value)\r
+                               {\r
+                                       $name = $this->_session->namespaceMap->getFullName($name);\r
+                                       $this->_properties[$name] = $value;\r
+                               }\r
+                       }\r
+                       \r
+                       $this->remove_array_value($aspect, $this->removedAspects);\r
+                       $this->addedAspects[] = $aspect;        \r
+               }                       \r
+       }\r
+       \r
+       public function removeAspect($aspect)\r
+       {\r
+               list($aspect) = $this->_session->namespaceMap->getFullNames(array($aspect));\r
+               $this->populateProperties();    \r
+               \r
+               if (in_array($aspect, $this->_aspects) == true)\r
+               {               \r
+                       $this->remove_array_value($aspect, $this->_aspects);\r
+                       $this->remove_array_value($aspect, $this->addedAspects);        \r
+                       $this->removedAspects[] = $aspect;\r
+               }\r
+       }\r
+       \r
+       public function createChild($type, $associationType, $associationName)\r
+       {               \r
+               list($type, $associationType, $associationName) = $this->_session->namespaceMap->getFullNames(array($type, $associationType, $associationName));\r
+               \r
+               $id = $this->_session->nextSessionId();\r
+               $newNode = new Node($this->_session, $this->_store, $id);       \r
+               $childAssociation = new ChildAssociation($this, $newNode, $associationType, $associationName, true);\r
+               \r
+               $newNode->_isNewNode = true;\r
+               \r
+               $newNode->_properties = array();\r
+               $newNode->_aspects = array();\r
+               $newNode->_properties = array();\r
+               $newNode->_children = array();\r
+               $newNode->origionalProperties = array();\r
+               $newNode->addedAspects = array();\r
+               $newNode->removedAspects = array();\r
+               \r
+               $newNode->_type = $type;\r
+               $newNode->_parents = array(); \r
+               $newNode->addedParents = array($this->__toString() => $childAssociation);\r
+               $newNode->_primaryParent = $this;\r
+               \r
+               $this->addedChildren[$newNode->__toString()] = $childAssociation;               \r
+               \r
+               $this->_session->addNode($newNode);\r
+               \r
+               return $newNode;                                        \r
+       }\r
+       \r
+       public function addChild($node, $associationType, $associationName)\r
+       {\r
+               list($associationType, $associationName) = $this->_session->namespaceMap->getFullNames(array($associationType, $associationName));\r
+               \r
+               $childAssociation = new ChildAssociation($this, $node, $associationType, $associationName, false);\r
+               $this->addedChildren[$node->__toString()] = $childAssociation;\r
+               $node->addedParents[$this->__toString()] = $childAssociation;\r
+       }\r
+       \r
+       public function removeChild($childAssociation)\r
+       {\r
+               \r
+       }\r
+       \r
+       public function addAssociation($to, $associationType)\r
+       {\r
+               list($associationType) = $this->_session->namespaceMap->getFullNames(array($associationType));\r
+               \r
+               $association = new Association($this, $to, $associationType);\r
+               $this->addedAssociations[$to->__toString()] = $association;             \r
+       }\r
+       \r
+       public function removeAssociation($association)\r
+       {\r
+               \r
+       }\r
+       \r
+       public function createVersion($description=null, $major=false)\r
+       {\r
+               // We can only create a version if there are no outstanding changes for this node\r
+               if ($this->isDirty() == true)\r
+               {\r
+                       throw new Exception("You must save any outstanding modifications before a new version can be created.");\r
+               }\r
+               \r
+               // TODO implement major flag ...\r
+               \r
+               $client = WebServiceFactory::getAuthoringService($this->_session->repository->connectionUrl, $this->_session->ticket);\r
+               $result = $client->createVersion(\r
+                       array("items" => array("nodes" => $this->__toArray()),\r
+                             "comments" => array("name" => "description", "value" => $description),\r
+                             "versionChildren" => false));                     \r
+                             \r
+               // Clear the properties and aspects\r
+               $this->_properties = null;\r
+               $this->_aspects = null;                                                               \r
+                             \r
+               // Get the version details \r
+               // TODO get some of the other details too ...\r
+               $versionId = $result->createVersionReturn->versions->id->uuid;\r
+               $versionStoreScheme = $result->createVersionReturn->versions->id->store->scheme;\r
+               $versionStoreAddress = $result->createVersionReturn->versions->id->store->address;              \r
+               \r
+               // Create the version object to return        \r
+               return new Version($this->_session, new Store($this->_session, $versionStoreAddress, $versionStoreScheme), $versionId);                                       \r
+       }\r
+       \r
+       private function isDirty()\r
+       {\r
+               $result = true;\r
+               if ($this->_isNewNode == false &&\r
+                       count($this->getModifiedProperties()) == 0 &&\r
+                       ($this->addedAspects == null || count($this->addedAspects) == 0) &&\r
+                       ($this->removedAssociations == null || count($this->removedAssociations) == 0) &&\r
+                       ($this->addedChildren == null || count($this->addedChildren) == 0) &&\r
+                       ($this->addedAssociations == null || count($this->addedAssociations) == 0))\r
+               {\r
+                       $result = false;\r
+               }\r
+               return $result;\r
+       }\r
+       \r
+       public function __get($name)\r
+       {\r
+               $fullName = $this->_session->namespaceMap->getFullName($name);\r
+               if ($fullName != $name)\r
+               {\r
+                       $this->populateProperties();    \r
+                       if (array_key_exists($fullName, $this->_properties) == true)\r
+                       {\r
+                               return $this->_properties[$fullName];\r
+                       }       \r
+                       else\r
+                       {       \r
+                               return null;    \r
+                       }       \r
+               }       \r
+               else\r
+               {\r
+                       return parent::__get($name);\r
+               }\r
+       }\r
+       \r
+       public function __set($name, $value)\r
+       {\r
+               $fullName = $this->_session->namespaceMap->getFullName($name);\r
+               if ($fullName != $name)\r
+               {\r
+                       $this->populateProperties();\r
+                       $this->_properties[$fullName] = $value;\r
+                       \r
+                       // Ensure that the node and property details are stored on the contentData object\r
+                       if ($value instanceof ContentData)\r
+                       {\r
+                               $value->setPropertyDetails($this, $fullName);   \r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       parent::__set($name, $value);\r
+               }\r
+       }\r
+\r
+    /**\r
+     * toString method.  Returns node as a node reference style string.\r
+     */\r
+       public function __toString() \r
+       {\r
+               return Node::__toNodeRef($this->_store, $this->id);\r
+       }\r
+       \r
+       public static function __toNodeRef($store, $id)\r
+       {\r
+               return $store->scheme . "://" . $store->address . "/" . $id;    \r
+       }\r
+       \r
+       public function __toArray()\r
+       {\r
+               return array("store" => $this->_store->__toArray(),\r
+                                        "uuid" => $this->_id);\r
+       }\r
+  \r
+    public function getSession()\r
+    {\r
+       return $this->_session;\r
+    }\r
+  \r
+       public function getStore() \r
+       {\r
+               return $this->_store;\r
+       }\r
+\r
+       public function getId() \r
+       {\r
+               return $this->_id;\r
+       }\r
+       \r
+       public function getIsNewNode()\r
+       {\r
+               return $this->_isNewNode;\r
+       }\r
+\r
+       public function getType() \r
+       {\r
+               $this->populateProperties();    \r
+               return $this->_type;\r
+       }\r
+\r
+       public function getAspects() \r
+       {\r
+               $this->populateProperties();\r
+               return $this->_aspects;\r
+       }\r
+       \r
+       public function getProperties()\r
+       {\r
+               $this->populateProperties();\r
+               return $this->_properties;\r
+       }\r
+       \r
+       public function setProperties($properties)\r
+       {\r
+               $this->populateProperties();\r
+               $this->_properties = $properties;       \r
+       }\r
+       \r
+       /**\r
+        * Accessor for the versionHistory property.\r
+        * \r
+        * @return      VersionHistory  the versionHistory for the node, null is none\r
+        */\r
+       public function getVersionHistory()\r
+       {\r
+               if ($this->_versionHistory == null)\r
+               {\r
+                       $this->_versionHistory = new VersionHistory($this);\r
+               }\r
+               return $this->_versionHistory;\r
+       }\r
+       \r
+       public function getChildren()\r
+       {\r
+               if ($this->_children == null)\r
+               {\r
+                       $this->populateChildren();\r
+               }\r
+               return $this->_children + $this->addedChildren;\r
+       }\r
+       \r
+       public function getParents()\r
+       {\r
+               if ($this->_parents == null)\r
+               {\r
+                       $this->populateParents();\r
+               }\r
+               return $this->_parents + $this->addedParents;\r
+       }\r
+       \r
+       public function getPrimaryParent()\r
+       {\r
+               if ($this->_primaryParent == null)\r
+               {\r
+                       $this->populateParents();\r
+               }\r
+               return $this->_primaryParent;   \r
+       }\r
+       \r
+       public function getAssociations()\r
+       {\r
+               if ($this->_associations == null)\r
+               {\r
+                       $this->populateAssociations();\r
+               }\r
+               return $this->_associations + $this->addedAssociations;\r
+       }\r
+       \r
+       /** Methods used to populate node details from repository */\r
+       \r
+       private function populateProperties()\r
+       {\r
+               if ($this->_isNewNode == false && $this->_properties == null)\r
+               {\r
+                       $result = $this->_session->repositoryService->get(array (\r
+                                       "where" => array (\r
+                                               "nodes" => array(\r
+                                                       "store" => $this->_store->__toArray(),\r
+                                                       "uuid" => $this->_id))));       \r
+                                                       \r
+                       $this->populateFromWebServiceNode($result->getReturn);\r
+               }       \r
+       }\r
+       \r
+       private function populateFromWebServiceNode($webServiceNode)\r
+       {\r
+               $this->_type = $webServiceNode->type;\r
+\r
+               // Get the aspects\r
+               $this->_aspects = array();\r
+               $aspects = $webServiceNode->aspects;\r
+               if (is_array($aspects) == true)\r
+               {\r
+                       foreach ($aspects as $aspect)\r
+                       {\r
+                               $this->_aspects[] = $aspect;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $this->_aspects[] = $aspects;   \r
+               }               \r
+\r
+               // Set the property values\r
+               // NOTE: do we need to be concerned with identifying whether this is an array or not when there is\r
+               //       only one property on a node\r
+               $this->_properties = array();\r
+               foreach ($webServiceNode->properties as $propertyDetails) \r
+               {\r
+                       $name = $propertyDetails->name;\r
+                       $isMultiValue = $propertyDetails->isMultiValue;\r
+                       $value = null;\r
+                       if ($isMultiValue == false)\r
+                       {\r
+                               $value = $propertyDetails->value;\r
+                               if ($this->isContentData($value) == true)\r
+                               {\r
+                                       $value = new ContentData($this, $name);\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $value = $propertyDetails->values;                              \r
+                       }\r
+                       $this->_properties[$name] = $value;\r
+                                               \r
+               }       \r
+               \r
+               $this->origionalProperties = $this->_properties;        \r
+               $this->addedAspects = array();\r
+               $this->removedAspects = array();\r
+               \r
+       }       \r
+       \r
+       private function populateChildren()\r
+       {\r
+               // TODO should do some sort of limited pull here        \r
+               $result = $this->_session->repositoryService->queryChildren(array("node" => $this->__toArray()));               \r
+               $resultSet = $result->queryReturn->resultSet;\r
+               \r
+               $children = array();\r
+               $map = $this->resultSetToMap($resultSet);\r
+               foreach($map as $value)\r
+               {\r
+                       $id = $value["{http://www.alfresco.org/model/system/1.0}node-uuid"];\r
+                       $store_scheme = $value["{http://www.alfresco.org/model/system/1.0}store-protocol"];\r
+                       $store_address = $value["{http://www.alfresco.org/model/system/1.0}store-identifier"];\r
+                       $assoc_type = $value["associationType"];\r
+                       $assoc_name = $value["associationName"];\r
+                       $isPrimary = $value["isPrimary"];\r
+                       $nthSibling = $value["nthSibling"];\r
+                       \r
+                       $child = $this->_session->getNode(new Store($this->_session, $store_address, $store_scheme), $id);\r
+                       $children[$child->__toString()] = new ChildAssociation($this, $child, $assoc_type, $assoc_name, $isPrimary, $nthSibling);\r
+               }\r
+               \r
+               $this->_children = $children;   \r
+       }\r
+       \r
+       private function populateAssociations()\r
+       {\r
+               // TODO should do some sort of limited pull here\r
+               $result = $this->_session->repositoryService->queryAssociated(array("node" => $this->__toArray(),\r
+                                                                                                                                                       "association" => array("associationType" => null,\r
+                                                                                                                                                                                                  "direction" => null)));\r
+               $resultSet = $result->queryReturn->resultSet;\r
+               \r
+               $associations = array();\r
+               $map = $this->resultSetToMap($resultSet);\r
+               foreach($map as $value)\r
+               {\r
+                       $id = $value["{http://www.alfresco.org/model/system/1.0}node-uuid"];\r
+                       $store_scheme = $value["{http://www.alfresco.org/model/system/1.0}store-protocol"];\r
+                       $store_address = $value["{http://www.alfresco.org/model/system/1.0}store-identifier"];\r
+                       $assoc_type = $value["associationType"];\r
+                       \r
+                       $to = $this->_session->getNode(new Store($this->_session, $store_address, $store_scheme), $id);\r
+                       $associations[$to->__toString()] = new Association($this, $to, $assoc_type);\r
+               }\r
+               \r
+               $this->_associations = $associations;   \r
+       }\r
+       \r
+       private function populateParents()\r
+       {               \r
+               // TODO should do some sort of limited pull here\r
+               $result = $this->_session->repositoryService->queryParents(array("node" => $this->__toArray()));                \r
+               $resultSet = $result->queryReturn->resultSet;\r
+               \r
+               $parents = array();\r
+               $map = $this->resultSetToMap($resultSet);\r
+               foreach($map as $value)\r
+               {\r
+                       $id = $value["{http://www.alfresco.org/model/system/1.0}node-uuid"];\r
+                       $store_scheme = $value["{http://www.alfresco.org/model/system/1.0}store-protocol"];\r
+                       $store_address = $value["{http://www.alfresco.org/model/system/1.0}store-identifier"];\r
+                       $assoc_type = $value["associationType"];\r
+                       $assoc_name = $value["associationName"];\r
+                       $isPrimary = $value["isPrimary"];\r
+                       $nthSibling = $value["nthSibling"];\r
+                       \r
+                       $parent = $this->_session->getNode(new Store($this->_session, $store_address, $store_scheme), $id);\r
+                       if ($isPrimary == "true" or $isPrimary == true)\r
+                       {\r
+                               $this->_primaryParent = $parent;\r
+                       }\r
+                       $parents[$parent->__toString()] = new ChildAssociation($parent, $this, $assoc_type, $assoc_name, $isPrimary, $nthSibling);\r
+               }\r
+               \r
+               $this->_parents = $parents;\r
+       }\r
+       \r
+       public function onBeforeSave(&$statements)\r
+       {\r
+               if ($this->_isNewNode == true)\r
+               {\r
+                       $childAssociation = $this->addedParents[$this->_primaryParent->__toString()];           \r
+                       \r
+                       $parentArray = array();\r
+                       $parent = $this->_primaryParent;\r
+                       if ($parent->_isNewNode == true)\r
+                       {\r
+                               $parentArray["parent_id"] = $parent->id;\r
+                               $parentArray["associationType"] = $childAssociation->type;\r
+                               $parentArray["childName"] = $childAssociation->name;\r
+                   }\r
+                   else\r
+                   {\r
+                       $parentArray["parent"] = array(\r
+                                                                                       "store" => $this->_store->__toArray(),\r
+                                                                                       "uuid" => $this->_primaryParent->_id,\r
+                                                                                       "associationType" => $childAssociation->type,\r
+                                                                                       "childName" => $childAssociation->name);\r
+                   }\r
+                               \r
+                       $this->addStatement($statements, "create",\r
+                                                               array("id" => $this->_id) +\r
+                                                               $parentArray +\r
+                                                               array(  \r
+                                                                       "type" => $this->_type,\r
+                                                                       "property" => $this->getPropertyArray($this->_properties)));    \r
+               }\r
+               else\r
+               {\r
+                       // Add the update statement for the modified properties\r
+                       $modifiedProperties = $this->getModifiedProperties();           \r
+                       if (count($modifiedProperties) != 0)\r
+                       {                                       \r
+                               $this->addStatement($statements, "update", array("property" => $this->getPropertyArray($modifiedProperties)) + $this->getWhereArray());\r
+                       }\r
+                       \r
+                       // TODO deal with any deleted properties\r
+               }\r
+               \r
+               // Update any modified content properties\r
+               if ($this->_properties != null)\r
+               {\r
+                       foreach($this->_properties as $name=>$value)\r
+                       {\r
+                               if (($value instanceof ContentData) && $value->isDirty == true)\r
+                               {\r
+                                       $value->onBeforeSave($statements, $this->getWhereArray());\r
+                               }\r
+                       }\r
+               }               \r
+               \r
+               // Add the addAspect statements\r
+               if ($this->addedAspects != null)\r
+               {\r
+                       foreach($this->addedAspects as $aspect)\r
+                       {\r
+                               $this->addStatement($statements, "addAspect", array("aspect" => $aspect) + $this->getWhereArray());\r
+                       }\r
+               }\r
+               \r
+               // Add the removeAspect\r
+               if ($this->removedAspects != null)\r
+               {\r
+                       foreach($this->removedAspects as $aspect)\r
+                       {\r
+                               $this->addStatement($statements, "removeAspect", array("aspect" => $aspect) + $this->getWhereArray());\r
+                       }\r
+               }\r
+               \r
+               // Add non primary children\r
+               foreach($this->addedChildren as $childAssociation)\r
+               {\r
+                       if ($childAssociation->isPrimary == false)\r
+                       {\r
+                               \r
+                               $assocDetails = array("associationType" => $childAssociation->type, "childName" => $childAssociation->name);\r
+                               \r
+                               $temp = array();\r
+                               if ($childAssociation->child->_isNewNode == true)\r
+                               {\r
+                                       $temp["to_id"] = $childAssociation->child->_id;\r
+                                       $temp = $temp + $assocDetails;\r
+                               }       \r
+                               else\r
+                               {\r
+                                       $temp["to"] = array(\r
+                                                                       "store" => $this->_store->__toArray(),\r
+                                                                       "uuid" => $childAssociation->child->_id) + \r
+                                                                       $assocDetails;  \r
+                               }\r
+                               $temp = $temp + $this->getWhereArray();\r
+                               $this->addStatement($statements, "addChild", $temp);\r
+                       }\r
+               }\r
+               \r
+               // Add associations\r
+               foreach($this->addedAssociations as $association)\r
+               {\r
+                       $temp = array("association" => $association->type);\r
+                       $temp = $temp + $this->getPredicateArray("from", $this) + $this->getPredicateArray("to", $association->to);\r
+                       $this->addStatement($statements, "createAssociation", $temp);\r
+               }\r
+       }\r
+       \r
+       private function addStatement(&$statements, $statement, $body)\r
+       {               \r
+               $result = array();      \r
+               if (array_key_exists($statement, $statements) == true)  \r
+               {\r
+                       $result = $statements[$statement];\r
+               }\r
+               $result[] = $body;\r
+               $statements[$statement] = $result;\r
+       }\r
+       \r
+       private function getWhereArray()\r
+       {\r
+               return $this->getPredicateArray("where", $this);\r
+       }\r
+       \r
+       private function getPredicateArray($label, $node)\r
+       {\r
+               if ($node->_isNewNode == true)\r
+               {\r
+                       return array($label."_id" => $node->_id);       \r
+               }\r
+               else\r
+               {\r
+                       return array(\r
+                                       $label => array(\r
+                                                "nodes" => $node->__toArray()\r
+                                                ));                                             \r
+               }       \r
+       }\r
+       \r
+       private function getPropertyArray($properties)\r
+       {\r
+               $result = array();\r
+               foreach ($properties as $name=>$value)\r
+               {       \r
+                       // Ignore content properties\r
+                       if (($value instanceof ContentData) == false)\r
+                       {\r
+                               // TODO need to support multi values\r
+                               $result[] = array(\r
+                                                               "name" => $name,\r
+                                                               "isMultiValue" => false,\r
+                                                               "value" => $value);\r
+                       }\r
+               }\r
+               return $result;\r
+       }\r
+       \r
+       private function getModifiedProperties()\r
+       {\r
+               $modified = $this->_properties;\r
+               $origional = $this->origionalProperties;\r
+               $result = array();\r
+               if ($modified != null)\r
+               {\r
+                       foreach ($modified as $key=>$value)\r
+                       {\r
+                               // Ignore content properties\r
+                               if (($value instanceof ContentData) == false)\r
+                               {\r
+                                       if (array_key_exists($key, $origional) == true)\r
+                                       {\r
+                                               // Check to see if the value have been modified\r
+                                               if ($value != $origional[$key])\r
+                                               {\r
+                                                       $result[$key] = $value;\r
+                                               }\r
+                                       }       \r
+                                       else\r
+                                       {                       \r
+                                               $result[$key] = $value;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               return $result;\r
+       }\r
+       \r
+       public function onAfterSave($idMap)\r
+       {\r
+               if (array_key_exists($this->_id, $idMap ) == true)\r
+               {\r
+                       $uuid = $idMap[$this->_id];\r
+                       if ($uuid != null)\r
+                       {\r
+                               $this->_id = $uuid;\r
+                       }\r
+               }\r
+               \r
+               if ($this->_isNewNode == true)\r
+               {\r
+                       $this->_isNewNode = false;\r
+                       \r
+                       // Clear the properties and aspect \r
+                       $this->_properties = null;\r
+                       $this->_aspects = null;\r
+               }\r
+               \r
+               // Update any modified content properties\r
+               if ($this->_properties != null)\r
+               {\r
+                       foreach($this->_properties as $name=>$value)\r
+                       {\r
+                               if (($value instanceof ContentData) && $value->isDirty == true)\r
+                               {\r
+                                       $value->onAfterSave();\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               $this->origionalProperties = $this->_properties;\r
+               \r
+               if ($this->_aspects != null)\r
+               {\r
+                       // Calculate the updated aspect list\r
+                       if ($this->addedAspects != null)\r
+                       {                       \r
+                               $this->_aspects = $this->_aspects + $this->addedAspects;\r
+                       }\r
+                       if ($this->removedAspects != null)\r
+                       {\r
+                               foreach ($this->_aspects as $aspect)\r
+                               {\r
+                                       if (in_array($aspect, $this->removedAspects) == true)\r
+                                       {                                       \r
+                                               $this->remove_array_value($aspect, $this->_aspects);\r
+                                       }\r
+                               }\r
+                       }\r
+               } \r
+               $this->addedAspects = array();\r
+               $this->removedAspects = array();\r
+               \r
+               if ($this->_parents != null)\r
+               {\r
+                       $this->_parents = $this->_parents + $this->addedParents;\r
+               }\r
+               $this->addedParents = array();\r
+               \r
+               if ($this->_children != null)\r
+               {\r
+                       $this->_children = $this->_children + $this->addedChildren;\r
+               }\r
+               $this->addedChildren = array();         \r
+               \r
+               if ($this->_associations != null)\r
+               {\r
+                       $this->_associations = $this->_associations + $this->addedAssociations;\r
+               }\r
+               $this->addedAssociations = array();\r
+       }\r
+}\r
+?>
\ No newline at end of file
diff --git a/lib/alfresco/Service/Repository.php b/lib/alfresco/Service/Repository.php
new file mode 100755 (executable)
index 0000000..edc9fe2
--- /dev/null
@@ -0,0 +1,133 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+require_once 'WebService/WebServiceFactory.php';\r
+require_once 'BaseObject.php';\r
+\r
+if (isset($_SESSION) == false)\r
+{\r
+   // Start the session\r
+   session_start();\r
+}   \r
\r
+class Al_Repository extends BaseObject  // Moodle\r
+{\r
+       private $_connectionUrl;        \r
+       private $_host;\r
+       private $_port;\r
+\r
+       public function __construct($connectionUrl="http://localhost:8080/alfresco/api")\r
+       {\r
+               $this->_connectionUrl = $connectionUrl;                 \r
+               $parts = parse_url($connectionUrl);\r
+               $this->_host = $parts["host"];\r
+               $this->_port = $parts["port"];\r
+       }\r
+       \r
+       public function getConnectionUrl()\r
+       {\r
+               return $this->_connectionUrl;\r
+       }\r
+       \r
+       public function getHost()\r
+       {\r
+               return $this->_host;    \r
+       }\r
+       \r
+       public function getPort()\r
+       {\r
+               return $this->_port;\r
+       }\r
+       \r
+       public function authenticate($userName, $password)\r
+       {\r
+               // TODO need to handle exceptions!\r
+               \r
+               $authenticationService = WebServiceFactory::getAuthenticationService($this->_connectionUrl);\r
+               $result = $authenticationService->startSession(array (\r
+                       "username" => $userName,\r
+                       "password" => $password\r
+               ));\r
+               \r
+               // Get the ticket and sessionId\r
+               $ticket = $result->startSessionReturn->ticket;\r
+               $sessionId = $result->startSessionReturn->sessionid;\r
+               \r
+               // Store the session id for later use\r
+               if ($sessionId != null)\r
+               {\r
+         $sessionIds = null;\r
+         if (isset($_SESSION["sessionIds"]) == false)\r
+                       {\r
+            $sessionIds = array();\r
+         }\r
+         else\r
+         {\r
+            $sessionIds = $_SESSION["sessionIds"];\r
+         }\r
+         $sessionIds[$ticket] = $sessionId;\r
+         $_SESSION["sessionIds"] = $sessionIds;\r
+               }\r
+               \r
+               return $ticket;\r
+       }\r
+       \r
+       public function createSession($ticket=null)\r
+       {\r
+               $session = null;\r
+               \r
+               if ($ticket == null)\r
+               {\r
+                       // TODO get ticket from some well known location ie: the $_SESSION\r
+               }       \r
+               else\r
+               {\r
+                       // TODO would be nice to be able to check that the ticket is still valid!\r
+                       \r
+                       // Create new session\r
+                       $session = new Session($this, $ticket); \r
+               }\r
+               \r
+               return $session;\r
+       }\r
+       \r
+       /**\r
+        * For a given ticket, returns the realated session id, null if one can not be found.\r
+        */\r
+       public static function getSessionId($ticket)\r
+       {\r
+      $result = null;\r
+      if (isset($_SESSION["sessionIds"]) == true)\r
+      {\r
+         $result = $_SESSION["sessionIds"][$ticket];\r
+      }\r
+      return $result;\r
+\r
+       }\r
+\r
+}\r
\r
+ ?>\r
diff --git a/lib/alfresco/Service/Session.php b/lib/alfresco/Service/Session.php
new file mode 100755 (executable)
index 0000000..4baf57c
--- /dev/null
@@ -0,0 +1,277 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
\r
+require_once 'Store.php';\r
+require_once 'Node.php';\r
+require_once 'WebService/WebServiceFactory.php';\r
+\r
+class Session extends BaseObject\r
+{\r
+       public $authenticationService;\r
+       public $repositoryService;\r
+       public $contentService;\r
+\r
+       private $_repository;\r
+       private $_ticket;\r
+       private $_stores;\r
+       private $_namespaceMap;\r
+       \r
+       private $nodeCache;\r
+       private $idCount = 0;\r
+\r
+    /**\r
+     * Constructor\r
+     * \r
+     * @param userName the user name\r
+     * @param ticket the currenlty authenticated users ticket\r
+     */\r
+       public function __construct($repository, $ticket)  \r
+       {\r
+               $this->nodeCache = array();\r
+               \r
+               $this->_repository = $repository;\r
+               $this->_ticket = $ticket;\r
+               \r
+               $this->repositoryService = WebServiceFactory::getRepositoryService($this->_repository->connectionUrl, $this->_ticket);\r
+               $this->contentService = WebServiceFactory::getContentService($this->_repository->connectionUrl, $this->_ticket);\r
+       }\r
+       \r
+       /**\r
+        * Creates a new store in the current respository\r
+        * \r
+        * @param $address the address of the new store\r
+        * @param $scheme the scheme of the new store, default value of 'workspace'\r
+        * @return Store the new store\r
+        */\r
+       public function createStore($address, $scheme="workspace")\r
+       {\r
+               // Create the store\r
+               $result = $this->repositoryService->createStore(array(\r
+                                                                                                       "scheme" => $scheme,\r
+                                                                                                       "address" => $address));\r
+               $store = new Store($this, $result->createStoreReturn->address, $result->createStoreReturn->scheme);                                                                                     \r
+               \r
+               // Add to the cached list if its been populated\r
+               if (isset($this->_stores) == true)\r
+               {\r
+                       $this->_stores[] = $store;\r
+               }       \r
+               \r
+               // Return the newly created store\r
+               return $store;\r
+       }\r
+       \r
+       /**\r
+        * Get the store\r
+        * \r
+        * @param $address the address of the store\r
+        * @param $scheme the scheme of the store.  The default it 'workspace'\r
+        * @return Store the store\r
+        */\r
+       public function getStore($address, $scheme="workspace")\r
+       {\r
+               return new Store($this, $address, $scheme);     \r
+       }\r
+       \r
+       /**\r
+        * Get the store from it string representation (eg: workspace://SpacesStore)\r
+        * \r
+        * @param $value the stores string representation\r
+        * @return Store the store\r
+        */\r
+       public function getStoreFromString($value)\r
+       {\r
+               list($scheme, $address) = split("://", $value);\r
+       return new Store($this, $address, $scheme);             \r
+       }       \r
+       \r
+       public function getNode($store, $id)\r
+    {\r
+       $node = $this->getNodeImpl($store, $id);\r
+       if ($node == null)\r
+       {\r
+               $node = new Node($this, $store, $id);\r
+               $this->addNode($node);\r
+       }               \r
+       return $node;\r
+    }\r
+    \r
+    public function getNodeFromString($value)\r
+    {\r
+       // TODO\r
+       throw Exception("getNode($value) no yet implemented");\r
+    }\r
+    \r
+    /**\r
+        * Adds a new node to the session.\r
+        */\r
+       public function addNode($node)\r
+       {\r
+               $this->nodeCache[$node->__toString()] = $node;\r
+       }\r
+       \r
+       private function getNodeImpl($store, $id)\r
+       {               \r
+               $result = null;\r
+               $nodeRef = $store->scheme . "://" . $store->address . "/" . $id;\r
+               if (array_key_exists($nodeRef, $this->nodeCache) == true)\r
+               {\r
+                       $result = $this->nodeCache[$nodeRef];\r
+               }\r
+               return $result;\r
+       }\r
+\r
+       /**\r
+        * Commits all unsaved changes to the repository\r
+        */\r
+       public function save($debug=false)\r
+       {\r
+               // Build the update statements from the node cache\r
+               $statements = array();\r
+               foreach ($this->nodeCache as $node)\r
+               {\r
+                       $node->onBeforeSave($statements);\r
+               }\r
+               \r
+               if ($debug == true)\r
+               {\r
+                       var_dump($statements);\r
+                       echo ("<br><br>");\r
+               }\r
+               \r
+               if (count($statements) > 0)\r
+               {\r
+                       // Make the web service call\r
+                       $result = $this->repositoryService->update(array("statements" => $statements));\r
+                       //var_dump($result);\r
+                                       \r
+                       // Update the state of the updated nodes\r
+                       foreach ($this->nodeCache as $node)\r
+                       {\r
+                               $node->onAfterSave($this->getIdMap($result));\r
+                       }\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Clears the current session by emptying the node cache.\r
+        * \r
+        * WARNING:  all unsaved changes will be lost when clearing the session.\r
+        */\r
+       public function clear()\r
+       {\r
+               // Clear the node cache\r
+               $this->nodeCache = array();     \r
+       }\r
+       \r
+       private function getIdMap($result)\r
+       {\r
+               $return = array();\r
+               $statements = $result->updateReturn;\r
+               if (is_array($statements) == true)\r
+               {\r
+                       foreach ($statements as $statement)\r
+                       {\r
+                               if ($statement->statement == "create")\r
+                               {\r
+                                       $id = $statement->sourceId;\r
+                                       $uuid = $statement->destination->uuid;\r
+                                       $return[$id] = $uuid;\r
+                               }\r
+                       }       \r
+               }       \r
+               else\r
+               {\r
+                       if ($statements->statement == "create")\r
+                               {\r
+                                       $id = $statements->sourceId;\r
+                                       $uuid = $statements->destination->uuid;\r
+                                       $return[$id] = $uuid;\r
+                               }       \r
+               }       \r
+               return $return; \r
+       }\r
+       \r
+       public function query($store, $query, $language='lucene')\r
+       {\r
+               // TODO need to support paged queries\r
+               $result = $this->repositoryService->query(array(\r
+                                       "store" => $store->__toArray(),\r
+                                       "query" => array(\r
+                                               "language" => $language,\r
+                                               "statement" => $query),\r
+                                       "includeMetaData" => false));                                   \r
+                               \r
+               // TODO for now do nothing with the score and the returned data                 \r
+               $resultSet = $result->queryReturn->resultSet;           \r
+               return $this->resultSetToNodes($this, $store, $resultSet);\r
+       }\r
+\r
+       public function getTicket()\r
+       {\r
+               return $this->_ticket;\r
+       }\r
+\r
+       public function getRepository()\r
+       {\r
+               return $this->_repository;\r
+       }\r
+       \r
+       public function getNamespaceMap()\r
+       {\r
+               if ($this->_namespaceMap == null)\r
+               {\r
+                       $this->_namespaceMap = new NamespaceMap();\r
+               }\r
+               return $this->_namespaceMap;\r
+       }\r
+\r
+       public function getStores()\r
+       {\r
+               if (isset ($this->_stores) == false)\r
+               {\r
+                       $this->_stores = array ();\r
+                       $results = $this->repositoryService->getStores();\r
+\r
+                       foreach ($results->getStoresReturn as $result)\r
+                       {\r
+                               $this->_stores[] = new Store($this, $result->address, $result->scheme);\r
+                       }\r
+               }\r
+\r
+               return $this->_stores;\r
+       }\r
+       \r
+       /** Want these methods to be package scope some how! **/\r
+       \r
+       public function nextSessionId()\r
+       {\r
+               $sessionId = "session".$this->_ticket.$this->idCount;\r
+               $this->idCount ++;\r
+               return $sessionId;\r
+       }\r
+}\r
+?>
\ No newline at end of file
diff --git a/lib/alfresco/Service/SpacesStore.php b/lib/alfresco/Service/SpacesStore.php
new file mode 100755 (executable)
index 0000000..5764f46
--- /dev/null
@@ -0,0 +1,54 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
\r
+require_once 'Store.php';\r
+require_once 'Node.php';\r
+\r
+class SpacesStore extends Store\r
+{\r
+       private $_companyHome;\r
+\r
+       public function __construct($session)\r
+       {\r
+               parent::__construct($session, "SpacesStore");\r
+       }\r
+\r
+       public function __toString()\r
+       {\r
+               return $this->scheme . "://" . $this->address;\r
+       }\r
+       \r
+       public function getCompanyHome()\r
+       {\r
+               if ($this->_companyHome == null)\r
+               {\r
+                       $nodes = $this->_session->query($this, 'PATH:"app:company_home"');\r
+               $this->_companyHome = $nodes[0];\r
+               }\r
+               return $this->_companyHome;\r
+       }\r
+}\r
+?>
\ No newline at end of file
diff --git a/lib/alfresco/Service/Store.php b/lib/alfresco/Service/Store.php
new file mode 100755 (executable)
index 0000000..fa72978
--- /dev/null
@@ -0,0 +1,81 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
\r
+require_once 'BaseObject.php';\r
+require_once 'Node.php';\r
+\r
+class Store extends BaseObject\r
+{\r
+       protected $_session;\r
+       protected $_address;\r
+       protected $_scheme;\r
+       protected $_rootNode;\r
+\r
+       public function __construct($session, $address, $scheme = "workspace")\r
+       {\r
+               $this->_session = $session;\r
+               $this->_address = $address;\r
+               $this->_scheme = $scheme;\r
+       }\r
+\r
+       public function __toString()\r
+       {\r
+               return $this->scheme . "://" . $this->address;\r
+       }\r
+       \r
+       public function __toArray()\r
+       {\r
+               return array(\r
+                       "scheme" => $this->_scheme,\r
+                       "address" => $this->_address);\r
+       }\r
+\r
+       public function getAddress()\r
+       {\r
+               return $this->_address;\r
+       }\r
+\r
+       public function getScheme()\r
+       {\r
+               return $this->_scheme;\r
+       }\r
+\r
+       public function getRootNode()\r
+       {\r
+               if (isset ($this->_rootNode) == false)\r
+               {\r
+                       $result = $this->_session->repositoryService->get(\r
+                               array(\r
+                                       "where" => array(\r
+                                               "store" => $this->__toArray())));\r
+\r
+                       $this->_rootNode = Node::createFromWebServiceData($this->_session, $result->getReturn);\r
+               }\r
+\r
+               return $this->_rootNode;\r
+       }\r
+}\r
+?>
\ No newline at end of file
diff --git a/lib/alfresco/Service/Version.php b/lib/alfresco/Service/Version.php
new file mode 100755 (executable)
index 0000000..cd1fd85
--- /dev/null
@@ -0,0 +1,200 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
\r
+ /**\r
+  * Version class\r
+  * \r
+  * @author Roy Wetherall\r
+  */\r
+ class Version extends BaseObject \r
+ {\r
+       private $_session;\r
+       private $_store;\r
+       private $_id;\r
+       private $_description;\r
+       private $_major;\r
+       private $_properties;\r
+       private $_type;\r
+       private $_aspects;\r
+       \r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param       $session                the session that the version is tied to\r
+        * @param       @store                  the store that the forzen node is stored in\r
+        * @prarm       @id                             the id of the frozen node\r
+        * @param   @description        the description of the version\r
+        * @param       @major                  indicates whether this is a major or minor revision     \r
+        */\r
+       public function __construct($session, $store, $id, $description=null, $major=false)\r
+       {\r
+               $this->_session = $session;\r
+               $this->_store = $store;\r
+               $this->_id = $id;\r
+               $this->_description = $description;\r
+               $this->_major = $major;         \r
+               $this->_properties = null;\r
+               $this->_aspects = null;\r
+               $this->_type = null;    \r
+       }       \r
+       \r
+       /**\r
+        *      __get override.\r
+        *\r
+        * If called with a valid property short name, the frozen value of that property is returned. \r
+        * \r
+        * @return      String  the appropriate property value, null if none found\r
+        */\r
+       public function __get($name)\r
+       {\r
+               $fullName = $this->_session->namespaceMap->getFullName($name);\r
+               if ($fullName != $name)\r
+               {\r
+                       $this->populateProperties();    \r
+                       if (array_key_exists($fullName, $this->_properties) == true)\r
+                       {\r
+                               return $this->_properties[$fullName];\r
+                       }       \r
+                       else\r
+                       {       \r
+                               return null;    \r
+                       }       \r
+               }       \r
+               else\r
+               {\r
+                       return parent::__get($name);\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Gets session\r
+        * \r
+        * @return Session      the session\r
+        */\r
+       public function getSession()\r
+       {\r
+               return $this->_session;\r
+       }\r
+       \r
+       /**\r
+        * Get the frozen nodes store\r
+        * \r
+        * @return Store        the store\r
+        */\r
+       public function getStore()\r
+       {\r
+               return $this->_store;\r
+       }\r
+       \r
+       public function getId()\r
+       {\r
+               return $this->_id;\r
+       }\r
+       \r
+       public function getDescription()\r
+       {\r
+               return $this->_description;\r
+       }\r
+       \r
+       public function getMajor()\r
+       {\r
+               return $this->_major;\r
+       }\r
+       \r
+       public function getType()\r
+       {\r
+               return $this->_type;\r
+       }\r
+       \r
+       public function getProperties()\r
+       {\r
+               return $this->_properties;\r
+       }\r
+       \r
+       public function getAspects()\r
+       {\r
+               return $this->_aspects;\r
+       }\r
+       \r
+       private function populateProperties()\r
+       {\r
+               if ($this->_properties == null)\r
+               {       \r
+                       $result = $this->_session->repositoryService->get(array (\r
+                                       "where" => array (\r
+                                               "nodes" => array(\r
+                                                       "store" => $this->_store->__toArray(),\r
+                                                       "uuid" => $this->_id))));       \r
+                                                       \r
+                       $this->populateFromWebServiceNode($result->getReturn);\r
+               }       \r
+       }\r
+       \r
+       private function populateFromWebServiceNode($webServiceNode)\r
+       {\r
+               $this->_type = $webServiceNode->type;\r
+\r
+               // Get the aspects\r
+               $this->_aspects = array();\r
+               $aspects = $webServiceNode->aspects;\r
+               if (is_array($aspects) == true)\r
+               {\r
+                       foreach ($aspects as $aspect)\r
+                       {\r
+                               $this->_aspects[] = $aspect;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $this->_aspects[] = $aspects;   \r
+               }               \r
+\r
+               // Set the property values\r
+               $this->_properties = array();\r
+               foreach ($webServiceNode->properties as $propertyDetails) \r
+               {\r
+                       $name = $propertyDetails->name;\r
+                       $isMultiValue = $propertyDetails->isMultiValue;\r
+                       $value = null;\r
+                       if ($isMultiValue == false)\r
+                       {\r
+                               $value = $propertyDetails->value;\r
+                               if ($this->isContentData($value) == true)\r
+                               {\r
+                                       $value = new ContentData($this, $name);\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $value = $propertyDetails->values;\r
+                       }\r
+                       \r
+                       $this->_properties[$name] = $value;\r
+               }               \r
+       }\r
+ }\r
+?>\r
diff --git a/lib/alfresco/Service/VersionHistory.php b/lib/alfresco/Service/VersionHistory.php
new file mode 100755 (executable)
index 0000000..c590611
--- /dev/null
@@ -0,0 +1,80 @@
+<?php\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
\r
+ /**\r
+  * Version history class.\r
+  * \r
+  * @author Roy Wetherall\r
+  */\r
+ class VersionHistory extends BaseObject \r
+ {\r
+       /** Node to which this version history relates */\r
+       private $_node;\r
+       \r
+       /** Array of versions */\r
+       private $_versions;\r
+       \r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param       $node   the node that this version history apples to\r
+        */\r
+       public function __construct($node) \r
+       { \r
+               $this->_node = $node;\r
+               $this->populateVersionHistory();\r
+       }\r
+       \r
+       /**\r
+        * Get the node that this version history relates to\r
+        */\r
+       public function getNode()\r
+       {\r
+               return $this->_node;\r
+       }\r
+       \r
+       /**\r
+        * Get a list of the versions in the version history\r
+        */\r
+       public function getVersions()\r
+       {\r
+               return $this->_versions;\r
+       }\r
+       \r
+       /**\r
+        * Populate the version history\r
+        */\r
+       private function populateVersionHistory()\r
+       {\r
+               // Use the web service API to get the version history for this node\r
+               $client = WebServiceFactory::getAuthoringService($this->_node->session->repository->connectionUrl, $this->_node->session->ticket);\r
+               $result = $client->getVersionHistory(array("node" => $this->_node->__toArray()));\r
+               //var_dump($result);\r
+               \r
+               // TODO populate the version history from the result of the web service call\r
+       }\r
+ }\r
+?>\r
diff --git a/lib/alfresco/Service/WebService/AlfrescoWebService.php b/lib/alfresco/Service/WebService/AlfrescoWebService.php
new file mode 100755 (executable)
index 0000000..e79cae1
--- /dev/null
@@ -0,0 +1,117 @@
+<?php\r
+\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+class AlfrescoWebService extends SoapClient\r
+{\r
+   private $securityExtNS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";\r
+   private $wsUtilityNS   = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";\r
+   private $passwordType  = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";\r
+\r
+   private $ticket;\r
+   \r
+   public function __construct($wsdl, $options = array('trace' => true, 'exceptions' => true), $ticket = null)\r
+   {\r
+      // Store the current ticket\r
+      $this->ticket = $ticket;\r
+\r
+      // Call the base class\r
+      parent::__construct($wsdl, $options);\r
+   }\r
+\r
+   public function __call($function_name, $arguments=array())\r
+   {\r
+      return $this->__soapCall($function_name, $arguments);\r
+   }\r
+\r
+   public function __soapCall($function_name, $arguments=array(), $options=array(), $input_headers=array(), $output_headers=array())\r
+   {\r
+      if (isset($this->ticket))\r
+      {\r
+         // Automatically add a security header         \r
+         $input_headers[] = new SoapHeader($this->securityExtNS, "Security", null, 1);\r
+         \r
+         // Set the JSESSION cookie value\r
+         $sessionId = Al_Repository::getSessionId($this->ticket); // Moodle\r
+         if ($sessionId != null)\r
+         {\r
+               $this->__setCookie("JSESSIONID", $sessionId);\r
+         }\r
+      }\r
+      \r
+      return parent::__soapCall($function_name, $arguments, $options, $input_headers, $output_headers);   \r
+   }\r
+   \r
+   public function __doRequest($request, $location, $action, $version)\r
+   {\r
+      // If this request requires authentication we have to manually construct the\r
+      // security headers.\r
+      if (isset($this->ticket))\r
+      { \r
+         $dom = new DOMDocument("1.0");\r
+         $dom->loadXML($request);\r
+\r
+         $securityHeader = $dom->getElementsByTagName("Security");\r
+\r
+         if ($securityHeader->length != 1)\r
+         {\r
+            throw new Exception("Expected length: 1, Received: " . $securityHeader->length . ". No Security Header, or more than one element called Security!");\r
+         }\r
+      \r
+         $securityHeader = $securityHeader->item(0);\r
+\r
+         // Construct Timestamp Header\r
+         $timeStamp = $dom->createElementNS($this->wsUtilityNS, "Timestamp");\r
+         $createdDate = date("Y-m-d\TH:i:s\Z", mktime(date("H")+24, date("i"), date("s"), date("m"), date("d"), date("Y")));\r
+         $expiresDate = date("Y-m-d\TH:i:s\Z", mktime(date("H")+25, date("i"), date("s"), date("m"), date("d"), date("Y")));\r
+         $created = new DOMElement("Created", $createdDate, $this->wsUtilityNS);\r
+         $expires = new DOMElement("Expires", $expiresDate, $this->wsUtilityNS);\r
+         $timeStamp->appendChild($created);\r
+         $timeStamp->appendChild($expires);\r
+\r
+         // Construct UsernameToken Header\r
+         $userNameToken = $dom->createElementNS($this->securityExtNS, "UsernameToken");\r
+         $userName = new DOMElement("Username", "username", $this->securityExtNS);\r
+         $passWord = $dom->createElementNS($this->securityExtNS, "Password");\r
+         $typeAttr = new DOMAttr("Type", $this->passwordType);\r
+         $passWord->appendChild($typeAttr);\r
+         $passWord->appendChild($dom->createTextNode($this->ticket));\r
+         $userNameToken->appendChild($userName);\r
+         $userNameToken->appendChild($passWord);\r
+\r
+         // Construct Security Header\r
+         $securityHeader->appendChild($timeStamp);\r
+         $securityHeader->appendChild($userNameToken);\r
+\r
+         // Save the XML Request\r
+         $request = $dom->saveXML();\r
+      }\r
+\r
+      return parent::__doRequest($request, $location, $action, $version);\r
+   }\r
+}\r
+\r
+?>\r
diff --git a/lib/alfresco/Service/WebService/WebServiceFactory.php b/lib/alfresco/Service/WebService/WebServiceFactory.php
new file mode 100755 (executable)
index 0000000..acc6aa9
--- /dev/null
@@ -0,0 +1,63 @@
+<?php\r
+\r
+/*\r
+ * Copyright (C) 2005 Alfresco, Inc.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+ * As a special exception to the terms and conditions of version 2.0 of \r
+ * the GPL, you may redistribute this Program in connection with Free/Libre \r
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's \r
+ * FLOSS exception.  You should have recieved a copy of the text describing \r
+ * the FLOSS exception, and it is also available here: \r
+ * http://www.alfresco.com/legal/licensing"\r
+ */\r
+\r
+require_once 'AlfrescoWebService.php';\r
+\r
+class WebServiceFactory\r
+{\r
+   public static function getAuthenticationService($path)\r
+   {\r
+        $path .= '/AuthenticationService?wsdl';\r
+        return new AlfrescoWebService($path, array());\r
+   }\r
+\r
+   public static function getRepositoryService($path, $ticket)\r
+   {\r
+        $path .= '/RepositoryService?wsdl';\r
+        return new AlfrescoWebService($path, array(), $ticket);\r
+   }\r
+   \r
+   public static function getContentService($path, $ticket)\r
+   {\r
+        $path .= '/ContentService?wsdl';\r
+        return new AlfrescoWebService($path, array(), $ticket);\r
+   }\r
+   \r
+   public static function getAdministrationService($path, $ticket)\r
+   {\r
+        $path .= '/AdministrationService?wsdl';\r
+        return new AlfrescoWebService($path, array(), $ticket);\r
+   }   \r
+   \r
+   public static function getAuthoringService($path, $ticket)\r
+   {\r
+        $path .= '/AuthoringService?wsdl';\r
+        return new AlfrescoWebService($path, array(), $ticket);\r
+   }\r
+}\r
+\r
+?>
\ No newline at end of file
diff --git a/repository/alfresco/icon.png b/repository/alfresco/icon.png
new file mode 100644 (file)
index 0000000..8079749
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 (executable)
index 0000000..05918df
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+/**
+ * repository_alfresco class
+ *
+ * @version $Id$
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ */
+require_once($CFG->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');
+    }
+}
+?>