]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Refs #2220: Pulled most classes / interfaces out of lib files (except query.php and...
authorewinslow <ewinslow@36083f99-b078-4883-b0ff-0f9b5a30f544>
Mon, 6 Sep 2010 02:42:09 +0000 (02:42 +0000)
committerewinslow <ewinslow@36083f99-b078-4883-b0ff-0f9b5a30f544>
Mon, 6 Sep 2010 02:42:09 +0000 (02:42 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@6908 36083f99-b078-4883-b0ff-0f9b5a30f544

77 files changed:
engine/classes/CronException.php [new file with mode: 0644]
engine/classes/ElggAccess.php [new file with mode: 0644]
engine/classes/ElggAnnotation.php [new file with mode: 0644]
engine/classes/ElggCache.php [new file with mode: 0644]
engine/classes/ElggDiskFilestore.php [new file with mode: 0644]
engine/classes/ElggEntity.php [new file with mode: 0644]
engine/classes/ElggExtender.php [new file with mode: 0644]
engine/classes/ElggFile.php [new file with mode: 0644]
engine/classes/ElggFileCache.php [new file with mode: 0644]
engine/classes/ElggFilestore.php [new file with mode: 0644]
engine/classes/ElggGroup.php [new file with mode: 0644]
engine/classes/ElggHMACCache.php [new file with mode: 0644]
engine/classes/ElggMemcache.php [new file with mode: 0644]
engine/classes/ElggMetadata.php [new file with mode: 0644]
engine/classes/ElggObject.php [new file with mode: 0644]
engine/classes/ElggPlugin.php [new file with mode: 0644]
engine/classes/ElggRelationship.php [new file with mode: 0644]
engine/classes/ElggSession.php [new file with mode: 0644]
engine/classes/ElggSharedMemoryCache.php [new file with mode: 0644]
engine/classes/ElggSite.php [new file with mode: 0644]
engine/classes/ElggStaticVariableCache.php [new file with mode: 0644]
engine/classes/ElggUser.php [new file with mode: 0644]
engine/classes/ElggWidget.php [new file with mode: 0644]
engine/classes/ErrorResult.php [new file with mode: 0644]
engine/classes/ExportException.php [new file with mode: 0644]
engine/classes/Exportable.php [new file with mode: 0644]
engine/classes/Friendable.php [new file with mode: 0644]
engine/classes/GenericResult.php [new file with mode: 0644]
engine/classes/ImportException.php [new file with mode: 0644]
engine/classes/Importable.php [new file with mode: 0644]
engine/classes/Locatable.php [new file with mode: 0644]
engine/classes/Loggable.php [new file with mode: 0644]
engine/classes/Notable.php [new file with mode: 0644]
engine/classes/ODD.php [new file with mode: 0644]
engine/classes/ODDDocument.php [new file with mode: 0644]
engine/classes/ODDEntity.php [new file with mode: 0644]
engine/classes/SuccessResult.php [new file with mode: 0644]
engine/classes/XMLRPCArrayParameter.php [new file with mode: 0644]
engine/classes/XMLRPCBase64Parameter.php [new file with mode: 0644]
engine/classes/XMLRPCBoolParameter.php [new file with mode: 0644]
engine/classes/XMLRPCCall.php [new file with mode: 0644]
engine/classes/XMLRPCDateParameter.php [new file with mode: 0644]
engine/classes/XMLRPCDoubleParameter.php [new file with mode: 0644]
engine/classes/XMLRPCErrorResponse.php [new file with mode: 0644]
engine/classes/XMLRPCIntParameter.php [new file with mode: 0644]
engine/classes/XMLRPCParameter.php [new file with mode: 0644]
engine/classes/XMLRPCResponse.php [new file with mode: 0644]
engine/classes/XMLRPCStringParameter.php [new file with mode: 0644]
engine/classes/XMLRPCStructParameter.php [new file with mode: 0644]
engine/classes/XMLRPCSuccessResponse.php [new file with mode: 0644]
engine/classes/XmlElement.php [new file with mode: 0644]
engine/lib/access.php
engine/lib/annotations.php
engine/lib/api.php
engine/lib/cache.php
engine/lib/calendar.php
engine/lib/cron.php
engine/lib/elgglib.php
engine/lib/entities.php
engine/lib/export.php
engine/lib/extender.php
engine/lib/filestore.php
engine/lib/group.php
engine/lib/location.php
engine/lib/memcache.php
engine/lib/metadata.php
engine/lib/objects.php
engine/lib/opendd.php
engine/lib/plugins.php
engine/lib/relationships.php
engine/lib/sessions.php
engine/lib/sites.php
engine/lib/system_log.php
engine/lib/users.php
engine/lib/widgets.php
engine/lib/xml-rpc.php
engine/lib/xml.php

diff --git a/engine/classes/CronException.php b/engine/classes/CronException.php
new file mode 100644 (file)
index 0000000..3720c2c
--- /dev/null
@@ -0,0 +1,3 @@
+<?php\r
+/** The cron exception. */\r
+class CronException extends Exception {}
\ No newline at end of file
diff --git a/engine/classes/ElggAccess.php b/engine/classes/ElggAccess.php
new file mode 100644 (file)
index 0000000..57cceef
--- /dev/null
@@ -0,0 +1,32 @@
+<?php\r
+/**\r
+ * Temporary class used to determing if access is being ignored\r
+ */\r
+class ElggAccess {\r
+       /**\r
+        * Bypass Elgg's access control if true.\r
+        * @var bool\r
+        */\r
+       private $ignore_access;\r
+\r
+       /**\r
+        * Get current ignore access setting.\r
+        * @return bool\r
+        */\r
+       public function get_ignore_access() {\r
+               return $this->ignore_access;\r
+       }\r
+\r
+       /**\r
+        * Set ignore access.\r
+        *\r
+        * @param $ignore bool true || false to ignore\r
+        * @return bool Previous setting\r
+        */\r
+       public function set_ignore_access($ignore = true) {\r
+               $prev = $this->ignore_access;\r
+               $this->ignore_access = $ignore;\r
+\r
+               return $prev;\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggAnnotation.php b/engine/classes/ElggAnnotation.php
new file mode 100644 (file)
index 0000000..fe85ca0
--- /dev/null
@@ -0,0 +1,107 @@
+<?php\r
+/**\r
+ * ElggAnnotation\r
+ *\r
+ * An annotation is similar to metadata.\r
+ * Each entity can have more than one of each type of annotation.\r
+ *\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ */\r
+class ElggAnnotation extends ElggExtender {\r
+\r
+       /**\r
+        * Construct a new annotation, optionally from a given id value or db object.\r
+        *\r
+        * @param mixed $id\r
+        */\r
+       function __construct($id = null) {\r
+               $this->attributes = array();\r
+\r
+               if (!empty($id)) {\r
+                       if ($id instanceof stdClass) {\r
+                               $annotation = $id;\r
+                       } else {\r
+                               $annotation = get_annotation($id);\r
+                       }\r
+\r
+                       if ($annotation) {\r
+                               $objarray = (array) $annotation;\r
+\r
+                               foreach($objarray as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+\r
+                               $this->attributes['type'] = "annotation";\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Class member get overloading\r
+        *\r
+        * @param string $name\r
+        * @return mixed\r
+        */\r
+       function __get($name) {\r
+               return $this->get($name);\r
+       }\r
+\r
+       /**\r
+        * Class member set overloading\r
+        *\r
+        * @param string $name\r
+        * @param mixed $value\r
+        * @return void\r
+        */\r
+       function __set($name, $value) {\r
+               return $this->set($name, $value);\r
+       }\r
+\r
+       /**\r
+        * Save this instance\r
+        *\r
+        * @return int an object id\r
+        */\r
+       function save() {\r
+               if ($this->id > 0) {\r
+                       return update_annotation($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);\r
+               } else {\r
+                       $this->id = create_annotation($this->entity_guid, $this->name, $this->value,\r
+                               $this->value_type, $this->owner_guid, $this->access_id);\r
+\r
+                       if (!$this->id) {\r
+                               throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));\r
+                       }\r
+                       return $this->id;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Delete the annotation.\r
+        */\r
+       function delete() {\r
+               return delete_annotation($this->id);\r
+       }\r
+\r
+       /**\r
+        * Get a url for this annotation.\r
+        *\r
+        * @return string\r
+        */\r
+       public function getURL() {\r
+               return get_annotation_url($this->id);\r
+       }\r
+\r
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * For a given ID, return the object associated with it.\r
+        * This is used by the river functionality primarily.\r
+        * This is useful for checking access permissions etc on objects.\r
+        */\r
+       public function getObjectFromID($id) {\r
+               return get_annotation($id);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggCache.php b/engine/classes/ElggCache.php
new file mode 100644 (file)
index 0000000..c592854
--- /dev/null
@@ -0,0 +1,164 @@
+<?php\r
+\r
+/**\r
+ * ElggCache The elgg cache superclass.\r
+ * This defines the interface for a cache (wherever that cache is stored).\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage API\r
+ */\r
+abstract class ElggCache implements\r
+       // Override for array access\r
+       ArrayAccess  {\r
+       /**\r
+        * Variables for the cache object.\r
+        *\r
+        * @var array\r
+        */\r
+       private $variables;\r
+\r
+       /**\r
+        * Set the constructor.\r
+        */\r
+       function __construct() {\r
+               $this->variables = array();\r
+       }\r
+\r
+       /**\r
+        * Set a cache variable.\r
+        *\r
+        * @param string $variable\r
+        * @param string $value\r
+        */\r
+       public function set_variable($variable, $value) {\r
+               if (!is_array($this->variables)) {\r
+                       $this->variables = array();\r
+               }\r
+\r
+               $this->variables[$variable] = $value;\r
+       }\r
+\r
+       /**\r
+        * Get variables for this cache.\r
+        *\r
+        * @param string $variable\r
+        * @return mixed The variable or null;\r
+        */\r
+       public function get_variable($variable) {\r
+               if (isset($this->variables[$variable])) {\r
+                       return $this->variables[$variable];\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Class member get overloading, returning key using $this->load defaults.\r
+        *\r
+        * @param string $key\r
+        * @return mixed\r
+        */\r
+       function __get($key) {\r
+               return $this->load($key);\r
+       }\r
+\r
+       /**\r
+        * Class member set overloading, setting a key using $this->save defaults.\r
+        *\r
+        * @param string $key\r
+        * @param mixed $value\r
+        * @return mixed\r
+        */\r
+       function __set($key, $value) {\r
+               return $this->save($key, $value);\r
+       }\r
+\r
+       /**\r
+        * Supporting isset, using $this->load() with default values.\r
+        *\r
+        * @param string $key The name of the attribute or metadata.\r
+        * @return bool\r
+        */\r
+       function __isset($key) {\r
+               return (bool)$this->load($key);\r
+       }\r
+\r
+       /**\r
+        * Supporting unsetting of magic attributes.\r
+        *\r
+        * @param string $key The name of the attribute or metadata.\r
+        */\r
+       function __unset($key) {\r
+               return $this->delete($key);\r
+       }\r
+\r
+       /**\r
+        * Save data in a cache.\r
+        *\r
+        * @param string $key\r
+        * @param string $data\r
+        * @return bool\r
+        */\r
+       abstract public function save($key, $data);\r
+\r
+       /**\r
+        * Load data from the cache using a given key.\r
+        *\r
+        * @param string $key\r
+        * @param int $offset\r
+        * @param int $limit\r
+        * @return mixed The stored data or false.\r
+        */\r
+       abstract public function load($key, $offset = 0, $limit = null);\r
+\r
+       /**\r
+        * Invalidate a key\r
+        *\r
+        * @param string $key\r
+        * @return bool\r
+        */\r
+       abstract public function delete($key);\r
+\r
+       /**\r
+        * Clear out all the contents of the cache.\r
+        *\r
+        */\r
+       abstract public function clear();\r
+\r
+       /**\r
+        * Add a key only if it doesn't already exist.\r
+        * Implemented simply here, if you extend this class and your caching engine provides a better way then\r
+        * override this accordingly.\r
+        *\r
+        * @param string $key\r
+        * @param string $data\r
+        * @return bool\r
+        */\r
+       public function add($key, $data) {\r
+               if (!isset($this[$key])) {\r
+                       return $this->save($key, $data);\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////\r
+       function offsetSet($key, $value) {\r
+               $this->save($key, $value);\r
+       }\r
+\r
+       function offsetGet($key) {\r
+               return $this->load($key);\r
+       }\r
+\r
+       function offsetUnset($key) {\r
+               if ( isset($this->key) ) {\r
+                       unset($this->key);\r
+               }\r
+       }\r
+\r
+       function offsetExists($offset) {\r
+               return isset($this->$offset);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggDiskFilestore.php b/engine/classes/ElggDiskFilestore.php
new file mode 100644 (file)
index 0000000..6b0fa25
--- /dev/null
@@ -0,0 +1,263 @@
+<?php
+/**
+ * @class ElggDiskFilestore
+ * This class uses disk storage to save data.
+ * @author Curverider Ltd
+ */
+class ElggDiskFilestore extends ElggFilestore {
+       /**
+        * Directory root.
+        */
+       private $dir_root;
+
+       /**
+        * Default depth of file directory matrix
+        */
+       private $matrix_depth = 5;
+
+       /**
+        * Construct a disk filestore using the given directory root.
+        *
+        * @param string $directory_root Root directory, must end in "/"
+        */
+       public function __construct($directory_root = "") {
+               global $CONFIG;
+
+               if ($directory_root) {
+                       $this->dir_root = $directory_root;
+               } else {
+                       $this->dir_root = $CONFIG->dataroot;
+               }
+       }
+
+       public function open(ElggFile $file, $mode) {
+               $fullname = $this->getFilenameOnFilestore($file);
+
+               // Split into path and name
+               $ls = strrpos($fullname,"/");
+               if ($ls===false) {
+                       $ls = 0;
+               }
+
+               $path = substr($fullname, 0, $ls);
+               $name = substr($fullname, $ls);
+
+               // Try and create the directory
+               try {
+                       $this->make_directory_root($path);
+               } catch (Exception $e) {
+
+               }
+
+               if (($mode!='write') && (!file_exists($fullname))) {
+                       return false;
+               }
+
+               switch ($mode) {
+                       case "read" :
+                               $mode = "rb";
+                               break;
+                       case "write" :
+                               $mode = "w+b";
+                               break;
+                       case "append" :
+                               $mode = "a+b";
+                               break;
+                       default:
+                               throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode));
+               }
+
+               return fopen($fullname, $mode);
+
+       }
+
+       public function write($f, $data) {
+               return fwrite($f, $data);
+       }
+
+       public function read($f, $length, $offset = 0) {
+               if ($offset) {
+                       $this->seek($f, $offset);
+               }
+
+               return fread($f, $length);
+       }
+
+       public function close($f) {
+               return fclose($f);
+       }
+
+       public function delete(ElggFile $file) {
+               $filename = $this->getFilenameOnFilestore($file);
+               if (file_exists($filename)) {
+                       return unlink($filename);
+               } else {
+                       return true;
+               }
+       }
+
+       public function seek($f, $position) {
+               return fseek($f, $position);
+       }
+
+       public function tell($f) {
+               return ftell($f);
+       }
+
+       public function eof($f) {
+               return feof($f);
+       }
+
+       public function getFileSize(ElggFile $file) {
+               return filesize($this->getFilenameOnFilestore($file));
+       }
+
+       public function getFilenameOnFilestore(ElggFile $file) {
+               $owner = $file->getOwnerEntity();
+               if (!$owner) {
+                       $owner = get_loggedin_user();
+               }
+
+               if ((!$owner) || (!$owner->username)) {
+                       throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:MissingOwner'), $file->getFilename(), $file->guid));
+               }
+
+               return $this->dir_root . $this->make_file_matrix($owner->guid) . $file->getFilename();
+       }
+
+       public function grabFile(ElggFile $file) {
+               return file_get_contents($file->getFilenameOnFilestore());
+       }
+
+       public function exists(ElggFile $file) {
+               return file_exists($this->getFilenameOnFilestore($file));
+       }
+
+       public function getSize($prefix,$container_guid) {
+               if ($container_guid) {
+                       return get_dir_size($this->dir_root.$this->make_file_matrix($container_guid).$prefix);
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Make the directory root.
+        *
+        * @param string $dirroot
+        */
+       protected function make_directory_root($dirroot) {
+               if (!file_exists($dirroot)) {
+                       if (!@mkdir($dirroot, 0700, true)) {
+                               throw new IOException(sprintf(elgg_echo('IOException:CouldNotMake'), $dirroot));
+                       }
+               }
+
+               return true;
+       }
+
+       /**
+        * Multibyte string tokeniser.
+        *
+        * Splits a string into an array. Will fail safely if mbstring is not installed (although this may still
+        * not handle .
+        *
+        * @param string $string String
+        * @param string $charset The charset, defaults to UTF8
+        * @return array
+        */
+       private function mb_str_split($string, $charset = 'UTF8') {
+               if (is_callable('mb_substr')) {
+                       $length = mb_strlen($string);
+                       $array = array();
+
+                       while ($length) {
+                               $array[] = mb_substr($string, 0, 1, $charset);
+                               $string = mb_substr($string, 1, $length, $charset);
+
+                               $length = mb_strlen($string);
+                       }
+
+                       return $array;
+               } else {
+                       return str_split($string);
+               }
+
+               return false;
+       }
+
+       /**
+        * Construct the filename matrix.
+        *
+        * @param int | string $identifier
+        * @return str
+        */
+       protected function make_file_matrix($identifier) {
+               if (is_numeric($identifier)) {
+                       return $this->user_file_matrix($identifier);
+               }
+
+               return $this->deprecated_file_matrix($identifier);
+       }
+
+       /**
+        * Construct the filename matrix with user info
+        *
+        * This method will generate a matrix using the entity's creation time and
+        * unique guid. This is intended only to determine a user's data directory.
+        *
+        * @param int $guid
+        * @return str
+        */
+       protected function user_file_matrix($guid) {
+               // lookup the entity
+               $user = get_entity($guid);
+               if ($user->type != 'user')
+               {
+                       // only to be used for user directories
+                       return FALSE;
+               }
+
+               if (!$user->time_created) {
+                       // fall back to deprecated method
+                       return $this->deprecated_file_matrix($user->username);
+               }
+
+               $time_created = date('Y/m/d', $user->time_created);
+               return "$time_created/$user->guid/";
+       }
+
+       /**
+        * Construct the filename matrix using a string
+        *
+        * Particularly, this is used with a username to generate the file storage
+        * location.
+        *
+        * @deprecated for user directories: use user_file_matrix() instead.
+        *
+        * @param str $filename
+        * @return str
+        */
+       protected function deprecated_file_matrix($filename) {
+               // throw a warning for using deprecated method
+               $error  = 'Deprecated use of ElggDiskFilestore::make_file_matrix. ';
+               $error .= 'Username passed instead of guid.';
+               elgg_log($error, WARNING);
+
+               $user = new ElggUser($filename);
+               return $this->user_file_matrix($user->guid);
+       }
+
+       public function getParameters() {
+               return array("dir_root" => $this->dir_root);
+       }
+
+       public function setParameters(array $parameters) {
+               if (isset($parameters['dir_root'])) {
+                       $this->dir_root = $parameters['dir_root'];
+                       return true;
+               }
+
+               return false;
+       }
+}
diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php
new file mode 100644 (file)
index 0000000..f0d58d1
--- /dev/null
@@ -0,0 +1,1210 @@
+<?php\r
+/**\r
+ * ElggEntity The elgg entity superclass\r
+ * This class holds methods for accessing the main entities table.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+abstract class ElggEntity implements\r
+       Notable,    // Calendar interface\r
+       Locatable,  // Geocoding interface\r
+       Exportable, // Allow export of data\r
+       Importable, // Allow import of data\r
+       Loggable,       // Can events related to this object class be logged\r
+       Iterator,       // Override foreach behaviour\r
+       ArrayAccess // Override for array access\r
+{\r
+       /**\r
+        * The main attributes of an entity.\r
+        * Blank entries for all database fields should be created by the constructor.\r
+        * Subclasses should add to this in their constructors.\r
+        * Any field not appearing in this will be viewed as a\r
+        */\r
+       protected $attributes;\r
+\r
+       /**\r
+        * If set, overrides the value of getURL()\r
+        */\r
+       protected $url_override;\r
+\r
+       /**\r
+        * Icon override, overrides the value of getIcon().\r
+        */\r
+       protected $icon_override;\r
+\r
+       /**\r
+        * Temporary cache for metadata, permitting meta data access before a guid has obtained.\r
+        */\r
+       protected $temp_metadata;\r
+\r
+       /**\r
+        * Temporary cache for annotations, permitting meta data access before a guid has obtained.\r
+        */\r
+       protected $temp_annotations;\r
+\r
+\r
+       /**\r
+        * Volatile data structure for this object, allows for storage of data\r
+        * in-memory that isn't sync'd back to the metadata table.\r
+        */\r
+       protected $volatile;\r
+\r
+       /**\r
+        * Initialise the attributes array.\r
+        * This is vital to distinguish between metadata and base parameters.\r
+        *\r
+        * Place your base parameters here.\r
+        *\r
+        * @return void\r
+        */\r
+       protected function initialise_attributes() {\r
+               initialise_entity_cache();\r
+\r
+               // Create attributes array if not already created\r
+               if (!is_array($this->attributes)) {\r
+                       $this->attributes = array();\r
+               }\r
+               if (!is_array($this->temp_metadata)) {\r
+                       $this->temp_metadata = array();\r
+               }\r
+               if (!is_array($this->temp_annotations)) {\r
+                       $this->temp_annotations = array();\r
+               }\r
+               if (!is_array($this->volatile)) {\r
+                       $this->volatile = array();\r
+               }\r
+\r
+               $this->attributes['guid'] = "";\r
+               $this->attributes['type'] = "";\r
+               $this->attributes['subtype'] = "";\r
+\r
+               $this->attributes['owner_guid'] = get_loggedin_userid();\r
+               $this->attributes['container_guid'] = get_loggedin_userid();\r
+\r
+               $this->attributes['site_guid'] = 0;\r
+               $this->attributes['access_id'] = ACCESS_PRIVATE;\r
+               $this->attributes['time_created'] = "";\r
+               $this->attributes['time_updated'] = "";\r
+               $this->attributes['last_action'] = '';\r
+               $this->attributes['enabled'] = "yes";\r
+\r
+               // There now follows a bit of a hack\r
+               /* Problem: To speed things up, some objects are split over several tables, this means that it requires\r
+                * n number of database reads to fully populate an entity. This causes problems for caching and create events\r
+                * since it is not possible to tell whether a subclassed entity is complete.\r
+                * Solution: We have two counters, one 'tables_split' which tells whatever is interested how many tables\r
+                * are going to need to be searched in order to fully populate this object, and 'tables_loaded' which is how\r
+                * many have been loaded thus far.\r
+                * If the two are the same then this object is complete.\r
+                *\r
+                * Use: isFullyLoaded() to check\r
+                */\r
+               $this->attributes['tables_split'] = 1;\r
+               $this->attributes['tables_loaded'] = 0;\r
+       }\r
+\r
+       /**\r
+        * Clone an entity\r
+        *\r
+        * Resets the guid so that the entity can be saved as a distinct entity from\r
+        * the original. Creation time will be set when this new entity is saved.\r
+        * The owner and container guids come from the original entity. The clone\r
+        * method copies metadata but does not copy over annotations, or private settings.\r
+        *\r
+        * Note: metadata will have its owner and access id set when the entity is saved\r
+        * and it will be the same as that of the entity.\r
+        */\r
+       public function __clone() {\r
+\r
+               $orig_entity = get_entity($this->guid);\r
+               if (!$orig_entity) {\r
+                       elgg_log("Failed to clone entity with GUID $this->guid", "ERROR");\r
+                       return;\r
+               }\r
+\r
+               $metadata_array = get_metadata_for_entity($this->guid);\r
+\r
+               $this->attributes['guid'] = "";\r
+\r
+               $this->attributes['subtype'] = $orig_entity->getSubtype();\r
+\r
+               // copy metadata over to new entity - slightly convoluted due to\r
+               // handling of metadata arrays\r
+               if (is_array($metadata_array)) {\r
+                       // create list of metadata names\r
+                       $metadata_names = array();\r
+                       foreach ($metadata_array as $metadata) {\r
+                               $metadata_names[] = $metadata['name'];\r
+                       }\r
+                       // arrays are stored with multiple enties per name\r
+                       $metadata_names = array_unique($metadata_names);\r
+\r
+                       // move the metadata over\r
+                       foreach ($metadata_names as $name) {\r
+                               $this->set($name, $orig_entity->$name);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Return the value of a given key.\r
+        * If $name is a key field (as defined in $this->attributes) that value is returned, otherwise it will\r
+        * then look to see if the value is in this object's metadata.\r
+        *\r
+        * Q: Why are we not using __get overload here?\r
+        * A: Because overload operators cause problems during subclassing, so we put the code here and\r
+        * create overloads in subclasses.\r
+        *\r
+        * subtype is returned as an id rather than the subtype string. Use getSubtype()\r
+        * to get the subtype string.\r
+        *\r
+        * @param string $name\r
+        * @return mixed Returns the value of a given value, or null.\r
+        */\r
+       public function get($name) {\r
+               // See if its in our base attribute\r
+               if (isset($this->attributes[$name])) {\r
+                       return $this->attributes[$name];\r
+               }\r
+\r
+               // No, so see if its in the meta data for this entity\r
+               $meta = $this->getMetaData($name);\r
+\r
+               // getMetaData returns NULL if $name is not found\r
+               return $meta;\r
+       }\r
+\r
+       /**\r
+        * Set the value of a given key, replacing it if necessary.\r
+        * If $name is a base attribute (as defined in $this->attributes) that value is set, otherwise it will\r
+        * set the appropriate item of metadata.\r
+        *\r
+        * Note: It is important that your class populates $this->attributes with keys for all base attributes, anything\r
+        * not in their gets set as METADATA.\r
+        *\r
+        * Q: Why are we not using __set overload here?\r
+        * A: Because overload operators cause problems during subclassing, so we put the code here and\r
+        * create overloads in subclasses.\r
+        *\r
+        * @param string $name\r
+        * @param mixed $value\r
+        */\r
+       public function set($name, $value) {\r
+               if (array_key_exists($name, $this->attributes)) {\r
+                       // Certain properties should not be manually changed!\r
+                       switch ($name) {\r
+                               case 'guid':\r
+                               case 'time_created':\r
+                               case 'time_updated':\r
+                               case 'last_action':\r
+                                       return FALSE;\r
+                                       break;\r
+                               default:\r
+                                       $this->attributes[$name] = $value;\r
+                                       break;\r
+                       }\r
+               } else {\r
+                       return $this->setMetaData($name, $value);\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+\r
+       /**\r
+        * Get a given piece of metadata.\r
+        *\r
+        * @param string $name\r
+        */\r
+       public function getMetaData($name) {\r
+               if ((int) ($this->guid) > 0) {\r
+                       $md = get_metadata_byname($this->getGUID(), $name);\r
+               } else {\r
+                       if (isset($this->temp_metadata[$name])) {\r
+                               return $this->temp_metadata[$name];\r
+                       }\r
+               }\r
+\r
+               if ($md && !is_array($md)) {\r
+                       return $md->value;\r
+               } else if ($md && is_array($md)) {\r
+                       return metadata_array_to_values($md);\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Class member get overloading\r
+        *\r
+        * @param string $name\r
+        * @return mixed\r
+        */\r
+       function __get($name) {\r
+               return $this->get($name);\r
+       }\r
+\r
+       /**\r
+        * Class member set overloading\r
+        *\r
+        * @param string $name\r
+        * @param mixed $value\r
+        * @return mixed\r
+        */\r
+       function __set($name, $value) {\r
+               return $this->set($name, $value);\r
+       }\r
+\r
+       /**\r
+        * Supporting isset.\r
+        *\r
+        * @param string $name The name of the attribute or metadata.\r
+        * @return bool\r
+        */\r
+       function __isset($name) {\r
+               return $this->$name !== NULL;\r
+       }\r
+\r
+       /**\r
+        * Supporting unsetting of magic attributes.\r
+        *\r
+        * @param string $name The name of the attribute or metadata.\r
+        */\r
+       function __unset($name) {\r
+               if (array_key_exists($name, $this->attributes)) {\r
+                       $this->attributes[$name] = "";\r
+               }\r
+               else {\r
+                       $this->clearMetaData($name);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Set a piece of metadata.\r
+        *\r
+        * @param string $name Name of the metadata\r
+        * @param mixed $value Value of the metadata\r
+        * @param string $value_type Types supported: integer and string. Will auto-identify if not set\r
+        * @param bool $multiple (does not support associative arrays)\r
+        * @return bool\r
+        */\r
+       public function setMetaData($name, $value, $value_type = "", $multiple = false) {\r
+               if (is_array($value)) {\r
+                       unset($this->temp_metadata[$name]);\r
+                       remove_metadata($this->getGUID(), $name);\r
+                       foreach ($value as $v) {\r
+                               if ((int) $this->guid > 0) {\r
+                                       $multiple = true;\r
+                                       if (!create_metadata($this->getGUID(), $name, $v, $value_type,\r
+                                       $this->getOwner(), $this->getAccessID(), $multiple)) {\r
+                                               return false;\r
+                                       }\r
+                               } else {\r
+                                       if (($multiple) && (isset($this->temp_metadata[$name]))) {\r
+                                               if (!is_array($this->temp_metadata[$name])) {\r
+                                                       $tmp = $this->temp_metadata[$name];\r
+                                                       $this->temp_metadata[$name] = array();\r
+                                                       $this->temp_metadata[$name][] = $tmp;\r
+                                               }\r
+\r
+                                               $this->temp_metadata[$name][] = $value;\r
+                                       }\r
+                                       else {\r
+                                               $this->temp_metadata[$name] = $value;\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       return true;\r
+               } else {\r
+                       unset($this->temp_metadata[$name]);\r
+                       if ((int) $this->guid > 0) {\r
+                               $result = create_metadata($this->getGUID(), $name, $value, $value_type, $this->getOwner(), $this->getAccessID(), $multiple);\r
+                               return (bool)$result;\r
+                       } else {\r
+                               if (($multiple) && (isset($this->temp_metadata[$name]))) {\r
+                                       if (!is_array($this->temp_metadata[$name])) {\r
+                                               $tmp = $this->temp_metadata[$name];\r
+                                               $this->temp_metadata[$name] = array();\r
+                                               $this->temp_metadata[$name][] = $tmp;\r
+                                       }\r
+\r
+                                       $this->temp_metadata[$name][] = $value;\r
+                               }\r
+                               else {\r
+                                       $this->temp_metadata[$name] = $value;\r
+                               }\r
+\r
+                               return true;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Clear metadata.\r
+        */\r
+       public function clearMetaData($name = "") {\r
+               if (empty($name)) {\r
+                       return clear_metadata($this->getGUID());\r
+               } else {\r
+                       return remove_metadata($this->getGUID(),$name);\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * Get a piece of volatile (non-persisted) data on this entity\r
+        */\r
+       public function getVolatileData($name) {\r
+               if (!is_array($this->volatile)) {\r
+                       $this->volatile = array();\r
+               }\r
+\r
+               if (array_key_exists($name, $this->volatile)) {\r
+                       return $this->volatile[$name];\r
+               } else {\r
+                       return NULL;\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * Set a piece of volatile (non-persisted) data on this entity\r
+        */\r
+       public function setVolatileData($name, $value) {\r
+               if (!is_array($this->volatile)) {\r
+                       $this->volatile = array();\r
+               }\r
+\r
+               $this->volatile[$name] = $value;\r
+       }\r
+\r
+\r
+       /**\r
+        * Remove all entities associated with this entity\r
+        *\r
+        * @return true\r
+        */\r
+       public function clearRelationships() {\r
+               remove_entity_relationships($this->getGUID());\r
+               remove_entity_relationships($this->getGUID(),"",true);\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Add a relationship.\r
+        *\r
+        * @param int $guid Relationship to link to.\r
+        * @param string $relationship The type of relationship.\r
+        * @return bool\r
+        */\r
+       public function addRelationship($guid, $relationship) {\r
+               return add_entity_relationship($this->getGUID(), $relationship, $guid);\r
+       }\r
+\r
+       /**\r
+        * Remove a relationship\r
+        *\r
+        * @param int $guid\r
+        * @param str $relationship\r
+        * @return bool\r
+        */\r
+       public function removeRelationship($guid, $relationship) {\r
+               return remove_entity_relationship($this->getGUID(), $relationship, $guid);\r
+       }\r
+\r
+       /**\r
+        * Adds a private setting to this entity.\r
+        *\r
+        * @param $name\r
+        * @param $value\r
+        * @return unknown_type\r
+        */\r
+       function setPrivateSetting($name, $value) {\r
+               return set_private_setting($this->getGUID(), $name, $value);\r
+       }\r
+\r
+       /**\r
+        * Gets private setting for this entity\r
+        *\r
+        * @param $name\r
+        * @return unknown_type\r
+        */\r
+       function getPrivateSetting($name) {\r
+               return get_private_setting($this->getGUID(), $name);\r
+       }\r
+\r
+       /**\r
+        * Removes private setting for this entity.\r
+        *\r
+        * @param $name\r
+        * @return unknown_type\r
+        */\r
+       function removePrivateSetting($name) {\r
+               return remove_private_setting($this->getGUID(), $name);\r
+       }\r
+\r
+       /**\r
+        * Adds an annotation to an entity. By default, the type is detected automatically; however,\r
+        * it can also be set. Note that by default, annotations are private.\r
+        *\r
+        * @param string $name\r
+        * @param mixed $value\r
+        * @param int $access_id\r
+        * @param int $owner_id\r
+        * @param string $vartype\r
+        */\r
+       function annotate($name, $value, $access_id = ACCESS_PRIVATE, $owner_id = 0, $vartype = "") {\r
+               if ((int) $this->guid > 0) {\r
+                       return create_annotation($this->getGUID(), $name, $value, $vartype, $owner_id, $access_id);\r
+               } else {\r
+                       $this->temp_annotations[$name] = $value;\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Get the annotations for an entity.\r
+        *\r
+        * @param string $name\r
+        * @param int $limit\r
+        * @param int $offset\r
+        * @param string $order\r
+        */\r
+       function getAnnotations($name, $limit = 50, $offset = 0, $order="asc") {\r
+               if ((int) ($this->guid) > 0) {\r
+                       return get_annotations($this->getGUID(), "", "", $name, "", 0, $limit, $offset, $order);\r
+               } else {\r
+                       return $this->temp_annotations[$name];\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Remove all annotations or all annotations for this entity.\r
+        *\r
+        * @param string $name\r
+        */\r
+       function clearAnnotations($name = "") {\r
+               return clear_annotations($this->getGUID(), $name);\r
+       }\r
+\r
+       /**\r
+        * Return the annotations for the entity.\r
+        *\r
+        * @param string $name The type of annotation.\r
+        */\r
+       function countAnnotations($name = "") {\r
+               return count_annotations($this->getGUID(), "", "", $name);\r
+       }\r
+\r
+       /**\r
+        * Get the average of an integer type annotation.\r
+        *\r
+        * @param string $name\r
+        */\r
+       function getAnnotationsAvg($name) {\r
+               return get_annotations_avg($this->getGUID(), "", "", $name);\r
+       }\r
+\r
+       /**\r
+        * Get the sum of integer type annotations of a given name.\r
+        *\r
+        * @param string $name\r
+        */\r
+       function getAnnotationsSum($name) {\r
+               return get_annotations_sum($this->getGUID(), "", "", $name);\r
+       }\r
+\r
+       /**\r
+        * Get the minimum of integer type annotations of given name.\r
+        *\r
+        * @param string $name\r
+        */\r
+       function getAnnotationsMin($name) {\r
+               return get_annotations_min($this->getGUID(), "", "", $name);\r
+       }\r
+\r
+       /**\r
+        * Get the maximum of integer type annotations of a given name.\r
+        *\r
+        * @param string $name\r
+        */\r
+       function getAnnotationsMax($name) {\r
+               return get_annotations_max($this->getGUID(), "", "", $name);\r
+       }\r
+\r
+       /**\r
+        * Gets an array of entities from a specific relationship type\r
+        *\r
+        * @param string $relationship Relationship type (eg "friends")\r
+        * @param true|false $inverse Is this an inverse relationship?\r
+        * @param int $limit Number of elements to return\r
+        * @param int $offset Indexing offset\r
+        * @return array|false An array of entities or false on failure\r
+        */\r
+       function getEntitiesFromRelationship($relationship, $inverse = false, $limit = 50, $offset = 0) {\r
+               return elgg_get_entities_from_relationship(array(\r
+                       'relationship' => $relationship,\r
+                       'relationship_guid' => $this->getGUID(),\r
+                       'inverse_relationship' => $inverse,\r
+                       'limit' => $limit,\r
+                       'offset' => $offset\r
+               ));\r
+       }\r
+\r
+       /**\r
+        * Gets the number of of entities from a specific relationship type\r
+        *\r
+        * @param string $relationship Relationship type (eg "friends")\r
+        * @param bool $inverse_relationship\r
+        * @return int|false The number of entities or false on failure\r
+        */\r
+       function countEntitiesFromRelationship($relationship, $inverse_relationship = FALSE) {\r
+               return elgg_get_entities_from_relationship(array(\r
+                       'relationship' => $relationship,\r
+                       'relationship_guid' => $this->getGUID(),\r
+                       'inverse_relationship' => $inverse_relationship,\r
+                       'count' => TRUE\r
+               ));\r
+       }\r
+\r
+       /**\r
+        * Determines whether or not the specified user (by default the current one) can edit the entity\r
+        *\r
+        * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user)\r
+        * @return true|false\r
+        */\r
+       function canEdit($user_guid = 0) {\r
+               return can_edit_entity($this->getGUID(), $user_guid);\r
+       }\r
+\r
+       /**\r
+        * Determines whether or not the specified user (by default the current one) can edit metadata on the entity\r
+        *\r
+        * @param ElggMetadata $metadata The piece of metadata to specifically check\r
+        * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user)\r
+        * @return true|false\r
+        */\r
+       function canEditMetadata($metadata = null, $user_guid = 0) {\r
+               return can_edit_entity_metadata($this->getGUID(), $user_guid, $metadata);\r
+       }\r
+\r
+       /**\r
+        * Returns whether the given user (or current user) has the ability to write to this container.\r
+        *\r
+        * @param int $user_guid The user.\r
+        * @return bool\r
+        */\r
+       public function canWriteToContainer($user_guid = 0) {\r
+               return can_write_to_container($user_guid, $this->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Obtain this entity's access ID\r
+        *\r
+        * @return int The access ID\r
+        */\r
+       public function getAccessID() {\r
+               return $this->get('access_id');\r
+       }\r
+\r
+       /**\r
+        * Obtain this entity's GUID\r
+        *\r
+        * @return int GUID\r
+        */\r
+       public function getGUID() {\r
+               return $this->get('guid');\r
+       }\r
+\r
+       /**\r
+        * Get the owner of this entity\r
+        *\r
+        * @return int The owner GUID\r
+        */\r
+       public function getOwner() {\r
+               return $this->get('owner_guid');\r
+       }\r
+\r
+       /**\r
+        * Returns the actual entity of the user who owns this entity, if any\r
+        *\r
+        * @return ElggEntity The owning user\r
+        */\r
+       public function getOwnerEntity() {\r
+               return get_entity($this->get('owner_guid'));\r
+       }\r
+\r
+       /**\r
+        * Gets the type of entity this is\r
+        *\r
+        * @return string Entity type\r
+        */\r
+       public function getType() {\r
+               return $this->get('type');\r
+       }\r
+\r
+       /**\r
+        * Returns the subtype of this entity\r
+        *\r
+        * @return string The entity subtype\r
+        */\r
+       public function getSubtype() {\r
+               // If this object hasn't been saved, then return the subtype string.\r
+               if (!((int) $this->guid > 0)) {\r
+                       return $this->get('subtype');\r
+               }\r
+\r
+               return get_subtype_from_id($this->get('subtype'));\r
+       }\r
+\r
+       /**\r
+        * Gets the UNIX epoch time that this entity was created\r
+        *\r
+        * @return int UNIX epoch time\r
+        */\r
+       public function getTimeCreated() {\r
+               return $this->get('time_created');\r
+       }\r
+\r
+       /**\r
+        * Gets the UNIX epoch time that this entity was last updated\r
+        *\r
+        * @return int UNIX epoch time\r
+        */\r
+       public function getTimeUpdated() {\r
+               return $this->get('time_updated');\r
+       }\r
+\r
+       /**\r
+        * Gets the display URL for this entity\r
+        *\r
+        * @return string The URL\r
+        */\r
+       public function getURL() {\r
+               if (!empty($this->url_override)) {\r
+                       return $this->url_override;\r
+               }\r
+               return get_entity_url($this->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Overrides the URL returned by getURL\r
+        *\r
+        * @param string $url The new item URL\r
+        * @return string The URL\r
+        */\r
+       public function setURL($url) {\r
+               $this->url_override = $url;\r
+               return $url;\r
+       }\r
+\r
+       /**\r
+        * Return a url for the entity's icon, trying multiple alternatives.\r
+        *\r
+        * @param string $size Either 'large','medium','small' or 'tiny'\r
+        * @return string The url or false if no url could be worked out.\r
+        */\r
+       public function getIcon($size = 'medium') {\r
+               if (isset($this->icon_override[$size])) {\r
+                       return $this->icon_override[$size];\r
+               }\r
+               return get_entity_icon_url($this, $size);\r
+       }\r
+\r
+       /**\r
+        * Set an icon override for an icon and size.\r
+        *\r
+        * @param string $url The url of the icon.\r
+        * @param string $size The size its for.\r
+        * @return bool\r
+        */\r
+       public function setIcon($url, $size = 'medium') {\r
+               $url = sanitise_string($url);\r
+               $size = sanitise_string($size);\r
+\r
+               if (!$this->icon_override) {\r
+                       $this->icon_override = array();\r
+               }\r
+               $this->icon_override[$size] = $url;\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Tests to see whether the object has been fully loaded.\r
+        *\r
+        * @return bool\r
+        */\r
+       public function isFullyLoaded() {\r
+               return ! ($this->attributes['tables_loaded'] < $this->attributes['tables_split']);\r
+       }\r
+\r
+       /**\r
+        * Save generic attributes to the entities table.\r
+        */\r
+       public function save() {\r
+               $guid = (int) $this->guid;\r
+               if ($guid > 0) {\r
+                       cache_entity($this);\r
+\r
+                       return update_entity(\r
+                               $this->get('guid'),\r
+                               $this->get('owner_guid'),\r
+                               $this->get('access_id'),\r
+                               $this->get('container_guid')\r
+                       );\r
+               } else {\r
+                       // Create a new entity (nb: using attribute array directly 'cos set function does something special!)\r
+                       $this->attributes['guid'] = create_entity($this->attributes['type'], $this->attributes['subtype'], $this->attributes['owner_guid'], $this->attributes['access_id'], $this->attributes['site_guid'], $this->attributes['container_guid']);\r
+                       if (!$this->attributes['guid']) {\r
+                               throw new IOException(elgg_echo('IOException:BaseEntitySaveFailed'));\r
+                       }\r
+\r
+                       // Save any unsaved metadata\r
+                       // @todo How to capture extra information (access id etc)\r
+                       if (sizeof($this->temp_metadata) > 0) {\r
+                               foreach($this->temp_metadata as $name => $value) {\r
+                                       $this->$name = $value;\r
+                                       unset($this->temp_metadata[$name]);\r
+                               }\r
+                       }\r
+\r
+                       // Save any unsaved annotations metadata.\r
+                       // @todo How to capture extra information (access id etc)\r
+                       if (sizeof($this->temp_annotations) > 0) {\r
+                               foreach($this->temp_annotations as $name => $value) {\r
+                                       $this->annotate($name, $value);\r
+                                       unset($this->temp_annotations[$name]);\r
+                               }\r
+                       }\r
+\r
+                       // set the subtype to id now rather than a string\r
+                       $this->attributes['subtype'] = get_subtype_id($this->attributes['type'], $this->attributes['subtype']);\r
+\r
+                       // Cache object handle\r
+                       if ($this->attributes['guid']) {\r
+                               cache_entity($this);\r
+                       }\r
+\r
+                       return $this->attributes['guid'];\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Load the basic entity information and populate base attributes array.\r
+        *\r
+        * @param int $guid\r
+        */\r
+       protected function load($guid) {\r
+               $row = get_entity_as_row($guid);\r
+\r
+               if ($row) {\r
+                       // Create the array if necessary - all subclasses should test before creating\r
+                       if (!is_array($this->attributes)) {\r
+                               $this->attributes = array();\r
+                       }\r
+\r
+                       // Now put these into the attributes array as core values\r
+                       $objarray = (array) $row;\r
+                       foreach($objarray as $key => $value) {\r
+                               $this->attributes[$key] = $value;\r
+                       }\r
+\r
+                       // Increment the portion counter\r
+                       if (!$this->isFullyLoaded()) {\r
+                               $this->attributes['tables_loaded']++;\r
+                       }\r
+\r
+                       // Cache object handle\r
+                       if ($this->attributes['guid']) {\r
+                               cache_entity($this);\r
+                       }\r
+\r
+                       return true;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Disable this entity.\r
+        *\r
+        * @param string $reason Optional reason\r
+        * @param bool $recursive Recursively disable all contained entities?\r
+        */\r
+       public function disable($reason = "", $recursive = true) {\r
+               return disable_entity($this->get('guid'), $reason, $recursive);\r
+       }\r
+\r
+       /**\r
+        * Re-enable this entity.\r
+        */\r
+       public function enable() {\r
+               return enable_entity($this->get('guid'));\r
+       }\r
+\r
+       /**\r
+        * Is this entity enabled?\r
+        *\r
+        * @return boolean\r
+        */\r
+       public function isEnabled() {\r
+               if ($this->enabled == 'yes') {\r
+                       return true;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Delete this entity.\r
+        */\r
+       public function delete() {\r
+               return delete_entity($this->get('guid'));\r
+       }\r
+\r
+       // LOCATABLE INTERFACE /////////////////////////////////////////////////////////////\r
+\r
+       /** Interface to set the location */\r
+       public function setLocation($location) {\r
+               $location = sanitise_string($location);\r
+\r
+               $this->location = $location;\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Set latitude and longitude tags for a given entity.\r
+        *\r
+        * @param float $lat\r
+        * @param float $long\r
+        */\r
+       public function setLatLong($lat, $long) {\r
+               $lat = sanitise_string($lat);\r
+               $long = sanitise_string($long);\r
+\r
+               $this->set('geo:lat', $lat);\r
+               $this->set('geo:long', $long);\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Get the contents of the ->geo:lat field.\r
+        *\r
+        */\r
+       public function getLatitude() {\r
+               return $this->get('geo:lat');\r
+       }\r
+\r
+       /**\r
+        * Get the contents of the ->geo:lat field.\r
+        *\r
+        */\r
+       public function getLongitude() {\r
+               return $this->get('geo:long');\r
+       }\r
+\r
+       /**\r
+        * Get the ->location metadata.\r
+        *\r
+        */\r
+       public function getLocation() {\r
+               return $this->get('location');\r
+       }\r
+\r
+       // NOTABLE INTERFACE ///////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Calendar functionality.\r
+        * This function sets the time of an object on a calendar listing.\r
+        *\r
+        * @param int $hour If ommitted, now is assumed.\r
+        * @param int $minute If ommitted, now is assumed.\r
+        * @param int $second If ommitted, now is assumed.\r
+        * @param int $day If ommitted, now is assumed.\r
+        * @param int $month If ommitted, now is assumed.\r
+        * @param int $year If ommitted, now is assumed.\r
+        * @param int $duration Duration of event, remainder of the day is assumed.\r
+        */\r
+       public function setCalendarTimeAndDuration($hour = NULL, $minute = NULL, $second = NULL, $day = NULL, $month = NULL, $year = NULL, $duration = NULL) {\r
+               $start = mktime($hour, $minute, $second, $month, $day, $year);\r
+               $end = $start + abs($duration);\r
+               if (!$duration) {\r
+                       $end = get_day_end($day,$month,$year);\r
+               }\r
+\r
+               $this->calendar_start = $start;\r
+               $this->calendar_end = $end;\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Return the start timestamp.\r
+        */\r
+       public function getCalendarStartTime() {\r
+               return (int)$this->calendar_start;\r
+       }\r
+\r
+       /**\r
+        * Return the end timestamp.\r
+        */\r
+       public function getCalendarEndTime() {\r
+               return (int)$this->calendar_end;\r
+       }\r
+\r
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an array of fields which can be exported.\r
+        */\r
+       public function getExportableValues() {\r
+               return array(\r
+                       'guid',\r
+                       'type',\r
+                       'subtype',\r
+                       'time_created',\r
+                       'time_updated',\r
+                       'container_guid',\r
+                       'owner_guid',\r
+                       'site_guid'\r
+               );\r
+       }\r
+\r
+       /**\r
+        * Export this class into an array of ODD Elements containing all necessary fields.\r
+        * Override if you wish to return more information than can be found in $this->attributes (shouldn't happen)\r
+        */\r
+       public function export() {\r
+               $tmp = array();\r
+\r
+               // Generate uuid\r
+               $uuid = guid_to_uuid($this->getGUID());\r
+\r
+               // Create entity\r
+               $odd = new ODDEntity(\r
+                       $uuid,\r
+                       $this->attributes['type'],\r
+                       get_subtype_from_id($this->attributes['subtype'])\r
+               );\r
+\r
+               $tmp[] = $odd;\r
+\r
+               $exportable_values = $this->getExportableValues();\r
+\r
+               // Now add its attributes\r
+               foreach ($this->attributes as $k => $v) {\r
+                       $meta = NULL;\r
+\r
+                       if (in_array( $k, $exportable_values)) {\r
+                               switch ($k) {\r
+                                       case 'guid' :                   // Dont use guid in OpenDD\r
+                                       case 'type' :                   // Type and subtype already taken care of\r
+                                       case 'subtype' :\r
+                                       break;\r
+\r
+                                       case 'time_created' :   // Created = published\r
+                                               $odd->setAttribute('published', date("r", $v));\r
+                                       break;\r
+\r
+                                       case 'site_guid' : // Container\r
+                                               $k = 'site_uuid';\r
+                                               $v = guid_to_uuid($v);\r
+                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);\r
+                                       break;\r
+\r
+                                       case 'container_guid' : // Container\r
+                                               $k = 'container_uuid';\r
+                                               $v = guid_to_uuid($v);\r
+                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);\r
+                                       break;\r
+\r
+                                       case 'owner_guid' :                     // Convert owner guid to uuid, this will be stored in metadata\r
+                                               $k = 'owner_uuid';\r
+                                               $v = guid_to_uuid($v);\r
+                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);\r
+                                       break;\r
+\r
+                                       default :\r
+                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);\r
+                               }\r
+\r
+                               // set the time of any metadata created\r
+                               if ($meta) {\r
+                                       $meta->setAttribute('published', date("r",$this->time_created));\r
+                                       $tmp[] = $meta;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Now we do something a bit special.\r
+               /*\r
+                * This provides a rendered view of the entity to foreign sites.\r
+                */\r
+\r
+               elgg_set_viewtype('default');\r
+               $view = elgg_view_entity($this, true);\r
+               elgg_set_viewtype();\r
+\r
+               $tmp[] = new ODDMetaData($uuid . "volatile/renderedentity/", $uuid, 'renderedentity', $view , 'volatile');\r
+\r
+               return $tmp;\r
+       }\r
+\r
+       // IMPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Import data from an parsed xml data array.\r
+        *\r
+        * @param array $data\r
+        * @param int $version\r
+        */\r
+       public function import(ODD $data) {\r
+               if (!($data instanceof ODDEntity)) {\r
+                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass'));\r
+               }\r
+\r
+               // Set type and subtype\r
+               $this->attributes['type'] = $data->getAttribute('class');\r
+               $this->attributes['subtype'] = $data->getAttribute('subclass');\r
+\r
+               // Set owner\r
+               $this->attributes['owner_guid'] = get_loggedin_userid(); // Import as belonging to importer.\r
+\r
+               // Set time\r
+               $this->attributes['time_created'] = strtotime($data->getAttribute('published'));\r
+               $this->attributes['time_updated'] = time();\r
+\r
+               return true;\r
+       }\r
+\r
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an identification for the object for storage in the system log.\r
+        * This id must be an integer.\r
+        *\r
+        * @return int\r
+        */\r
+       public function getSystemLogID() {\r
+               return $this->getGUID();\r
+       }\r
+\r
+       /**\r
+        * Return the class name of the object.\r
+        */\r
+       public function getClassName() {\r
+               return get_class($this);\r
+       }\r
+\r
+       /**\r
+        * For a given ID, return the object associated with it.\r
+        * This is used by the river functionality primarily.\r
+        * This is useful for checking access permissions etc on objects.\r
+        */\r
+       public function getObjectFromID($id) {\r
+               return get_entity($id);\r
+       }\r
+\r
+       /**\r
+        * Return the GUID of the owner of this object.\r
+        */\r
+       public function getObjectOwnerGUID() {\r
+               return $this->owner_guid;\r
+       }\r
+\r
+       /**\r
+        * Returns tags for this entity.\r
+        *\r
+        * @param array $tag_names Optionally restrict by tag metadata names.\r
+        * @return array\r
+        */\r
+       public function getTags($tag_names = NULL) {\r
+               global $CONFIG;\r
+\r
+               if ($tag_names && !is_array($tag_names)) {\r
+                       $tag_names = array($tag_names);\r
+               }\r
+\r
+               $valid_tags = elgg_get_registered_tag_metadata_names();\r
+               $entity_tags = array();\r
+\r
+               foreach ($valid_tags as $tag_name) {\r
+                       if (is_array($tag_names) && !in_array($tag_name, $tag_names)) {\r
+                               continue;\r
+                       }\r
+\r
+                       if ($tags = $this->$tag_name) {\r
+                               // if a single tag, metadata returns a string.\r
+                               // if multiple tags, metadata returns an array.\r
+                               if (is_array($tags)) {\r
+                                       $entity_tags = array_merge($entity_tags, $tags);\r
+                               } else {\r
+                                       $entity_tags[] = $tags;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return $entity_tags;\r
+       }\r
+\r
+       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////\r
+       /*\r
+        * This lets an entity's attributes be displayed using foreach as a normal array.\r
+        * Example: http://www.sitepoint.com/print/php5-standard-library\r
+        */\r
+\r
+       private $valid = FALSE;\r
+\r
+       function rewind() {\r
+               $this->valid = (FALSE !== reset($this->attributes));\r
+       }\r
+\r
+       function current() {\r
+               return current($this->attributes);\r
+       }\r
+\r
+       function key() {\r
+               return key($this->attributes);\r
+       }\r
+\r
+       function next() {\r
+               $this->valid = (FALSE !== next($this->attributes));\r
+       }\r
+\r
+       function valid() {\r
+               return $this->valid;\r
+       }\r
+\r
+       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////\r
+       /*\r
+        * This lets an entity's attributes be accessed like an associative array.\r
+        * Example: http://www.sitepoint.com/print/php5-standard-library\r
+        */\r
+\r
+       function offsetSet($key, $value) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       $this->attributes[$key] = $value;\r
+               }\r
+       }\r
+\r
+       function offsetGet($key) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       return $this->attributes[$key];\r
+               }\r
+       }\r
+\r
+       function offsetUnset($key) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects\r
+               }\r
+       }\r
+\r
+       function offsetExists($offset) {\r
+               return array_key_exists($offset, $this->attributes);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggExtender.php b/engine/classes/ElggExtender.php
new file mode 100644 (file)
index 0000000..ec7a21f
--- /dev/null
@@ -0,0 +1,252 @@
+<?php\r
+\r
+/**\r
+ * ElggExtender\r
+ *\r
+ * @author Curverider Ltd\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+abstract class ElggExtender implements\r
+       Exportable,\r
+       Loggable,       // Can events related to this object class be logged\r
+       Iterator,       // Override foreach behaviour\r
+       ArrayAccess // Override for array access\r
+{\r
+       /**\r
+        * This contains the site's main properties (id, etc)\r
+        * @var array\r
+        */\r
+       protected $attributes;\r
+\r
+       /**\r
+        * Get an attribute\r
+        *\r
+        * @param string $name\r
+        * @return mixed\r
+        */\r
+       protected function get($name) {\r
+               if (isset($this->attributes[$name])) {\r
+                       // Sanitise value if necessary\r
+                       if ($name=='value') {\r
+                               switch ($this->attributes['value_type']) {\r
+                                       case 'integer' :\r
+                                               return (int)$this->attributes['value'];\r
+\r
+                                       //case 'tag' :\r
+                                       //case 'file' :\r
+                                       case 'text' :\r
+                                               return ($this->attributes['value']);\r
+\r
+                                       default :\r
+                                               throw new InstallationException(sprintf(elgg_echo('InstallationException:TypeNotSupported'), $this->attributes['value_type']));\r
+                               }\r
+                       }\r
+\r
+                       return $this->attributes[$name];\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Set an attribute\r
+        *\r
+        * @param string $name\r
+        * @param mixed $value\r
+        * @param string $value_type\r
+        * @return boolean\r
+        */\r
+       protected function set($name, $value, $value_type = "") {\r
+               $this->attributes[$name] = $value;\r
+               if ($name == 'value') {\r
+                       $this->attributes['value_type'] = detect_extender_valuetype($value, $value_type);\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Return the owner of this annotation.\r
+        *\r
+        * @return mixed\r
+        */\r
+       public function getOwner() {\r
+               return $this->owner_guid;\r
+       }\r
+\r
+       /**\r
+        * Return the owner entity\r
+        *\r
+        * @return mixed\r
+        * @since 1.7.0\r
+        */\r
+       public function getOwnerEntity() {\r
+               return get_user($this->owner_guid);\r
+       }\r
+\r
+       /**\r
+        * Returns the entity this is attached to\r
+        *\r
+        * @return ElggEntity The enttiy\r
+        */\r
+       public function getEntity() {\r
+               return get_entity($this->entity_guid);\r
+       }\r
+\r
+       /**\r
+        * Save this data to the appropriate database table.\r
+        */\r
+       abstract public function save();\r
+\r
+       /**\r
+        * Delete this data.\r
+        */\r
+       abstract public function delete();\r
+\r
+       /**\r
+        * Determines whether or not the specified user can edit this\r
+        *\r
+        * @param int $user_guid The GUID of the user (defaults to currently logged in user)\r
+        * @return true|false\r
+        */\r
+       public function canEdit($user_guid = 0) {\r
+               return can_edit_extender($this->id,$this->type,$user_guid);\r
+       }\r
+\r
+       /**\r
+        * Return a url for this extender.\r
+        *\r
+        * @return string\r
+        */\r
+       public abstract function getURL();\r
+\r
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an array of fields which can be exported.\r
+        */\r
+       public function getExportableValues() {\r
+               return array(\r
+                       'id',\r
+                       'entity_guid',\r
+                       'name',\r
+                       'value',\r
+                       'value_type',\r
+                       'owner_guid',\r
+                       'type',\r
+               );\r
+       }\r
+\r
+       /**\r
+        * Export this object\r
+        *\r
+        * @return array\r
+        */\r
+       public function export() {\r
+               $uuid = get_uuid_from_object($this);\r
+\r
+               $meta = new ODDMetadata($uuid, guid_to_uuid($this->entity_guid), $this->attributes['name'], $this->attributes['value'], $this->attributes['type'], guid_to_uuid($this->owner_guid));\r
+               $meta->setAttribute('published', date("r", $this->time_created));\r
+\r
+               return $meta;\r
+       }\r
+\r
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an identification for the object for storage in the system log.\r
+        * This id must be an integer.\r
+        *\r
+        * @return int\r
+        */\r
+       public function getSystemLogID() {\r
+               return $this->id;\r
+       }\r
+\r
+       /**\r
+        * Return the class name of the object.\r
+        */\r
+       public function getClassName() {\r
+               return get_class($this);\r
+       }\r
+\r
+       /**\r
+        * Return the GUID of the owner of this object.\r
+        */\r
+       public function getObjectOwnerGUID() {\r
+               return $this->owner_guid;\r
+       }\r
+\r
+       /**\r
+        * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc\r
+        */\r
+       public function getType() {\r
+               return $this->type;\r
+       }\r
+\r
+       /**\r
+        * Return a subtype. For metadata & annotations this is the 'name' and\r
+        * for relationship this is the relationship type.\r
+        */\r
+       public function getSubtype() {\r
+               return $this->name;\r
+       }\r
+\r
+\r
+       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////\r
+       /*\r
+        * This lets an entity's attributes be displayed using foreach as a normal array.\r
+        * Example: http://www.sitepoint.com/print/php5-standard-library\r
+        */\r
+\r
+       private $valid = FALSE;\r
+\r
+       function rewind() {\r
+               $this->valid = (FALSE !== reset($this->attributes));\r
+       }\r
+\r
+       function current() {\r
+               return current($this->attributes);\r
+       }\r
+\r
+       function key() {\r
+               return key($this->attributes);\r
+       }\r
+\r
+       function next() {\r
+               $this->valid = (FALSE !== next($this->attributes));\r
+       }\r
+\r
+       function valid() {\r
+               return $this->valid;\r
+       }\r
+\r
+       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////\r
+       /*\r
+        * This lets an entity's attributes be accessed like an associative array.\r
+        * Example: http://www.sitepoint.com/print/php5-standard-library\r
+        */\r
+\r
+       function offsetSet($key, $value) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       $this->attributes[$key] = $value;\r
+               }\r
+       }\r
+\r
+       function offsetGet($key) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       return $this->attributes[$key];\r
+               }\r
+       }\r
+\r
+       function offsetUnset($key) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       // Full unsetting is dangerious for our objects\r
+                       $this->attributes[$key] = "";\r
+               }\r
+       }\r
+\r
+       function offsetExists($offset) {\r
+               return array_key_exists($offset, $this->attributes);\r
+       }\r
+}\r
diff --git a/engine/classes/ElggFile.php b/engine/classes/ElggFile.php
new file mode 100644 (file)
index 0000000..68ed2f2
--- /dev/null
@@ -0,0 +1,318 @@
+<?php
+
+/**
+ * @class ElggFile
+ * This class represents a physical file.
+ *
+ * Usage:
+ *             Create a new ElggFile object and specify a filename, and optionally a FileStore (if one isn't specified
+ *             then the default is assumed.
+ *
+ *             Open the file using the appropriate mode, and you will be able to read and write to the file.
+ *
+ *             Optionally, you can also call the file's save() method, this will turn the file into an entity in the
+ *             system and permit you to do things like attach tags to the file etc. This is not done automatically since
+ *             there are many occasions where you may want access to file data on datastores using the ElggFile interface
+ *             but do not want to create an Entity reference to it in the system (temporary files for example).
+ *
+ * @author Curverider Ltd
+ */
+class ElggFile extends ElggObject {
+       /** Filestore */
+       private $filestore;
+
+       /** File handle used to identify this file in a filestore. Created by open. */
+       private $handle;
+
+       protected function initialise_attributes() {
+               parent::initialise_attributes();
+
+               $this->attributes['subtype'] = "file";
+       }
+
+       public function __construct($guid = null) {
+               parent::__construct($guid);
+
+               // Set default filestore
+               $this->filestore = $this->getFilestore();
+       }
+
+       /**
+        * Set the filename of this file.
+        *
+        * @param string $name The filename.
+        */
+       public function setFilename($name) {
+               $this->filename = $name;
+       }
+
+       /**
+        * Return the filename.
+        */
+       public function getFilename() {
+               return $this->filename;
+       }
+
+       /**
+        * Return the filename of this file as it is/will be stored on the filestore, which may be different
+        * to the filename.
+        */
+       public function getFilenameOnFilestore() {
+               return $this->filestore->getFilenameOnFilestore($this);
+       }
+
+       /*
+        * Return the size of the filestore associated with this file
+        *
+        */
+       public function getFilestoreSize($prefix='',$container_guid=0) {
+               if (!$container_guid) {
+                       $container_guid = $this->container_guid;
+               }
+               $fs = $this->getFilestore();
+               return $fs->getSize($prefix,$container_guid);
+       }
+
+       /**
+        * Get the mime type of the file.
+        */
+       public function getMimeType() {
+               if ($this->mimetype) {
+                       return $this->mimetype;
+               }
+
+               // @todo Guess mimetype if not here
+       }
+
+       /**
+        * Set the mime type of the file.
+        *
+        * @param $mimetype The mimetype
+        */
+       public function setMimeType($mimetype) {
+               return $this->mimetype = $mimetype;
+       }
+
+       /**
+        * Set the optional file description.
+        *
+        * @param string $description The description.
+        */
+       public function setDescription($description) {
+               $this->description = $description;
+       }
+
+       /**
+        * Open the file with the given mode
+        *
+        * @param string $mode Either read/write/append
+        */
+       public function open($mode) {
+               if (!$this->getFilename()) {
+                       throw new IOException(elgg_echo('IOException:MissingFileName'));
+               }
+
+               // See if file has already been saved
+               // seek on datastore, parameters and name?
+
+               // Sanity check
+               if (
+                       ($mode!="read") &&
+                       ($mode!="write") &&
+                       ($mode!="append")
+               ) {
+                       throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode));
+               }
+
+               // Get the filestore
+               $fs = $this->getFilestore();
+
+               // Ensure that we save the file details to object store
+               //$this->save();
+
+               // Open the file handle
+               $this->handle = $fs->open($this, $mode);
+
+               return $this->handle;
+       }
+
+       /**
+        * Write some data.
+        *
+        * @param string $data The data
+        */
+       public function write($data) {
+               $fs = $this->getFilestore();
+
+               return $fs->write($this->handle, $data);
+       }
+
+       /**
+        * Read some data.
+        *
+        * @param int $length Amount to read.
+        * @param int $offset The offset to start from.
+        */
+       public function read($length, $offset = 0) {
+               $fs = $this->getFilestore();
+
+               return $fs->read($this->handle, $length, $offset);
+       }
+
+       /**
+        * Gets the full contents of this file.
+        *
+        * @return mixed The file contents.
+        */
+       public function grabFile() {
+               $fs = $this->getFilestore();
+               return $fs->grabFile($this);
+       }
+
+       /**
+        * Close the file and commit changes
+        */
+       public function close() {
+               $fs = $this->getFilestore();
+
+               if ($fs->close($this->handle)) {
+                       $this->handle = NULL;
+
+                       return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * Delete this file.
+        */
+       public function delete() {
+               $fs = $this->getFilestore();
+               if ($fs->delete($this)) {
+                       return parent::delete();
+               }
+       }
+
+       /**
+        * Seek a position in the file.
+        *
+        * @param int $position
+        */
+       public function seek($position) {
+               $fs = $this->getFilestore();
+
+               return $fs->seek($this->handle, $position);
+       }
+
+       /**
+        * Return the current position of the file.
+        *
+        * @return int The file position
+        */
+       public function tell() {
+               $fs = $this->getFilestore();
+
+               return $fs->tell($this->handle);
+       }
+
+       /**
+        * Return the size of the file in bytes.
+        */
+       public function size() {
+               return $this->filestore->getFileSize($this);
+       }
+
+       /**
+        * Return a boolean value whether the file handle is at the end of the file
+        */
+       public function eof() {
+               $fs = $this->getFilestore();
+
+               return $fs->eof($this->handle);
+       }
+
+       public function exists() {
+               $fs = $this->getFilestore();
+
+               return $fs->exists($this);
+       }
+
+       /**
+        * Set a filestore.
+        *
+        * @param ElggFilestore $filestore The file store.
+        */
+       public function setFilestore(ElggFilestore $filestore) {
+               $this->filestore = $filestore;
+       }
+
+       /**
+        * Return a filestore suitable for saving this file.
+        * This filestore is either a pre-registered filestore, a filestore loaded from metatags saved
+        * along side this file, or the system default.
+        */
+       protected function getFilestore() {
+               // Short circuit if already set.
+               if ($this->filestore) {
+                       return $this->filestore;
+               }
+
+               // If filestore meta set then retrieve filestore
+               // @todo Better way of doing this?
+               $metas = get_metadata_for_entity($this->guid);
+               $parameters = array();
+               if (is_array($metas)) {
+                       foreach ($metas as $meta) {
+                               if (strpos($meta->name, "filestore::")!==false) {
+                                       // Filestore parameter tag
+                                       $comp = explode("::", $meta->name);
+                                       $name = $comp[1];
+
+                                       $parameters[$name] = $meta->value;
+                               }
+                       }
+               }
+
+               if (isset($parameters['filestore'])) {
+                       if (!class_exists($parameters['filestore'])) {
+                               $msg = sprintf(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile'),
+                                                               $parameters['filestore'],
+                                                               $this->guid);
+                               throw new ClassNotFoundException($msg);
+                       }
+
+                       // Create new filestore object
+                       $this->filestore = new $parameters['filestore']();
+
+                       $this->filestore->setParameters($parameters);
+               } else {
+                       // @todo - should we log error if filestore not set
+               }
+
+
+               // if still nothing then set filestore to default
+               if (!$this->filestore) {
+                       $this->filestore = get_default_filestore();
+               }
+
+               return $this->filestore;
+       }
+
+       public function save() {
+               if (!parent::save()) {
+                       return false;
+               }
+
+               // Save datastore metadata
+               $params = $this->filestore->getParameters();
+               foreach ($params as $k => $v) {
+                       $this->setMetaData("filestore::$k", $v);
+               }
+
+               // Now make a note of the filestore class
+               $this->setMetaData("filestore::filestore", get_class($this->filestore));
+
+               return true;
+       }
+}
diff --git a/engine/classes/ElggFileCache.php b/engine/classes/ElggFileCache.php
new file mode 100644 (file)
index 0000000..b8989a9
--- /dev/null
@@ -0,0 +1,164 @@
+<?php\r
+/**\r
+ * ElggFileCache\r
+ * Store cached data in a file store.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage API\r
+ */\r
+class ElggFileCache extends ElggCache {\r
+       /**\r
+        * Set the Elgg cache.\r
+        *\r
+        * @param string $cache_path The cache path.\r
+        * @param int $max_age Maximum age in seconds, 0 if no limit.\r
+        * @param int $max_size Maximum size of cache in seconds, 0 if no limit.\r
+        */\r
+       function __construct($cache_path, $max_age = 0, $max_size = 0) {\r
+               $this->set_variable("cache_path", $cache_path);\r
+               $this->set_variable("max_age", $max_age);\r
+               $this->set_variable("max_size", $max_size);\r
+\r
+               if ($cache_path=="") {\r
+                       throw new ConfigurationException(elgg_echo('ConfigurationException:NoCachePath'));\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Create and return a handle to a file.\r
+        *\r
+        * @param string $filename\r
+        * @param string $rw\r
+        */\r
+       protected function create_file($filename, $rw = "rb") {\r
+               // Create a filename matrix\r
+               $matrix = "";\r
+               $depth = strlen($filename);\r
+               if ($depth > 5) {\r
+                       $depth = 5;\r
+               }\r
+\r
+               // Create full path\r
+               $path = $this->get_variable("cache_path") . $matrix;\r
+               if (!is_dir($path)) {\r
+                       mkdir($path, 0700, true);\r
+               }\r
+\r
+               // Open the file\r
+               if ((!file_exists($path . $filename)) && ($rw=="rb")) {\r
+                       return false;\r
+               }\r
+\r
+               return fopen($path . $filename, $rw);\r
+       }\r
+\r
+       /**\r
+        * Create a sanitised filename for the file.\r
+        *\r
+        * @param string $filename\r
+        */\r
+       protected function sanitise_filename($filename) {\r
+               // @todo : Writeme\r
+\r
+               return $filename;\r
+       }\r
+\r
+       /**\r
+        * Save a key\r
+        *\r
+        * @param string $key\r
+        * @param string $data\r
+        * @return boolean\r
+        */\r
+       public function save($key, $data) {\r
+               $f = $this->create_file($this->sanitise_filename($key), "wb");\r
+               if ($f) {\r
+                       $result = fwrite($f, $data);\r
+                       fclose($f);\r
+\r
+                       return $result;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Load a key\r
+        *\r
+        * @param string $key\r
+        * @param int $offset\r
+        * @param int $limit\r
+        * @return string\r
+        */\r
+       public function load($key, $offset = 0, $limit = null) {\r
+               $f = $this->create_file($this->sanitise_filename($key));\r
+               if ($f) {\r
+                       //fseek($f, $offset);\r
+                       if (!$limit) {\r
+                               $limit = -1;\r
+                       }\r
+                       $data = stream_get_contents($f, $limit, $offset);\r
+\r
+                       fclose($f);\r
+\r
+                       return $data;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Invalidate a given key.\r
+        *\r
+        * @param string $key\r
+        * @return bool\r
+        */\r
+       public function delete($key) {\r
+               $dir = $this->get_variable("cache_path");\r
+               \r
+               if (file_exists($dir.$key)) {\r
+                       return unlink($dir.$key);\r
+               }\r
+               return TRUE;\r
+       }\r
+\r
+       public function clear() {\r
+               // @todo writeme\r
+       }\r
+\r
+       public function __destruct() {\r
+               // @todo Check size and age, clean up accordingly\r
+               $size = 0;\r
+               $dir = $this->get_variable("cache_path");\r
+\r
+               // Short circuit if both size and age are unlimited\r
+               if (($this->get_variable("max_age")==0) && ($this->get_variable("max_size")==0)) {\r
+                       return;\r
+               }\r
+\r
+               $exclude = array(".","..");\r
+\r
+               $files = scandir($dir);\r
+               if (!$files) {\r
+                       throw new IOException(sprintf(elgg_echo('IOException:NotDirectory'), $dir));\r
+               }\r
+\r
+               // Perform cleanup\r
+               foreach ($files as $f) {\r
+                       if (!in_array($f, $exclude)) {\r
+                               $stat = stat($dir.$f);\r
+\r
+                               // Add size\r
+                               $size .= $stat['size'];\r
+\r
+                               // Is this older than my maximum date?\r
+                               if (($this->get_variable("max_age")>0) && (time() - $stat['mtime'] > $this->get_variable("max_age"))) {\r
+                                       unlink($dir.$f);\r
+                               }\r
+\r
+                               // @todo Size\r
+                       }\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggFilestore.php b/engine/classes/ElggFilestore.php
new file mode 100644 (file)
index 0000000..3311842
--- /dev/null
@@ -0,0 +1,115 @@
+<?php\r
+/**\r
+ * @class ElggFilestore\r
+ * This class defines the interface for all elgg data repositories.\r
+ * @author Curverider Ltd\r
+ */\r
+abstract class ElggFilestore {\r
+       /**\r
+        * Attempt to open the file $file for storage or writing.\r
+        *\r
+        * @param ElggFile $file\r
+        * @param string $mode "read", "write", "append"\r
+        * @return mixed A handle to the opened file or false on error.\r
+        */\r
+       abstract public function open(ElggFile $file, $mode);\r
+\r
+       /**\r
+        * Write data to a given file handle.\r
+        *\r
+        * @param mixed $f The file handle - exactly what this is depends on the file system\r
+        * @param string $data The binary string of data to write\r
+        * @return int Number of bytes written.\r
+        */\r
+       abstract public function write($f, $data);\r
+\r
+       /**\r
+        * Read data from a filestore.\r
+        *\r
+        * @param mixed $f The file handle\r
+        * @param int $length Length in bytes to read.\r
+        * @param int $offset The optional offset.\r
+        * @return mixed String of data or false on error.\r
+        */\r
+       abstract public function read($f, $length, $offset = 0);\r
+\r
+       /**\r
+        * Seek a given position within a file handle.\r
+        *\r
+        * @param mixed $f The file handle.\r
+        * @param int $position The position.\r
+        */\r
+       abstract public function seek($f, $position);\r
+\r
+       /**\r
+        * Return a whether the end of a file has been reached.\r
+        *\r
+        * @param mixed $f The file handle.\r
+        * @return boolean\r
+        */\r
+       abstract public function eof($f);\r
+\r
+       /**\r
+        * Return the current position in an open file.\r
+        *\r
+        * @param mixed $f The file handle.\r
+        * @return int\r
+        */\r
+       abstract public function tell($f);\r
+\r
+       /**\r
+        * Close a given file handle.\r
+        *\r
+        * @param mixed $f\r
+        */\r
+       abstract public function close($f);\r
+\r
+       /**\r
+        * Delete the file associated with a given file handle.\r
+        *\r
+        * @param ElggFile $file\r
+        */\r
+       abstract public function delete(ElggFile $file);\r
+\r
+       /**\r
+        * Return the size in bytes for a given file.\r
+        *\r
+        * @param ElggFile $file\r
+        */\r
+       abstract public function getFileSize(ElggFile $file);\r
+\r
+       /**\r
+        * Return the filename of a given file as stored on the filestore.\r
+        *\r
+        * @param ElggFile $file\r
+        */\r
+       abstract public function getFilenameOnFilestore(ElggFile $file);\r
+\r
+       /**\r
+        * Get the filestore's creation parameters as an associative array.\r
+        * Used for serialisation and for storing the creation details along side a file object.\r
+        *\r
+        * @return array\r
+        */\r
+       abstract public function getParameters();\r
+\r
+       /**\r
+        * Set the parameters from the associative array produced by $this->getParameters().\r
+        */\r
+       abstract public function setParameters(array $parameters);\r
+\r
+       /**\r
+        * Get the contents of the whole file.\r
+        *\r
+        * @param mixed $file The file handle.\r
+        * @return mixed The file contents.\r
+        */\r
+       abstract public function grabFile(ElggFile $file);\r
+\r
+       /**\r
+        * Return whether a file physically exists or not.\r
+        *\r
+        * @param ElggFile $file\r
+        */\r
+       abstract public function exists(ElggFile $file);\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggGroup.php b/engine/classes/ElggGroup.php
new file mode 100644 (file)
index 0000000..9713ca3
--- /dev/null
@@ -0,0 +1,299 @@
+<?php\r
+\r
+/**\r
+ * @class ElggGroup Class representing a container for other elgg entities.\r
+ * @author Curverider Ltd\r
+ */\r
+class ElggGroup extends ElggEntity\r
+       implements Friendable {\r
+\r
+       protected function initialise_attributes() {\r
+               parent::initialise_attributes();\r
+\r
+               $this->attributes['type'] = "group";\r
+               $this->attributes['name'] = "";\r
+               $this->attributes['description'] = "";\r
+               $this->attributes['tables_split'] = 2;\r
+       }\r
+\r
+       /**\r
+        * Construct a new user entity, optionally from a given id value.\r
+        *\r
+        * @param mixed $guid If an int, load that GUID.\r
+        *      If a db row then will attempt to load the rest of the data.\r
+        * @throws Exception if there was a problem creating the user.\r
+        */\r
+       function __construct($guid = null) {\r
+               $this->initialise_attributes();\r
+\r
+               if (!empty($guid)) {\r
+                       // Is $guid is a DB row - either a entity row, or a user table row.\r
+                       if ($guid instanceof stdClass) {\r
+                               // Load the rest\r
+                               if (!$this->load($guid->guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));\r
+                               }\r
+                       }\r
+                       // Is $guid is an ElggGroup? Use a copy constructor\r
+                       else if ($guid instanceof ElggGroup) {\r
+                               elgg_deprecated_notice('This type of usage of the ElggGroup constructor was deprecated. Please use the clone method.', 1.7);\r
+\r
+                               foreach ($guid->attributes as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                       }\r
+                       // Is this is an ElggEntity but not an ElggGroup = ERROR!\r
+                       else if ($guid instanceof ElggEntity) {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggGroup'));\r
+                       }\r
+                       // We assume if we have got this far, $guid is an int\r
+                       else if (is_numeric($guid)) {\r
+                               if (!$this->load($guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));\r
+                               }\r
+                       }\r
+\r
+                       else {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Add an ElggObject to this group.\r
+        *\r
+        * @param ElggObject $object The object.\r
+        * @return bool\r
+        */\r
+       public function addObjectToGroup(ElggObject $object) {\r
+               return add_object_to_group($this->getGUID(), $object->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Remove an object from the containing group.\r
+        *\r
+        * @param int $guid The guid of the object.\r
+        * @return bool\r
+        */\r
+       public function removeObjectFromGroup($guid) {\r
+               return remove_object_from_group($this->getGUID(), $guid);\r
+       }\r
+\r
+       public function get($name) {\r
+               if ($name == 'username') {\r
+                       return 'group:' . $this->getGUID();\r
+               }\r
+               return parent::get($name);\r
+       }\r
+\r
+/**\r
+ * Start friendable compatibility block:\r
+ *\r
+ *     public function addFriend($friend_guid);\r
+       public function removeFriend($friend_guid);\r
+       public function isFriend();\r
+       public function isFriendsWith($user_guid);\r
+       public function isFriendOf($user_guid);\r
+       public function getFriends($subtype = "", $limit = 10, $offset = 0);\r
+       public function getFriendsOf($subtype = "", $limit = 10, $offset = 0);\r
+       public function getObjects($subtype="", $limit = 10, $offset = 0);\r
+       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0);\r
+       public function countObjects($subtype = "");\r
+ */\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function addFriend($friend_guid) {\r
+               return $this->join(get_entity($friend_guid));\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function removeFriend($friend_guid) {\r
+               return $this->leave(get_entity($friend_guid));\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function isFriend() {\r
+               return $this->isMember();\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function isFriendsWith($user_guid) {\r
+               return $this->isMember($user_guid);\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function isFriendOf($user_guid) {\r
+               return $this->isMember($user_guid);\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function getFriends($subtype = "", $limit = 10, $offset = 0) {\r
+               return get_group_members($this->getGUID(), $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function getFriendsOf($subtype = "", $limit = 10, $offset = 0) {\r
+               return get_group_members($this->getGUID(), $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Get objects contained in this group.\r
+        *\r
+        * @param string $subtype\r
+        * @param int $limit\r
+        * @param int $offset\r
+        * @return mixed\r
+        */\r
+       public function getObjects($subtype="", $limit = 10, $offset = 0) {\r
+               return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false);\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) {\r
+               return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false);\r
+       }\r
+\r
+       /**\r
+        * For compatibility with Friendable\r
+        */\r
+       public function countObjects($subtype = "") {\r
+               return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", 10, 0, true);\r
+       }\r
+\r
+/**\r
+ * End friendable compatibility block\r
+ */\r
+\r
+       /**\r
+        * Get a list of group members.\r
+        *\r
+        * @param int $limit\r
+        * @param int $offset\r
+        * @return mixed\r
+        */\r
+       public function getMembers($limit = 10, $offset = 0, $count = false) {\r
+               return get_group_members($this->getGUID(), $limit, $offset, 0 , $count);\r
+       }\r
+\r
+       /**\r
+        * Returns whether the current group is public membership or not.\r
+        * @return bool\r
+        */\r
+       public function isPublicMembership() {\r
+               if ($this->membership == ACCESS_PUBLIC) {\r
+                       return true;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Return whether a given user is a member of this group or not.\r
+        *\r
+        * @param ElggUser $user The user\r
+        * @return bool\r
+        */\r
+       public function isMember($user = 0) {\r
+               if (!($user instanceof ElggUser)) {\r
+                       $user = get_loggedin_user();\r
+               }\r
+               if (!($user instanceof ElggUser)) {\r
+                       return false;\r
+               }\r
+               return is_group_member($this->getGUID(), $user->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Join an elgg user to this group.\r
+        *\r
+        * @param ElggUser $user\r
+        * @return bool\r
+        */\r
+       public function join(ElggUser $user) {\r
+               return join_group($this->getGUID(), $user->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Remove a user from the group.\r
+        *\r
+        * @param ElggUser $user\r
+        */\r
+       public function leave(ElggUser $user) {\r
+               return leave_group($this->getGUID(), $user->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Override the load function.\r
+        * This function will ensure that all data is loaded (were possible), so\r
+        * if only part of the ElggGroup is loaded, it'll load the rest.\r
+        *\r
+        * @param int $guid\r
+        */\r
+       protected function load($guid) {\r
+               // Test to see if we have the generic stuff\r
+               if (!parent::load($guid)) {\r
+                       return false;\r
+               }\r
+\r
+               // Check the type\r
+               if ($this->attributes['type']!='group') {\r
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));\r
+               }\r
+\r
+               // Load missing data\r
+               $row = get_group_entity_as_row($guid);\r
+               if (($row) && (!$this->isFullyLoaded())) {\r
+                       // If $row isn't a cached copy then increment the counter\r
+                       $this->attributes['tables_loaded'] ++;\r
+               }\r
+\r
+               // Now put these into the attributes array as core values\r
+               $objarray = (array) $row;\r
+               foreach($objarray as $key => $value) {\r
+                       $this->attributes[$key] = $value;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Override the save function.\r
+        */\r
+       public function save() {\r
+               // Save generic stuff\r
+               if (!parent::save()) {\r
+                       return false;\r
+               }\r
+\r
+               // Now save specific stuff\r
+               return create_group_entity($this->get('guid'), $this->get('name'), $this->get('description'));\r
+       }\r
+\r
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an array of fields which can be exported.\r
+        */\r
+       public function getExportableValues() {\r
+               return array_merge(parent::getExportableValues(), array(\r
+                       'name',\r
+                       'description',\r
+               ));\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggHMACCache.php b/engine/classes/ElggHMACCache.php
new file mode 100644 (file)
index 0000000..8c50d7d
--- /dev/null
@@ -0,0 +1,94 @@
+<?php\r
+/**\r
+ * ElggHMACCache\r
+ * Store cached data in a temporary database, only used by the HMAC stuff.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage API\r
+ */\r
+class ElggHMACCache extends ElggCache {\r
+       /**\r
+        * Set the Elgg cache.\r
+        *\r
+        * @param int $max_age Maximum age in seconds, 0 if no limit.\r
+        */\r
+       function __construct($max_age = 0) {\r
+               $this->set_variable("max_age", $max_age);\r
+       }\r
+\r
+       /**\r
+        * Save a key\r
+        *\r
+        * @param string $key\r
+        * @param string $data\r
+        * @return boolean\r
+        */\r
+       public function save($key, $data) {\r
+               global $CONFIG;\r
+\r
+               $key = sanitise_string($key);\r
+               $time = time();\r
+\r
+               return insert_data("INSERT into {$CONFIG->dbprefix}hmac_cache (hmac, ts) VALUES ('$key', '$time')");\r
+       }\r
+\r
+       /**\r
+        * Load a key\r
+        *\r
+        * @param string $key\r
+        * @param int $offset\r
+        * @param int $limit\r
+        * @return string\r
+        */\r
+       public function load($key, $offset = 0, $limit = null) {\r
+               global $CONFIG;\r
+\r
+               $key = sanitise_string($key);\r
+\r
+               $row = get_data_row("SELECT * from {$CONFIG->dbprefix}hmac_cache where hmac='$key'");\r
+               if ($row) {\r
+                       return $row->hmac;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Invalidate a given key.\r
+        *\r
+        * @param string $key\r
+        * @return bool\r
+        */\r
+       public function delete($key) {\r
+               global $CONFIG;\r
+\r
+               $key = sanitise_string($key);\r
+\r
+               return delete_data("DELETE from {$CONFIG->dbprefix}hmac_cache where hmac='$key'");\r
+       }\r
+\r
+       /**\r
+        * Clear out all the contents of the cache.\r
+        *\r
+        * Not currently implemented in this cache type.\r
+        */\r
+       public function clear() {\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Clean out old stuff.\r
+        *\r
+        */\r
+       public function __destruct() {\r
+               global $CONFIG;\r
+\r
+               $time = time();\r
+               $age = (int)$this->get_variable("max_age");\r
+\r
+               $expires = $time-$age;\r
+\r
+               delete_data("DELETE from {$CONFIG->dbprefix}hmac_cache where ts<$expires");\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggMemcache.php b/engine/classes/ElggMemcache.php
new file mode 100644 (file)
index 0000000..5e898c2
--- /dev/null
@@ -0,0 +1,151 @@
+<?php\r
+/**\r
+ * Memcache wrapper class.\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ */\r
+class ElggMemcache extends ElggSharedMemoryCache {\r
+       /**\r
+        * Minimum version of memcached needed to run\r
+        *\r
+        */\r
+       private static $MINSERVERVERSION = '1.1.12';\r
+\r
+       /**\r
+        * Memcache object\r
+        */\r
+       private $memcache;\r
+\r
+       /**\r
+        * Expiry of saved items (default timeout after a day to prevent anything getting too stale)\r
+        */\r
+       private $expires = 86400;\r
+\r
+       /**\r
+        * The version of memcache running\r
+        */\r
+       private $version = 0;\r
+\r
+       /**\r
+        * Connect to memcache.\r
+        *\r
+        * @param string $cache_id The namespace for this cache to write to - note, namespaces of the same name are shared!\r
+        */\r
+       function __construct($namespace = 'default') {\r
+               global $CONFIG;\r
+\r
+               $this->setNamespace($namespace);\r
+\r
+               // Do we have memcache?\r
+               if (!class_exists('Memcache')) {\r
+                       throw new ConfigurationException(elgg_echo('memcache:notinstalled'));\r
+               }\r
+\r
+               // Create memcache object\r
+               $this->memcache = new Memcache;\r
+\r
+               // Now add servers\r
+               if (!$CONFIG->memcache_servers) {\r
+                       throw new ConfigurationException(elgg_echo('memcache:noservers'));\r
+               }\r
+\r
+               if (is_callable($this->memcache, 'addServer')) {\r
+                       foreach ($CONFIG->memcache_servers as $server) {\r
+                               if (is_array($server)) {\r
+                                       $this->memcache->addServer(\r
+                                               $server[0],\r
+                                               isset($server[1]) ? $server[1] : 11211,\r
+                                               isset($server[2]) ? $server[2] : true,\r
+                                               isset($server[3]) ? $server[3] : null,\r
+                                               isset($server[4]) ? $server[4] : 1,\r
+                                               isset($server[5]) ? $server[5] : 15,\r
+                                               isset($server[6]) ? $server[6] : true\r
+                                       );\r
+\r
+                               } else {\r
+                                       $this->memcache->addServer($server, 11211);\r
+                               }\r
+                       }\r
+               } else {\r
+                       elgg_log(elgg_echo('memcache:noaddserver'), 'ERROR');\r
+\r
+                       $server = $CONFIG->memcache_servers[0];\r
+                       if (is_array($server)) {\r
+                               $this->memcache->connect($server[0], $server[1]);\r
+                       } else {\r
+                               $this->memcache->addServer($server, 11211);\r
+                       }\r
+               }\r
+\r
+               // Get version\r
+               $this->version = $this->memcache->getversion();\r
+               if (version_compare($this->version, ElggMemcache::$MINSERVERVERSION, '<')) {\r
+                       throw new ConfigurationException(sprintf(elgg_echo('memcache:versiontoolow'), ElggMemcache::$MINSERVERVERSION, $this->version));\r
+               }\r
+\r
+               // Set some defaults\r
+               if (isset($CONFIG->memcache_expires)) {\r
+                       $this->expires = $CONFIG->memcache_expires;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Set the default expiry.\r
+        *\r
+        * @param int $expires The lifetime as a unix timestamp or time from now. Defaults forever.\r
+        */\r
+       public function setDefaultExpiry($expires = 0) {\r
+               $this->expires = $expires;\r
+       }\r
+\r
+       /**\r
+        * Combine a key with the namespace.\r
+        * Memcache can only accept <250 char key. If the given key is too long it is shortened.\r
+        *\r
+        * @param string $key The key\r
+        * @return string The new key.\r
+        */\r
+       private function make_memcache_key($key) {\r
+               $prefix = $this->getNamespace() . ":";\r
+\r
+               if (strlen($prefix.$key)> 250) {\r
+                       $key = md5($key);\r
+               }\r
+\r
+               return $prefix.$key;\r
+       }\r
+\r
+       public function save($key, $data) {\r
+               $key = $this->make_memcache_key($key);\r
+\r
+               $result = $this->memcache->set($key, $data, null, $this->expires);\r
+               if (!$result) {\r
+                       elgg_log("MEMCACHE: FAILED TO SAVE $key", 'ERROR');\r
+               }\r
+\r
+               return $result;\r
+       }\r
+\r
+       public function load($key, $offset = 0, $limit = null) {\r
+               $key = $this->make_memcache_key($key);\r
+\r
+               $result = $this->memcache->get($key);\r
+               if (!$result) {\r
+                       elgg_log("MEMCACHE: FAILED TO LOAD $key", 'ERROR');\r
+               }\r
+\r
+               return $result;\r
+       }\r
+\r
+       public function delete($key) {\r
+               $key = $this->make_memcache_key($key);\r
+\r
+               return $this->memcache->delete($key, 0);\r
+       }\r
+\r
+       public function clear() {\r
+               // DISABLE clearing for now - you must use delete on a specific key.\r
+               return true;\r
+\r
+               // @todo Namespaces as in #532\r
+       }\r
+}\r
diff --git a/engine/classes/ElggMetadata.php b/engine/classes/ElggMetadata.php
new file mode 100644 (file)
index 0000000..631b73c
--- /dev/null
@@ -0,0 +1,114 @@
+<?php\r
+\r
+/**\r
+ * ElggMetadata\r
+ * This class describes metadata that can be attached to ElggEntities.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+class ElggMetadata extends ElggExtender {\r
+       /**\r
+        * Construct a new site object, optionally from a given id value or row.\r
+        *\r
+        * @param mixed $id\r
+        */\r
+       function __construct($id = null) {\r
+               $this->attributes = array();\r
+\r
+               if (!empty($id)) {\r
+                       // Create from db row\r
+                       if ($id instanceof stdClass) {\r
+                               $metadata = $id;\r
+                       } else {\r
+                               $metadata = get_metadata($id);\r
+                       }\r
+\r
+                       if ($metadata) {\r
+                               $objarray = (array) $metadata;\r
+                               foreach($objarray as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                               $this->attributes['type'] = "metadata";\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Class member get overloading\r
+        *\r
+        * @param string $name\r
+        * @return mixed\r
+        */\r
+       function __get($name) {\r
+               return $this->get($name);\r
+       }\r
+\r
+       /**\r
+        * Class member set overloading\r
+        *\r
+        * @param string $name\r
+        * @param mixed $value\r
+        * @return mixed\r
+        */\r
+       function __set($name, $value) {\r
+               return $this->set($name, $value);\r
+       }\r
+\r
+       /**\r
+        * Determines whether or not the user can edit this piece of metadata\r
+        *\r
+        * @return true|false Depending on permissions\r
+        */\r
+       function canEdit() {\r
+               if ($entity = get_entity($this->get('entity_guid'))) {\r
+                       return $entity->canEditMetadata($this);\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Save matadata object\r
+        *\r
+        * @return int the metadata object id\r
+        */\r
+       function save() {\r
+               if ($this->id > 0) {\r
+                       return update_metadata($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);\r
+               } else {\r
+                       $this->id = create_metadata($this->entity_guid, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);\r
+                       if (!$this->id) {\r
+                               throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));\r
+                       }\r
+                       return $this->id;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Delete a given metadata.\r
+        */\r
+       function delete() {\r
+               return delete_metadata($this->id);\r
+       }\r
+\r
+       /**\r
+        * Get a url for this item of metadata.\r
+        *\r
+        * @return string\r
+        */\r
+       public function getURL() {\r
+               return get_metadata_url($this->id);\r
+       }\r
+\r
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * For a given ID, return the object associated with it.\r
+        * This is used by the river functionality primarily.\r
+        * This is useful for checking access permissions etc on objects.\r
+        */\r
+       public function getObjectFromID($id) {\r
+               return get_metadata($id);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggObject.php b/engine/classes/ElggObject.php
new file mode 100644 (file)
index 0000000..af67ef3
--- /dev/null
@@ -0,0 +1,199 @@
+<?php\r
+\r
+/**\r
+ * ElggObject\r
+ * Representation of an "object" in the system.\r
+ *\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+class ElggObject extends ElggEntity {\r
+       /**\r
+        * Initialise the attributes array.\r
+        * This is vital to distinguish between metadata and base parameters.\r
+        *\r
+        * Place your base parameters here.\r
+        */\r
+       protected function initialise_attributes() {\r
+               parent::initialise_attributes();\r
+\r
+               $this->attributes['type'] = "object";\r
+               $this->attributes['title'] = "";\r
+               $this->attributes['description'] = "";\r
+               $this->attributes['tables_split'] = 2;\r
+       }\r
+\r
+       /**\r
+        * Construct a new object entity, optionally from a given id value.\r
+        *\r
+        * @param mixed $guid If an int, load that GUID.\r
+        *      If a db row then will attempt to load the rest of the data.\r
+        * @throws Exception if there was a problem creating the object.\r
+        */\r
+       function __construct($guid = null) {\r
+               $this->initialise_attributes();\r
+\r
+               if (!empty($guid)) {\r
+                       // Is $guid is a DB row - either a entity row, or a object table row.\r
+                       if ($guid instanceof stdClass) {\r
+                               // Load the rest\r
+                               if (!$this->load($guid->guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));\r
+                               }\r
+                       }\r
+\r
+                       // Is $guid is an ElggObject? Use a copy constructor\r
+                       else if ($guid instanceof ElggObject) {\r
+                               elgg_deprecated_notice('This type of usage of the ElggObject constructor was deprecated. Please use the clone method.', 1.7);\r
+\r
+                               foreach ($guid->attributes as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                       }\r
+\r
+                       // Is this is an ElggEntity but not an ElggObject = ERROR!\r
+                       else if ($guid instanceof ElggEntity) {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggObject'));\r
+                       }\r
+\r
+                       // We assume if we have got this far, $guid is an int\r
+                       else if (is_numeric($guid)) {\r
+                               if (!$this->load($guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));\r
+                               }\r
+                       }\r
+\r
+                       else {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Override the load function.\r
+        * This function will ensure that all data is loaded (were possible), so\r
+        * if only part of the ElggObject is loaded, it'll load the rest.\r
+        *\r
+        * @param int $guid\r
+        * @return true|false\r
+        */\r
+       protected function load($guid) {\r
+               // Test to see if we have the generic stuff\r
+               if (!parent::load($guid)) {\r
+                       return false;\r
+               }\r
+\r
+               // Check the type\r
+               if ($this->attributes['type']!='object') {\r
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));\r
+               }\r
+\r
+               // Load missing data\r
+               $row = get_object_entity_as_row($guid);\r
+               if (($row) && (!$this->isFullyLoaded())) {\r
+                       // If $row isn't a cached copy then increment the counter\r
+                       $this->attributes['tables_loaded'] ++;\r
+               }\r
+\r
+               // Now put these into the attributes array as core values\r
+               $objarray = (array) $row;\r
+               foreach($objarray as $key => $value) {\r
+                       $this->attributes[$key] = $value;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Override the save function.\r
+        * @return true|false\r
+        */\r
+       public function save() {\r
+               // Save generic stuff\r
+               if (!parent::save()) {\r
+                       return false;\r
+               }\r
+\r
+               // Now save specific stuff\r
+               return create_object_entity($this->get('guid'), $this->get('title'), $this->get('description'), $this->get('container_guid'));\r
+       }\r
+\r
+       /**\r
+        * Get sites that this object is a member of\r
+        *\r
+        * @param string $subtype Optionally, the subtype of result we want to limit to\r
+        * @param int $limit The number of results to return\r
+        * @param int $offset Any indexing offset\r
+        */\r
+       function getSites($subtype="", $limit = 10, $offset = 0) {\r
+               return get_site_objects($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Add this object to a particular site\r
+        *\r
+        * @param int $site_guid The guid of the site to add it to\r
+        * @return true|false\r
+        */\r
+       function addToSite($site_guid) {\r
+               return add_site_object($this->getGUID(), $site_guid);\r
+       }\r
+\r
+       /**\r
+        * Set the container for this object.\r
+        *\r
+        * @param int $container_guid The ID of the container.\r
+        * @return bool\r
+        */\r
+       function setContainer($container_guid) {\r
+               $container_guid = (int)$container_guid;\r
+\r
+               return $this->set('container_guid', $container_guid);\r
+       }\r
+\r
+       /**\r
+        * Return the container GUID of this object.\r
+        *\r
+        * @return int\r
+        */\r
+       function getContainer() {\r
+               return $this->get('container_guid');\r
+       }\r
+\r
+       /**\r
+        * As getContainer(), but returns the whole entity.\r
+        *\r
+        * @return mixed ElggGroup object or false.\r
+        */\r
+       function getContainerEntity() {\r
+               $result = get_entity($this->getContainer());\r
+\r
+               if (($result) && ($result instanceof ElggGroup)) {\r
+                       return $result;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Get the collections associated with a object.\r
+        *\r
+        * @param string $subtype Optionally, the subtype of result we want to limit to\r
+        * @param int $limit The number of results to return\r
+        * @param int $offset Any indexing offset\r
+        * @return unknown\r
+        */\r
+       //public function getCollections($subtype="", $limit = 10, $offset = 0) { get_object_collections($this->getGUID(), $subtype, $limit, $offset); }\r
+\r
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an array of fields which can be exported.\r
+        */\r
+       public function getExportableValues() {\r
+               return array_merge(parent::getExportableValues(), array(\r
+                       'title',\r
+                       'description',\r
+               ));\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php
new file mode 100644 (file)
index 0000000..921665f
--- /dev/null
@@ -0,0 +1,56 @@
+<?php\r
+/**\r
+ * @class ElggPlugin Object representing a plugin's settings for a given site.\r
+ * This class is currently a stub, allowing a plugin to saving settings in an object's metadata for each site.\r
+ * @author Curverider Ltd\r
+ */\r
+class ElggPlugin extends ElggObject {\r
+       protected function initialise_attributes() {\r
+               parent::initialise_attributes();\r
+\r
+               $this->attributes['subtype'] = "plugin";\r
+       }\r
+\r
+       public function __construct($guid = null) {\r
+               parent::__construct($guid);\r
+       }\r
+\r
+       /**\r
+        * Override entity get and sets in order to save data to private data store.\r
+        */\r
+       public function get($name) {\r
+               // See if its in our base attribute\r
+               if (isset($this->attributes[$name])) {\r
+                       return $this->attributes[$name];\r
+               }\r
+\r
+               // No, so see if its in the private data store.\r
+               // get_private_setting() returns false if it doesn't exist\r
+               $meta = get_private_setting($this->guid, $name);\r
+\r
+               if ($meta === false) {\r
+                       // Can't find it, so return null\r
+                       return NULL;\r
+               }\r
+\r
+               return $meta;\r
+       }\r
+\r
+       /**\r
+        * Override entity get and sets in order to save data to private data store.\r
+        */\r
+       public function set($name, $value) {\r
+               if (array_key_exists($name, $this->attributes)) {\r
+                       // Check that we're not trying to change the guid!\r
+                       if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) {\r
+                               return false;\r
+                       }\r
+\r
+                       $this->attributes[$name] = $value;\r
+               } else {\r
+                       return set_private_setting($this->guid, $name, $value);\r
+               }\r
+\r
+               return true;\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggRelationship.php b/engine/classes/ElggRelationship.php
new file mode 100644 (file)
index 0000000..4d14941
--- /dev/null
@@ -0,0 +1,287 @@
+<?php\r
+\r
+/**\r
+ * Relationship class.\r
+ *\r
+ * @author Curverider Ltd\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+class ElggRelationship implements\r
+       Importable,\r
+       Exportable,\r
+       Loggable,       // Can events related to this object class be logged\r
+       Iterator,       // Override foreach behaviour\r
+       ArrayAccess // Override for array access\r
+       {\r
+       /**\r
+        * This contains the site's main properties (id, etc)\r
+        * @var array\r
+        */\r
+       protected $attributes;\r
+\r
+       /**\r
+        * Construct a new site object, optionally from a given id value or row.\r
+        *\r
+        * @param mixed $id\r
+        */\r
+       function __construct($id = null) {\r
+               $this->attributes = array();\r
+\r
+               if (!empty($id)) {\r
+                       if ($id instanceof stdClass) {\r
+                               $relationship = $id; // Create from db row\r
+                       } else {\r
+                               $relationship = get_relationship($id);\r
+                       }\r
+\r
+                       if ($relationship) {\r
+                               $objarray = (array) $relationship;\r
+                               foreach($objarray as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Class member get overloading\r
+        *\r
+        * @param string $name\r
+        * @return mixed\r
+        */\r
+       function __get($name) {\r
+               if (isset($this->attributes[$name])) {\r
+                       return $this->attributes[$name];\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Class member set overloading\r
+        *\r
+        * @param string $name\r
+        * @param mixed $value\r
+        * @return mixed\r
+        */\r
+       function __set($name, $value) {\r
+               $this->attributes[$name] = $value;\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Save the relationship\r
+        *\r
+        * @return int the relationship id\r
+        */\r
+       public function save() {\r
+               if ($this->id > 0) {\r
+                       delete_relationship($this->id);\r
+               }\r
+\r
+               $this->id = add_entity_relationship($this->guid_one, $this->relationship, $this->guid_two);\r
+               if (!$this->id) {\r
+                       throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));\r
+               }\r
+\r
+               return $this->id;\r
+       }\r
+\r
+       /**\r
+        * Delete a given relationship.\r
+        */\r
+       public function delete() {\r
+               return delete_relationship($this->id);\r
+       }\r
+\r
+       /**\r
+        * Get a URL for this relationship.\r
+        *\r
+        * @return string\r
+        */\r
+       public function getURL() {\r
+               return get_relationship_url($this->id);\r
+       }\r
+\r
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an array of fields which can be exported.\r
+        */\r
+       public function getExportableValues() {\r
+               return array(\r
+                       'id',\r
+                       'guid_one',\r
+                       'relationship',\r
+                       'guid_two'\r
+               );\r
+       }\r
+\r
+       /**\r
+        * Export this relationship\r
+        *\r
+        * @return array\r
+        */\r
+       public function export() {\r
+               $uuid = get_uuid_from_object($this);\r
+               $relationship = new ODDRelationship(\r
+                       guid_to_uuid($this->guid_one),\r
+                       $this->relationship,\r
+                       guid_to_uuid($this->guid_two)\r
+               );\r
+\r
+               $relationship->setAttribute('uuid', $uuid);\r
+\r
+               return $relationship;\r
+       }\r
+\r
+       // IMPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Import a relationship\r
+        *\r
+        * @param array $data\r
+        * @param int $version\r
+        * @return ElggRelationship\r
+        * @throws ImportException\r
+        */\r
+       public function import(ODD $data) {\r
+               if (!($element instanceof ODDRelationship)) {\r
+                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass'));\r
+               }\r
+\r
+               $uuid_one = $data->getAttribute('uuid1');\r
+               $uuid_two = $data->getAttribute('uuid2');\r
+\r
+               // See if this entity has already been imported, if so then we need to link to it\r
+               $entity1 = get_entity_from_uuid($uuid_one);\r
+               $entity2 = get_entity_from_uuid($uuid_two);\r
+               if (($entity1) && ($entity2)) {\r
+                       // Set the item ID\r
+                       $this->attributes['guid_one'] = $entity1->getGUID();\r
+                       $this->attributes['guid_two'] = $entity2->getGUID();\r
+\r
+                       // Map verb to relationship\r
+                       //$verb = $data->getAttribute('verb');\r
+                       //$relationship = get_relationship_from_verb($verb);\r
+                       $relationship = $data->getAttribute('type');\r
+\r
+                       if ($relationship) {\r
+                               $this->attributes['relationship'] = $relationship;\r
+                               // save\r
+                               $result = $this->save();\r
+                               if (!$result) {\r
+                                       throw new ImportException(sprintf(elgg_echo('ImportException:ProblemSaving'), get_class()));\r
+                               }\r
+\r
+                               return $this;\r
+                       }\r
+               }\r
+       }\r
+\r
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an identification for the object for storage in the system log.\r
+        * This id must be an integer.\r
+        *\r
+        * @return int\r
+        */\r
+       public function getSystemLogID() {\r
+               return $this->id;\r
+       }\r
+\r
+       /**\r
+        * Return the class name of the object.\r
+        */\r
+       public function getClassName() {\r
+               return get_class($this);\r
+       }\r
+\r
+       /**\r
+        * For a given ID, return the object associated with it.\r
+        * This is used by the river functionality primarily.\r
+        * This is useful for checking access permissions etc on objects.\r
+        */\r
+       public function getObjectFromID($id) {\r
+               return get_relationship($id);\r
+       }\r
+\r
+       /**\r
+        * Return the GUID of the owner of this object.\r
+        */\r
+       public function getObjectOwnerGUID() {\r
+               return $this->owner_guid;\r
+       }\r
+\r
+       /**\r
+        * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc\r
+        */\r
+       public function getType() {\r
+               return 'relationship';\r
+       }\r
+\r
+       /**\r
+        * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.\r
+        */\r
+       public function getSubtype() {\r
+               return $this->relationship;\r
+       }\r
+\r
+       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////\r
+       /*\r
+        * This lets an entity's attributes be displayed using foreach as a normal array.\r
+        * Example: http://www.sitepoint.com/print/php5-standard-library\r
+        */\r
+\r
+       private $valid = FALSE;\r
+\r
+       function rewind() {\r
+               $this->valid = (FALSE !== reset($this->attributes));\r
+       }\r
+\r
+       function current() {\r
+               return current($this->attributes);\r
+       }\r
+\r
+       function key() {\r
+               return key($this->attributes);\r
+       }\r
+\r
+       function next() {\r
+               $this->valid = (FALSE !== next($this->attributes));\r
+       }\r
+\r
+       function valid() {\r
+               return $this->valid;\r
+       }\r
+\r
+       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////\r
+       /*\r
+        * This lets an entity's attributes be accessed like an associative array.\r
+        * Example: http://www.sitepoint.com/print/php5-standard-library\r
+        */\r
+\r
+       function offsetSet($key, $value) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       $this->attributes[$key] = $value;\r
+               }\r
+       }\r
+\r
+       function offsetGet($key) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       return $this->attributes[$key];\r
+               }\r
+       }\r
+\r
+       function offsetUnset($key) {\r
+               if ( array_key_exists($key, $this->attributes) ) {\r
+                       $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects\r
+               }\r
+       }\r
+\r
+       function offsetExists($offset) {\r
+               return array_key_exists($offset, $this->attributes);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggSession.php b/engine/classes/ElggSession.php
new file mode 100644 (file)
index 0000000..8745025
--- /dev/null
@@ -0,0 +1,95 @@
+<?php\r
+/**\r
+ * Magic session class.\r
+ * This class is intended to extend the $_SESSION magic variable by providing an API hook\r
+ * to plug in other values.\r
+ *\r
+ * Primarily this is intended to provide a way of supplying "logged in user" details without touching the session\r
+ * (which can cause problems when accessed server side).\r
+ *\r
+ * If a value is present in the session then that value is returned, otherwise a plugin hook 'session:get', '$var' is called,\r
+ * where $var is the variable being requested.\r
+ *\r
+ * Setting values will store variables in the session in the normal way.\r
+ *\r
+ * LIMITATIONS: You can not access multidimensional arrays\r
+ *\r
+ * This is EXPERIMENTAL.\r
+ */\r
+class ElggSession implements ArrayAccess {\r
+       /** Local cache of trigger retrieved variables */\r
+       private static $__localcache;\r
+\r
+       function __isset($key) {\r
+               return $this->offsetExists($key);\r
+       }\r
+\r
+       /** Set a value, go straight to session. */\r
+       function offsetSet($key, $value) {\r
+               $_SESSION[$key] = $value;\r
+       }\r
+\r
+       /**\r
+        * Get a variable from either the session, or if its not in the session attempt to get it from\r
+        * an api call.\r
+        */\r
+       function offsetGet($key) {\r
+               if (!ElggSession::$__localcache) {\r
+                       ElggSession::$__localcache = array();\r
+               }\r
+\r
+               if (isset($_SESSION[$key])) {\r
+                       return $_SESSION[$key];\r
+               }\r
+\r
+               if (isset(ElggSession::$__localcache[$key])) {\r
+                       return ElggSession::$__localcache[$key];\r
+               }\r
+\r
+               $value = NULL;\r
+               $value = trigger_plugin_hook('session:get', $key, NULL, $value);\r
+\r
+               ElggSession::$__localcache[$key] = $value;\r
+\r
+               return ElggSession::$__localcache[$key];\r
+       }\r
+\r
+       /**\r
+       * Unset a value from the cache and the session.\r
+       */\r
+       function offsetUnset($key) {\r
+               unset(ElggSession::$__localcache[$key]);\r
+               unset($_SESSION[$key]);\r
+       }\r
+\r
+       /**\r
+       * Return whether the value is set in either the session or the cache.\r
+       */\r
+       function offsetExists($offset) {\r
+               if (isset(ElggSession::$__localcache[$offset])) {\r
+                       return true;\r
+               }\r
+\r
+               if (isset($_SESSION[$offset])) {\r
+                       return true;\r
+               }\r
+\r
+               if ($this->offsetGet($offset)){\r
+                       return true;\r
+               }\r
+       }\r
+\r
+\r
+       // Alias functions\r
+       function get($key) {\r
+               return $this->offsetGet($key);\r
+       }\r
+\r
+       function set($key, $value) {\r
+               return $this->offsetSet($key, $value);\r
+       }\r
+\r
+       function del($key) {\r
+               return $this->offsetUnset($key);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggSharedMemoryCache.php b/engine/classes/ElggSharedMemoryCache.php
new file mode 100644 (file)
index 0000000..cae7894
--- /dev/null
@@ -0,0 +1,34 @@
+<?php\r
+/**\r
+ * Shared memory cache description.\r
+ * Extends ElggCache with functions useful to shared memory style caches (static variables, memcache etc)\r
+ */\r
+abstract class ElggSharedMemoryCache extends ElggCache {\r
+       /**\r
+        * Namespace variable used to keep various bits of the cache\r
+        * separate.\r
+        *\r
+        * @var string\r
+        */\r
+       private $namespace;\r
+\r
+       /**\r
+        * Set the namespace of this cache.\r
+        * This is useful for cache types (like memcache or static variables) where there is one large\r
+        * flat area of memory shared across all instances of the cache.\r
+        *\r
+        * @param string $namespace\r
+        */\r
+       public function setNamespace($namespace = "default") {\r
+               $this->namespace = $namespace;\r
+       }\r
+\r
+       /**\r
+        * Get the namespace currently defined.\r
+        *\r
+        * @return string\r
+        */\r
+       public function getNamespace() {\r
+               return $this->namespace;\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggSite.php b/engine/classes/ElggSite.php
new file mode 100644 (file)
index 0000000..77e2637
--- /dev/null
@@ -0,0 +1,299 @@
+<?php\r
+/**\r
+ * ElggSite\r
+ * Representation of a "site" in the system.\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+class ElggSite extends ElggEntity {\r
+       /**\r
+        * Initialise the attributes array.\r
+        * This is vital to distinguish between metadata and base parameters.\r
+        *\r
+        * Place your base parameters here.\r
+        */\r
+       protected function initialise_attributes() {\r
+               parent::initialise_attributes();\r
+\r
+               $this->attributes['type'] = "site";\r
+               $this->attributes['name'] = "";\r
+               $this->attributes['description'] = "";\r
+               $this->attributes['url'] = "";\r
+               $this->attributes['tables_split'] = 2;\r
+       }\r
+\r
+       /**\r
+        * Construct a new site object, optionally from a given id value.\r
+        *\r
+        * @param mixed $guid If an int, load that GUID.\r
+        *      If a db row then will attempt to load the rest of the data.\r
+        * @throws Exception if there was a problem creating the site.\r
+        */\r
+       function __construct($guid = null) {\r
+               $this->initialise_attributes();\r
+\r
+               if (!empty($guid)) {\r
+                       // Is $guid is a DB row - either a entity row, or a site table row.\r
+                       if ($guid instanceof stdClass) {\r
+                               // Load the rest\r
+                               if (!$this->load($guid->guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));\r
+                               }\r
+                       }\r
+\r
+                       // Is $guid is an ElggSite? Use a copy constructor\r
+                       else if ($guid instanceof ElggSite) {\r
+                               elgg_deprecated_notice('This type of usage of the ElggSite constructor was deprecated. Please use the clone method.', 1.7);\r
+                               \r
+                               foreach ($guid->attributes as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                       }\r
+\r
+                       // Is this is an ElggEntity but not an ElggSite = ERROR!\r
+                       else if ($guid instanceof ElggEntity) {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggSite'));\r
+                       }\r
+\r
+                       // See if this is a URL\r
+                       else if (strpos($guid, "http") !== false) {\r
+                               $guid = get_site_by_url($guid);\r
+                               foreach ($guid->attributes as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                       }\r
+\r
+                       // We assume if we have got this far, $guid is an int\r
+                       else if (is_numeric($guid)) {\r
+                               if (!$this->load($guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));\r
+                               }\r
+                       }\r
+\r
+                       else {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Override the load function.\r
+        * This function will ensure that all data is loaded (were possible), so\r
+        * if only part of the ElggSite is loaded, it'll load the rest.\r
+        *\r
+        * @param int $guid\r
+        */\r
+       protected function load($guid) {\r
+               // Test to see if we have the generic stuff\r
+               if (!parent::load($guid)) {\r
+                       return false;\r
+               }\r
+\r
+               // Check the type\r
+               if ($this->attributes['type']!='site') {\r
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));\r
+               }\r
+\r
+               // Load missing data\r
+               $row = get_site_entity_as_row($guid);\r
+               if (($row) && (!$this->isFullyLoaded())) {\r
+                       // If $row isn't a cached copy then increment the counter\r
+                       $this->attributes['tables_loaded'] ++;\r
+               }\r
+\r
+               // Now put these into the attributes array as core values\r
+               $objarray = (array) $row;\r
+               foreach($objarray as $key => $value) {\r
+                       $this->attributes[$key] = $value;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Override the save function.\r
+        */\r
+       public function save() {\r
+               // Save generic stuff\r
+               if (!parent::save()) {\r
+                       return false;\r
+               }\r
+\r
+               // Now save specific stuff\r
+               return create_site_entity($this->get('guid'), $this->get('name'), $this->get('description'), $this->get('url'));\r
+       }\r
+\r
+       /**\r
+        * Delete this site.\r
+        */\r
+       public function delete() {\r
+               global $CONFIG;\r
+               if ($CONFIG->site->getGUID() == $this->guid) {\r
+                       throw new SecurityException('SecurityException:deletedisablecurrentsite');\r
+               }\r
+\r
+               return parent::delete();\r
+       }\r
+\r
+       /**\r
+        * Disable override to add safety rail.\r
+        *\r
+        * @param unknown_type $reason\r
+        */\r
+       public function disable($reason = "") {\r
+               global $CONFIG;\r
+\r
+               if ($CONFIG->site->getGUID() == $this->guid) {\r
+                       throw new SecurityException('SecurityException:deletedisablecurrentsite');\r
+               }\r
+\r
+               return parent::disable($reason);\r
+       }\r
+\r
+       /**\r
+        * Return a list of users using this site.\r
+        *\r
+        * @param int $limit\r
+        * @param int $offset\r
+        * @return array of ElggUsers\r
+        */\r
+       public function getMembers($limit = 10, $offset = 0) {\r
+               get_site_members($this->getGUID(), $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Add a user to the site.\r
+        *\r
+        * @param int $user_guid\r
+        */\r
+       public function addUser($user_guid) {\r
+               return add_site_user($this->getGUID(), $user_guid);\r
+       }\r
+\r
+       /**\r
+        * Remove a site user.\r
+        *\r
+        * @param int $user_guid\r
+        */\r
+       public function removeUser($user_guid) {\r
+               return remove_site_user($this->getGUID(), $user_guid);\r
+       }\r
+\r
+       /**\r
+        * Get an array of member ElggObjects.\r
+        *\r
+        * @param string $subtype\r
+        * @param int $limit\r
+        * @param int $offset\r
+        */\r
+       public function getObjects($subtype="", $limit = 10, $offset = 0) {\r
+               get_site_objects($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Add an object to the site.\r
+        *\r
+        * @param int $user_id\r
+        */\r
+       public function addObject($object_guid) {\r
+               return add_site_object($this->getGUID(), $object_guid);\r
+       }\r
+\r
+       /**\r
+        * Remove a site user.\r
+        *\r
+        * @param int $user_id\r
+        */\r
+       public function removeObject($object_guid) {\r
+               return remove_site_object($this->getGUID(), $object_guid);\r
+       }\r
+\r
+       /**\r
+        * Get the collections associated with a site.\r
+        *\r
+        * @param string $type\r
+        * @param int $limit\r
+        * @param int $offset\r
+        * @return unknown\r
+        */\r
+       public function getCollections($subtype="", $limit = 10, $offset = 0) {\r
+               get_site_collections($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an array of fields which can be exported.\r
+        */\r
+       public function getExportableValues() {\r
+               return array_merge(parent::getExportableValues(), array(\r
+                       'name',\r
+                       'description',\r
+                       'url',\r
+               ));\r
+       }\r
+       \r
+       public function check_walled_garden() {\r
+               global $CONFIG;\r
+               \r
+               if ($CONFIG->walled_garden && !isloggedin()) {\r
+                       // hook into the index system call at the highest priority\r
+                       register_plugin_hook('index', 'system', 'elgg_walled_garden_index', 1);\r
+                       \r
+                       if (!$this->is_public_page()) {\r
+                               register_error(elgg_echo('loggedinrequired'));\r
+                               forward();\r
+                       }\r
+               }\r
+       }\r
+       \r
+       public function is_public_page($url='') {\r
+               global $CONFIG;\r
+               \r
+               if (empty($url)) {\r
+                       $url = current_page_url();\r
+                       \r
+                       // do not check against URL queries\r
+                       if ($pos = strpos($url, '?')) {\r
+                               $url = substr($url, 0, $pos);\r
+                       }\r
+               }\r
+               \r
+               // always allow index page\r
+               if ($url == $CONFIG->url) {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // default public pages\r
+               $defaults = array(\r
+                       'action/login',\r
+                       'pg/register',\r
+                       'action/register',\r
+                       'account/forgotten_password\.php',\r
+                       'action/user/requestnewpassword',\r
+                       'pg/resetpassword',\r
+                       'upgrade\.php',\r
+                       'xml-rpc\.php',\r
+                       'mt/mt-xmlrpc\.cgi',\r
+                       '_css/css\.css',\r
+                       '_css/js\.php',\r
+               );\r
+               \r
+               // include a hook for plugin authors to include public pages\r
+               $plugins = trigger_plugin_hook('public_pages', 'walled_garden', NULL, array());\r
+               \r
+               // lookup admin-specific public pages\r
+               \r
+               // allow public pages\r
+               foreach (array_merge($defaults, $plugins) as $public) {\r
+                       $pattern = "`^{$CONFIG->url}$public/*$`i";\r
+                       if (preg_match($pattern, $url)) {\r
+                               return TRUE;\r
+                       }\r
+               }\r
+               \r
+               // non-public page\r
+               return FALSE;\r
+       }\r
+}\r
diff --git a/engine/classes/ElggStaticVariableCache.php b/engine/classes/ElggStaticVariableCache.php
new file mode 100644 (file)
index 0000000..0038862
--- /dev/null
@@ -0,0 +1,66 @@
+<?php\r
+/**\r
+ * ElggStaticVariableCache\r
+ * Dummy cache which stores values in a static array. Using this makes future replacements to other caching back\r
+ * ends (eg memcache) much easier.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage API\r
+ */\r
+class ElggStaticVariableCache extends ElggSharedMemoryCache {\r
+       /**\r
+        * The cache.\r
+        *\r
+        * @var unknown_type\r
+        */\r
+       private static $__cache;\r
+\r
+       /**\r
+        * Create the variable cache.\r
+        *\r
+        * This function creates a variable cache in a static variable in memory, optionally with a given namespace (to avoid overlap).\r
+        *\r
+        * @param string $namespace The namespace for this cache to write to - note, namespaces of the same name are shared!\r
+        */\r
+       function __construct($namespace = 'default') {\r
+               $this->setNamespace($namespace);\r
+               $this->clear();\r
+       }\r
+\r
+       public function save($key, $data) {\r
+               $namespace = $this->getNamespace();\r
+\r
+               ElggStaticVariableCache::$__cache[$namespace][$key] = $data;\r
+\r
+               return true;\r
+       }\r
+\r
+       public function load($key, $offset = 0, $limit = null) {\r
+               $namespace = $this->getNamespace();\r
+\r
+               if (isset(ElggStaticVariableCache::$__cache[$namespace][$key])) {\r
+                       return ElggStaticVariableCache::$__cache[$namespace][$key];\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       public function delete($key) {\r
+               $namespace = $this->getNamespace();\r
+\r
+               unset(ElggStaticVariableCache::$__cache[$namespace][$key]);\r
+\r
+               return true;\r
+       }\r
+\r
+       public function clear() {\r
+               $namespace = $this->getNamespace();\r
+\r
+               if (!isset(ElggStaticVariableCache::$__cache)) {\r
+                       ElggStaticVariableCache::$__cache = array();\r
+               }\r
+\r
+               ElggStaticVariableCache::$__cache[$namespace] = array();\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ElggUser.php b/engine/classes/ElggUser.php
new file mode 100644 (file)
index 0000000..001da19
--- /dev/null
@@ -0,0 +1,427 @@
+<?php\r
+/**\r
+ * ElggUser\r
+ *\r
+ * Representation of a "user" in the system.\r
+ *\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+class ElggUser extends ElggEntity\r
+       implements Friendable {\r
+       /**\r
+        * Initialise the attributes array.\r
+        * This is vital to distinguish between metadata and base parameters.\r
+        *\r
+        * Place your base parameters here.\r
+        */\r
+       protected function initialise_attributes() {\r
+               parent::initialise_attributes();\r
+\r
+               $this->attributes['type'] = "user";\r
+               $this->attributes['name'] = "";\r
+               $this->attributes['username'] = "";\r
+               $this->attributes['password'] = "";\r
+               $this->attributes['salt'] = "";\r
+               $this->attributes['email'] = "";\r
+               $this->attributes['language'] = "";\r
+               $this->attributes['code'] = "";\r
+               $this->attributes['banned'] = "no";\r
+               $this->attributes['admin'] = 'no';\r
+               $this->attributes['tables_split'] = 2;\r
+       }\r
+\r
+       /**\r
+        * Construct a new user entity, optionally from a given id value.\r
+        *\r
+        * @param mixed $guid If an int, load that GUID.\r
+        *      If a db row then will attempt to load the rest of the data.\r
+        * @throws Exception if there was a problem creating the user.\r
+        */\r
+       function __construct($guid = null) {\r
+               $this->initialise_attributes();\r
+\r
+               if (!empty($guid)) {\r
+                       // Is $guid is a DB row - either a entity row, or a user table row.\r
+                       if ($guid instanceof stdClass) {\r
+                               // Load the rest\r
+                               if (!$this->load($guid->guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));\r
+                               }\r
+                       }\r
+\r
+                       // See if this is a username\r
+                       else if (is_string($guid)) {\r
+                               $guid = get_user_by_username($guid);\r
+                               foreach ($guid->attributes as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                       }\r
+\r
+                       // Is $guid is an ElggUser? Use a copy constructor\r
+                       else if ($guid instanceof ElggUser) {\r
+                               elgg_deprecated_notice('This type of usage of the ElggUser constructor was deprecated. Please use the clone method.', 1.7);\r
+\r
+                               foreach ($guid->attributes as $key => $value) {\r
+                                       $this->attributes[$key] = $value;\r
+                               }\r
+                       }\r
+\r
+                       // Is this is an ElggEntity but not an ElggUser = ERROR!\r
+                       else if ($guid instanceof ElggEntity) {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggUser'));\r
+                       }\r
+\r
+                       // We assume if we have got this far, $guid is an int\r
+                       else if (is_numeric($guid)) {\r
+                               if (!$this->load($guid)) {\r
+                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));\r
+                               }\r
+                       }\r
+\r
+                       else {\r
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Override the load function.\r
+        * This function will ensure that all data is loaded (were possible), so\r
+        * if only part of the ElggUser is loaded, it'll load the rest.\r
+        *\r
+        * @param int $guid\r
+        * @return true|false\r
+        */\r
+       protected function load($guid) {\r
+               // Test to see if we have the generic stuff\r
+               if (!parent::load($guid)) {\r
+                       return false;\r
+               }\r
+\r
+               // Check the type\r
+               if ($this->attributes['type']!='user') {\r
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));\r
+               }\r
+\r
+               // Load missing data\r
+               $row = get_user_entity_as_row($guid);\r
+               if (($row) && (!$this->isFullyLoaded())) {\r
+                       // If $row isn't a cached copy then increment the counter\r
+                       $this->attributes['tables_loaded'] ++;\r
+               }\r
+\r
+               // Now put these into the attributes array as core values\r
+               $objarray = (array) $row;\r
+               foreach($objarray as $key => $value) {\r
+                       $this->attributes[$key] = $value;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Saves this user to the database.\r
+        * @return true|false\r
+        */\r
+       public function save() {\r
+               // Save generic stuff\r
+               if (!parent::save()) {\r
+                       return false;\r
+               }\r
+\r
+               // Now save specific stuff\r
+               return create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'), $this->get('password'), $this->get('salt'), $this->get('email'), $this->get('language'), $this->get('code'));\r
+       }\r
+\r
+       /**\r
+        * User specific override of the entity delete method.\r
+        *\r
+        * @return bool\r
+        */\r
+       public function delete() {\r
+               global $USERNAME_TO_GUID_MAP_CACHE, $CODE_TO_GUID_MAP_CACHE;\r
+\r
+               // clear cache\r
+               if (isset($USERNAME_TO_GUID_MAP_CACHE[$this->username])) {\r
+                       unset($USERNAME_TO_GUID_MAP_CACHE[$this->username]);\r
+               }\r
+               if (isset($CODE_TO_GUID_MAP_CACHE[$this->code])) {\r
+                       unset($CODE_TO_GUID_MAP_CACHE[$this->code]);\r
+               }\r
+\r
+               // Delete owned data\r
+               clear_annotations_by_owner($this->guid);\r
+               clear_metadata_by_owner($this->guid);\r
+               clear_user_files($this);\r
+\r
+               // Delete entity\r
+               return parent::delete();\r
+       }\r
+\r
+       /**\r
+        * Ban this user.\r
+        *\r
+        * @param string $reason Optional reason\r
+        */\r
+       public function ban($reason = "") {\r
+               return ban_user($this->guid, $reason);\r
+       }\r
+\r
+       /**\r
+        * Unban this user.\r
+        */\r
+       public function unban() {\r
+               return unban_user($this->guid);\r
+       }\r
+\r
+       /**\r
+        * Is this user banned or not?\r
+        *\r
+        * @return bool\r
+        */\r
+       public function isBanned() {\r
+               return $this->banned == 'yes';\r
+       }\r
+\r
+       /**\r
+        * Is this user admin?\r
+        *\r
+        * @return bool\r
+        */\r
+       public function isAdmin() {\r
+\r
+               // for backward compatibility we need to pull this directly\r
+               // from the attributes instead of using the magic methods.\r
+               // this can be removed in 1.9\r
+               // return $this->admin == 'yes';\r
+               return $this->attributes['admin'] == 'yes';\r
+       }\r
+\r
+       /**\r
+        * Make the user an admin\r
+        *\r
+        * @return bool\r
+        */\r
+       public function makeAdmin() {\r
+               if (make_user_admin($this->guid)) {\r
+                       $this->attributes['admin'] = 'yes';\r
+                       return TRUE;\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       /**\r
+        * Remove the admin flag for user\r
+        *\r
+        * @return bool\r
+        */\r
+       public function removeAdmin() {\r
+               if (remove_user_admin($this->guid)) {\r
+                       $this->attributes['admin'] = 'no';\r
+                       return TRUE;\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       /**\r
+        * Get sites that this user is a member of\r
+        *\r
+        * @param string $subtype Optionally, the subtype of result we want to limit to\r
+        * @param int $limit The number of results to return\r
+        * @param int $offset Any indexing offset\r
+        */\r
+       function getSites($subtype="", $limit = 10, $offset = 0) {\r
+               // return get_site_users($this->getGUID(), $subtype, $limit, $offset);\r
+               return get_user_sites($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Add this user to a particular site\r
+        *\r
+        * @param int $site_guid The guid of the site to add it to\r
+        * @return true|false\r
+        */\r
+       function addToSite($site_guid) {\r
+               // return add_site_user($this->getGUID(), $site_guid);\r
+               return add_site_user($site_guid, $this->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Remove this user from a particular site\r
+        *\r
+        * @param int $site_guid The guid of the site to remove it from\r
+        * @return true|false\r
+        */\r
+       function removeFromSite($site_guid) {\r
+               //return remove_site_user($this->getGUID(), $site_guid);\r
+               return remove_site_user($site_guid, $this->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Adds a user to this user's friends list\r
+        *\r
+        * @param int $friend_guid The GUID of the user to add\r
+        * @return true|false Depending on success\r
+        */\r
+       function addFriend($friend_guid) {\r
+               return user_add_friend($this->getGUID(), $friend_guid);\r
+       }\r
+\r
+       /**\r
+        * Removes a user from this user's friends list\r
+        *\r
+        * @param int $friend_guid The GUID of the user to remove\r
+        * @return true|false Depending on success\r
+        */\r
+       function removeFriend($friend_guid) {\r
+               return user_remove_friend($this->getGUID(), $friend_guid);\r
+       }\r
+\r
+       /**\r
+        * Determines whether or not this user is a friend of the currently logged in user\r
+        *\r
+        * @return true|false\r
+        */\r
+       function isFriend() {\r
+               return user_is_friend(get_loggedin_userid(), $this->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Determines whether this user is friends with another user\r
+        *\r
+        * @param int $user_guid The GUID of the user to check is on this user's friends list\r
+        * @return true|false\r
+        */\r
+       function isFriendsWith($user_guid) {\r
+               return user_is_friend($this->getGUID(), $user_guid);\r
+       }\r
+\r
+       /**\r
+        * Determines whether or not this user is on another user's friends list\r
+        *\r
+        * @param int $user_guid The GUID of the user to check against\r
+        * @return true|false\r
+        */\r
+       function isFriendOf($user_guid) {\r
+               return user_is_friend($user_guid, $this->getGUID());\r
+       }\r
+\r
+       /**\r
+        * Retrieves a list of this user's friends\r
+        *\r
+        * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all)\r
+        * @param int $limit The number of users to retrieve\r
+        * @param int $offset Indexing offset, if any\r
+        * @return array|false Array of ElggUsers, or false, depending on success\r
+        */\r
+       function getFriends($subtype = "", $limit = 10, $offset = 0) {\r
+               return get_user_friends($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Retrieves a list of people who have made this user a friend\r
+        *\r
+        * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all)\r
+        * @param int $limit The number of users to retrieve\r
+        * @param int $offset Indexing offset, if any\r
+        * @return array|false Array of ElggUsers, or false, depending on success\r
+        */\r
+       function getFriendsOf($subtype = "", $limit = 10, $offset = 0) {\r
+               return get_user_friends_of($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Get an array of ElggObjects owned by this user.\r
+        *\r
+        * @param string $subtype The subtype of the objects, if any\r
+        * @param int $limit Number of results to return\r
+        * @param int $offset Any indexing offset\r
+        */\r
+       public function getObjects($subtype="", $limit = 10, $offset = 0) {\r
+               return get_user_objects($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Get an array of ElggObjects owned by this user's friends.\r
+        *\r
+        * @param string $subtype The subtype of the objects, if any\r
+        * @param int $limit Number of results to return\r
+        * @param int $offset Any indexing offset\r
+        */\r
+       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) {\r
+               return get_user_friends_objects($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * Counts the number of ElggObjects owned by this user\r
+        *\r
+        * @param string $subtype The subtypes of the objects, if any\r
+        * @return int The number of ElggObjects\r
+        */\r
+       public function countObjects($subtype = "") {\r
+               return count_user_objects($this->getGUID(), $subtype);\r
+       }\r
+\r
+       /**\r
+        * Get the collections associated with a user.\r
+        *\r
+        * @param string $subtype Optionally, the subtype of result we want to limit to\r
+        * @param int $limit The number of results to return\r
+        * @param int $offset Any indexing offset\r
+        * @return unknown\r
+        */\r
+       public function getCollections($subtype="", $limit = 10, $offset = 0) {\r
+               return get_user_collections($this->getGUID(), $subtype, $limit, $offset);\r
+       }\r
+\r
+       /**\r
+        * If a user's owner is blank, return its own GUID as the owner\r
+        *\r
+        * @return int User GUID\r
+        */\r
+       function getOwner() {\r
+               if ($this->owner_guid == 0) {\r
+                       return $this->getGUID();\r
+               }\r
+\r
+               return $this->owner_guid;\r
+       }\r
+\r
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Return an array of fields which can be exported.\r
+        */\r
+       public function getExportableValues() {\r
+               return array_merge(parent::getExportableValues(), array(\r
+                       'name',\r
+                       'username',\r
+                       'language',\r
+               ));\r
+       }\r
+\r
+       // backward compatibility with admin flag\r
+       // remove for 1.9\r
+       public function __set($name, $value) {\r
+               if ($name == 'admin' || $name == 'siteadmin') {\r
+                       elgg_deprecated_notice('The admin/siteadmin metadata are not longer used.  Use ElggUser->makeAdmin() and ElggUser->removeAdmin().', '1.7.1');\r
+\r
+                       if ($value == 'yes' || $value == '1') {\r
+                               $this->makeAdmin();\r
+                       } else {\r
+                               $this->removeAdmin();\r
+                       }\r
+               }\r
+               return parent::__set($name, $value);\r
+       }\r
+\r
+       public function __get($name) {\r
+               if ($name == 'admin' || $name == 'siteadmin') {\r
+                       elgg_deprecated_notice('The admin/siteadmin metadata are not longer used.  Use ElggUser->isAdmin().', '1.7.1');\r
+                       return $this->isAdmin();\r
+               }\r
+\r
+               return parent::__get($name);\r
+       }\r
+}\r
diff --git a/engine/classes/ElggWidget.php b/engine/classes/ElggWidget.php
new file mode 100644 (file)
index 0000000..dbca3c3
--- /dev/null
@@ -0,0 +1,53 @@
+<?php\r
+\r
+/**\r
+ * Override ElggObject in order to store widget data in ultra-private stores.\r
+ */\r
+class ElggWidget extends ElggObject {\r
+       protected function initialise_attributes() {\r
+               parent::initialise_attributes();\r
+\r
+               $this->attributes['subtype'] = "widget";\r
+       }\r
+\r
+       public function __construct($guid = null) {\r
+               parent::__construct($guid);\r
+       }\r
+\r
+       /**\r
+        * Override entity get and sets in order to save data to private data store.\r
+        */\r
+       public function get($name) {\r
+               // See if its in our base attribute\r
+               if (isset($this->attributes[$name])) {\r
+                       return $this->attributes[$name];\r
+               }\r
+\r
+               // No, so see if its in the private data store.\r
+               $meta = get_private_setting($this->guid, $name);\r
+               if ($meta) {\r
+                       return $meta;\r
+               }\r
+\r
+               // Can't find it, so return null\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Override entity get and sets in order to save data to private data store.\r
+        */\r
+       public function set($name, $value) {\r
+               if (array_key_exists($name, $this->attributes)) {\r
+                       // Check that we're not trying to change the guid!\r
+                       if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) {\r
+                               return false;\r
+                       }\r
+\r
+                       $this->attributes[$name] = $value;\r
+               } else {\r
+                       return set_private_setting($this->guid, $name, $value);\r
+               }\r
+\r
+               return true;\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ErrorResult.php b/engine/classes/ErrorResult.php
new file mode 100644 (file)
index 0000000..5fc6c88
--- /dev/null
@@ -0,0 +1,44 @@
+<?php\r
+/**\r
+ * ErrorResult\r
+ * The error result class.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+class ErrorResult extends GenericResult {\r
+       // Fail with no specific code\r
+       public static $RESULT_FAIL = -1 ;\r
+\r
+       public static $RESULT_FAIL_APIKEY_DISABLED = -30;\r
+       public static $RESULT_FAIL_APIKEY_INACTIVE = -31;\r
+       public static $RESULT_FAIL_APIKEY_INVALID = -32;\r
+\r
+       // Invalid, expired or missing auth token\r
+       public static $RESULT_FAIL_AUTHTOKEN = -20;\r
+\r
+       public function ErrorResult($message, $code = "", Exception $exception = NULL) {\r
+               if ($code == "") {\r
+                       $code = ErrorResult::$RESULT_FAIL;\r
+               }\r
+\r
+               if ($exception!=NULL) {\r
+                       $this->setResult($exception->__toString());\r
+               }\r
+\r
+               $this->setStatusCode($code, $message);\r
+       }\r
+\r
+       /**\r
+        * Get a new instance of the ErrorResult.\r
+        *\r
+        * @param string $message\r
+        * @param int $code\r
+        * @param Exception $exception Optional exception for generating a stack trace.\r
+        */\r
+       public static function getInstance($message, $code = "", Exception $exception = NULL) {\r
+               // Return a new error object.\r
+               return new ErrorResult($message, $code, $exception);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ExportException.php b/engine/classes/ExportException.php
new file mode 100644 (file)
index 0000000..dc5c686
--- /dev/null
@@ -0,0 +1,9 @@
+<?php\r
+/**\r
+ * Export exception\r
+ *\r
+ * @package Elgg\r
+ * @subpackage Exceptions\r
+ *\r
+ */\r
+class ExportException extends DataFormatException {}
\ No newline at end of file
diff --git a/engine/classes/Exportable.php b/engine/classes/Exportable.php
new file mode 100644 (file)
index 0000000..da5a7cc
--- /dev/null
@@ -0,0 +1,21 @@
+<?php\r
+/**\r
+ * Define an interface for all ODD exportable objects.\r
+ *\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ * @author Curverider Ltd\r
+ */\r
+interface Exportable {\r
+       /**\r
+        * This must take the contents of the object and convert it to exportable ODD\r
+        * @return object or array of objects.\r
+        */\r
+       public function export();\r
+\r
+       /**\r
+        * Return a list of all fields that can be exported.\r
+        * This should be used as the basis for the values returned by export()\r
+        */\r
+       public function getExportableValues();\r
+}
\ No newline at end of file
diff --git a/engine/classes/Friendable.php b/engine/classes/Friendable.php
new file mode 100644 (file)
index 0000000..d400bd0
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+/**
+ * An interface for objects that behave as elements within a social network that have a profile.
+ *
+ */
+interface Friendable {
+       /**
+        * Adds a user as a friend
+        *
+        * @param int $friend_guid The GUID of the user to add
+        */
+       public function addFriend($friend_guid);
+
+       /**
+        * Removes a user as a friend
+        *
+        * @param int $friend_guid The GUID of the user to remove
+        */
+       public function removeFriend($friend_guid);
+
+       /**
+        * Determines whether or not the current user is a friend of this entity
+        *
+        */
+       public function isFriend();
+
+       /**
+        * Determines whether or not this entity is friends with a particular entity
+        *
+        * @param int $user_guid The GUID of the entity this entity may or may not be friends with
+        */
+       public function isFriendsWith($user_guid);
+
+       /**
+        * Determines whether or not a foreign entity has made this one a friend
+        *
+        * @param int $user_guid The GUID of the foreign entity
+        */
+       public function isFriendOf($user_guid);
+
+       /**
+        * Returns this entity's friends
+        *
+        * @param string $subtype The subtype of entity to return
+        * @param int $limit The number of entities to return
+        * @param int $offset Indexing offset
+        */
+       public function getFriends($subtype = "", $limit = 10, $offset = 0);
+
+       /**
+        * Returns entities that have made this entity a friend
+        *
+        * @param string $subtype The subtype of entity to return
+        * @param int $limit The number of entities to return
+        * @param int $offset Indexing offset
+        */
+       public function getFriendsOf($subtype = "", $limit = 10, $offset = 0);
+
+       /**
+        * Returns objects in this entity's container
+        *
+        * @param string $subtype The subtype of entity to return
+        * @param int $limit The number of entities to return
+        * @param int $offset Indexing offset
+        */
+       public function getObjects($subtype="", $limit = 10, $offset = 0);
+
+       /**
+        * Returns objects in the containers of this entity's friends
+        *
+        * @param string $subtype The subtype of entity to return
+        * @param int $limit The number of entities to return
+        * @param int $offset Indexing offset
+        */
+       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0);
+
+       /**
+        * Returns the number of object entities in this entity's container
+        *
+        * @param string $subtype The subtype of entity to count
+        */
+       public function countObjects($subtype = "");
+}
\ No newline at end of file
diff --git a/engine/classes/GenericResult.php b/engine/classes/GenericResult.php
new file mode 100644 (file)
index 0000000..8bccd77
--- /dev/null
@@ -0,0 +1,107 @@
+<?php\r
+/**\r
+ * GenericResult Result superclass.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+abstract class GenericResult {\r
+       /**\r
+        * The status of the result.\r
+        * @var int\r
+        */\r
+       private $status_code;\r
+\r
+       /**\r
+        * Message returned along with the status which is almost always an error message.\r
+        * This must be human readable, understandable and localised.\r
+        * @var string\r
+        */\r
+       private $message;\r
+\r
+       /**\r
+        * Result store.\r
+        * Attach result specific informaton here.\r
+        *\r
+        * @var mixed. Should probably be an object of some sort.\r
+        */\r
+       private $result;\r
+\r
+       /**\r
+        * Set a status code and optional message.\r
+        *\r
+        * @param int $status The status code.\r
+        * @param string $message The message.\r
+        */\r
+       protected function setStatusCode($status, $message = "") {\r
+               $this->status_code = $status;\r
+               $this->message = $message;\r
+       }\r
+\r
+       /**\r
+        * Set the result.\r
+        *\r
+        * @param mixed $result\r
+        */\r
+       protected function setResult($result) {\r
+               $this->result = $result;\r
+       }\r
+\r
+       protected function getStatusCode() {\r
+               return $this->status_code;\r
+       }\r
+\r
+       protected function getStatusMessage() {\r
+               return $this->message;\r
+       }\r
+\r
+       protected function getResult() {\r
+               return $this->result;\r
+       }\r
+\r
+       /**\r
+        * Serialise to a standard class.\r
+        *\r
+        * DEVNOTE: The API is only interested in data, we can not easily serialise\r
+        * custom classes without the need for 1) the other side being PHP, 2) you need to have the class\r
+        * definition installed, 3) its the right version!\r
+        *\r
+        * Therefore, I'm not bothering.\r
+        *\r
+        * Override this to include any more specific information, however api results should be attached to the\r
+        * class using setResult().\r
+        *\r
+        * if $CONFIG->debug is set then additional information about the runtime environment and authentication will be\r
+        * returned.\r
+        *\r
+        * @return stdClass Object containing the serialised result.\r
+        */\r
+       public function export() {\r
+               global $ERRORS, $CONFIG, $_PAM_HANDLERS_MSG;\r
+\r
+               $result = new stdClass;\r
+\r
+               $result->status = $this->getStatusCode();\r
+               if ($this->getStatusMessage()!="") {\r
+                       $result->message = $this->getStatusMessage();\r
+               }\r
+\r
+               $resultdata = $this->getResult();\r
+               if (isset($resultdata)) {\r
+                       $result->result = $resultdata;\r
+               }\r
+\r
+               if (isset($CONFIG->debug)) {\r
+                       if (count($ERRORS)) {\r
+                               $result->runtime_errors = $ERRORS;\r
+                       }\r
+\r
+                       if (count($_PAM_HANDLERS_MSG)) {\r
+                               $result->pam = $_PAM_HANDLERS_MSG;\r
+                       }\r
+               }\r
+\r
+               return $result;\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/ImportException.php b/engine/classes/ImportException.php
new file mode 100644 (file)
index 0000000..fd86fc2
--- /dev/null
@@ -0,0 +1,8 @@
+<?php\r
+/**\r
+ * Import exception\r
+ *\r
+ * @package Elgg\r
+ * @subpackage Exceptions\r
+ */\r
+class ImportException extends DataFormatException {}
\ No newline at end of file
diff --git a/engine/classes/Importable.php b/engine/classes/Importable.php
new file mode 100644 (file)
index 0000000..775319c
--- /dev/null
@@ -0,0 +1,16 @@
+<?php\r
+/**\r
+ * Define an interface for all ODD importable objects.\r
+ * @author Curverider Ltd\r
+ */\r
+interface Importable {\r
+       /**\r
+        * Accepts an array of data to import, this data is parsed from the XML produced by export.\r
+        * The function should return the constructed object data, or NULL.\r
+        *\r
+        * @param ODD $data\r
+        * @return bool\r
+        * @throws ImportException if there was a critical error importing data.\r
+        */\r
+       public function import(ODD $data);\r
+}\r
diff --git a/engine/classes/Locatable.php b/engine/classes/Locatable.php
new file mode 100644 (file)
index 0000000..5f52d8e
--- /dev/null
@@ -0,0 +1,36 @@
+<?php\r
+\r
+/**\r
+ * Define an interface for geo-tagging entities.\r
+ *\r
+ */\r
+interface Locatable {\r
+       /** Set a location text */\r
+       public function setLocation($location);\r
+\r
+       /**\r
+        * Set latitude and longitude tags for a given entity.\r
+        *\r
+        * @param float $lat\r
+        * @param float $long\r
+        */\r
+       public function setLatLong($lat, $long);\r
+\r
+       /**\r
+        * Get the contents of the ->geo:lat field.\r
+        *\r
+        */\r
+       public function getLatitude();\r
+\r
+       /**\r
+        * Get the contents of the ->geo:lat field.\r
+        *\r
+        */\r
+       public function getLongitude();\r
+\r
+       /**\r
+        * Get the ->location metadata.\r
+        *\r
+        */\r
+       public function getLocation();\r
+}
\ No newline at end of file
diff --git a/engine/classes/Loggable.php b/engine/classes/Loggable.php
new file mode 100644 (file)
index 0000000..e126414
--- /dev/null
@@ -0,0 +1,49 @@
+<?php\r
+/**\r
+ * Interface that provides an interface which must be implemented by all objects wishing to be\r
+ * recorded in the system log (and by extension the river).\r
+ *\r
+ * This interface defines a set of methods that permit the system log functions to hook in and retrieve\r
+ * the necessary information and to identify what events can actually be logged.\r
+ *\r
+ * To have events involving your object to be logged simply implement this interface.\r
+ *\r
+ * @author Curverider Ltd\r
+ */\r
+interface Loggable {\r
+       /**\r
+        * Return an identification for the object for storage in the system log.\r
+        * This id must be an integer.\r
+        *\r
+        * @return int\r
+        */\r
+       public function getSystemLogID();\r
+\r
+       /**\r
+        * Return the class name of the object.\r
+        * Added as a function because get_class causes errors for some reason.\r
+        */\r
+       public function getClassName();\r
+\r
+       /**\r
+        * Return the type of the object - eg. object, group, user, relationship, metadata, annotation etc\r
+        */\r
+       public function getType();\r
+\r
+       /**\r
+        * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.\r
+        */\r
+       public function getSubtype();\r
+\r
+       /**\r
+        * For a given ID, return the object associated with it.\r
+        * This is used by the river functionality primarily.\r
+        * This is useful for checking access permissions etc on objects.\r
+        */\r
+       public function getObjectFromID($id);\r
+\r
+       /**\r
+        * Return the GUID of the owner of this object.\r
+        */\r
+       public function getObjectOwnerGUID();\r
+}
\ No newline at end of file
diff --git a/engine/classes/Notable.php b/engine/classes/Notable.php
new file mode 100644 (file)
index 0000000..3c133d4
--- /dev/null
@@ -0,0 +1,30 @@
+<?php\r
+/**\r
+ * Calendar interface for events.\r
+ *\r
+ */\r
+interface Notable {\r
+       /**\r
+        * Calendar functionality.\r
+        * This function sets the time of an object on a calendar listing.\r
+        *\r
+        * @param int $hour If ommitted, now is assumed.\r
+        * @param int $minute If ommitted, now is assumed.\r
+        * @param int $second If ommitted, now is assumed.\r
+        * @param int $day If ommitted, now is assumed.\r
+        * @param int $month If ommitted, now is assumed.\r
+        * @param int $year If ommitted, now is assumed.\r
+        * @param int $duration Duration of event, remainder of the day is assumed.\r
+        */\r
+       public function setCalendarTimeAndDuration($hour = NULL, $minute = NULL, $second = NULL, $day = NULL, $month = NULL, $year = NULL, $duration = NULL);\r
+\r
+       /**\r
+        * Return the start timestamp.\r
+        */\r
+       public function getCalendarStartTime();\r
+\r
+       /**\r
+        * Return the end timestamp.\r
+        */\r
+       public function getCalendarEndTime();\r
+}
\ No newline at end of file
diff --git a/engine/classes/ODD.php b/engine/classes/ODD.php
new file mode 100644 (file)
index 0000000..a4118ee
--- /dev/null
@@ -0,0 +1,94 @@
+<?php\r
+/**\r
+ * Open Data Definition (ODD) superclass.\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ * @author Curverider Ltd\r
+ */\r
+abstract class ODD {\r
+       /**\r
+        * Attributes.\r
+        */\r
+       private $attributes = array();\r
+\r
+       /**\r
+        * Optional body.\r
+        */\r
+       private $body;\r
+\r
+       /**\r
+        * Construct an ODD document with initial values.\r
+        */\r
+       public function __construct() {\r
+               $this->body = "";\r
+       }\r
+\r
+       public function getAttributes() {\r
+               return $this->attributes;\r
+       }\r
+\r
+       public function setAttribute($key, $value) {\r
+               $this->attributes[$key] = $value;\r
+       }\r
+\r
+       public function getAttribute($key) {\r
+               if (isset($this->attributes[$key])) {\r
+                       return $this->attributes[$key];\r
+               }\r
+\r
+               return NULL;\r
+       }\r
+\r
+       public function setBody($value) {\r
+               $this->body = $value;\r
+       }\r
+\r
+       public function getBody() {\r
+               return $this->body;\r
+       }\r
+\r
+       /**\r
+        * Set the published time.\r
+        *\r
+        * @param int $time Unix timestamp\r
+        */\r
+       public function setPublished($time) {\r
+               $this->attributes['published'] = date("r", $time);\r
+       }\r
+\r
+       /**\r
+        * Return the published time as a unix timestamp.\r
+        *\r
+        * @return int or false on failure.\r
+        */\r
+       public function getPublishedAsTime() {\r
+               return strtotime($this->attributes['published']);\r
+       }\r
+\r
+       /**\r
+        * For serialisation, implement to return a string name of the tag eg "header" or "metadata".\r
+        * @return string\r
+        */\r
+       abstract protected function getTagName();\r
+\r
+       /**\r
+        * Magic function to generate valid ODD XML for this item.\r
+        */\r
+       public function __toString() {\r
+               // Construct attributes\r
+               $attr = "";\r
+               foreach ($this->attributes as $k => $v) {\r
+                       $attr .= ($v!="") ? "$k=\"$v\" " : "";\r
+               }\r
+\r
+               $body = $this->getBody();\r
+               $tag = $this->getTagName();\r
+\r
+               $end = "/>";\r
+               if ($body!="") {\r
+                       $end = "><![CDATA[$body]]></{$tag}>";\r
+               }\r
+\r
+               return "<{$tag} $attr" . $end . "\n";\r
+       }\r
+}\r
diff --git a/engine/classes/ODDDocument.php b/engine/classes/ODDDocument.php
new file mode 100644 (file)
index 0000000..0c8731a
--- /dev/null
@@ -0,0 +1,129 @@
+<?php\r
+/**\r
+ * @class ODDDocument ODD Document container.\r
+ * This class is used during import and export to construct.\r
+ * @author Curverider Ltd\r
+ */\r
+class ODDDocument implements Iterator {\r
+       /**\r
+        * ODD Version\r
+        *\r
+        * @var string\r
+        */\r
+       private $ODDSupportedVersion = "1.0";\r
+\r
+       /**\r
+        * Elements of the document.\r
+        */\r
+       private $elements;\r
+\r
+       /**\r
+        * Optional wrapper factory.\r
+        */\r
+       private $wrapperfactory;\r
+\r
+       public function __construct(array $elements = NULL) {\r
+               if ($elements) {\r
+                       if (is_array($elements)) {\r
+                               $this->elements = $elements;\r
+                       } else {\r
+                               $this->addElement($elements);\r
+                       }\r
+               } else {\r
+                       $this->elements = array();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Return the version of ODD being used.\r
+        *\r
+        * @return string\r
+        */\r
+       public function getVersion() {\r
+               return $this->ODDSupportedVersion;\r
+       }\r
+\r
+       public function getNumElements() {\r
+               return count($this->elements);\r
+       }\r
+\r
+       public function addElement(ODD $element) {\r
+               if (!is_array($this->elements)) {\r
+                       $this->elements = array();\r
+                       $this->elements[] = $element;\r
+               }\r
+       }\r
+\r
+       public function addElements(array $elements) {\r
+               foreach ($elements as $element) {\r
+                       $this->addElement($element);\r
+               }\r
+       }\r
+\r
+       public function getElements() {\r
+               return $this->elements;\r
+       }\r
+\r
+       /**\r
+        * Set an optional wrapper factory to optionally embed the ODD document in another format.\r
+        */\r
+       public function setWrapperFactory(ODDWrapperFactory $factory) {\r
+               $this->wrapperfactory = $factory;\r
+       }\r
+\r
+       /**\r
+        * Magic function to generate valid ODD XML for this item.\r
+        */\r
+       public function __toString() {\r
+               $xml = "";\r
+\r
+               if ($this->wrapperfactory) {\r
+                       // A wrapper has been provided\r
+                       $wrapper = $this->wrapperfactory->getElementWrapper($this); // Get the wrapper for this element\r
+\r
+                       $xml = $wrapper->wrap($this); // Wrap this element (and subelements)\r
+               } else {\r
+                       // Output begin tag\r
+                       $generated = date("r");\r
+                       $xml .= "<odd version=\"{$this->ODDSupportedVersion}\" generated=\"$generated\">\n";\r
+\r
+                       // Get XML for elements\r
+                       foreach ($this->elements as $element) {\r
+                               $xml .= "$element";\r
+                       }\r
+\r
+                       // Output end tag\r
+                       $xml .= "</odd>\n";\r
+               }\r
+\r
+               return $xml;\r
+       }\r
+\r
+       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////\r
+       /*\r
+        * This lets an entity's attributes be displayed using foreach as a normal array.\r
+        * Example: http://www.sitepoint.com/print/php5-standard-library\r
+        */\r
+\r
+       private $valid = FALSE;\r
+\r
+       function rewind() {\r
+               $this->valid = (FALSE !== reset($this->elements));\r
+       }\r
+\r
+       function current() {\r
+               return current($this->elements);\r
+       }\r
+\r
+       function key() {\r
+               return key($this->elements);\r
+       }\r
+\r
+       function next() {\r
+               $this->valid = (FALSE !== next($this->elements));\r
+       }\r
+\r
+       function valid() {\r
+               return $this->valid;\r
+       }\r
+}\r
diff --git a/engine/classes/ODDEntity.php b/engine/classes/ODDEntity.php
new file mode 100644 (file)
index 0000000..30da5f3
--- /dev/null
@@ -0,0 +1,60 @@
+<?php\r
+\r
+/**\r
+ * ODD Entity class.\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ * @author Curverider Ltd\r
+ */\r
+class ODDEntity extends ODD {\r
+       function __construct($uuid, $class, $subclass = "") {\r
+               parent::__construct();\r
+\r
+               $this->setAttribute('uuid', $uuid);\r
+               $this->setAttribute('class', $class);\r
+               $this->setAttribute('subclass', $subclass);\r
+       }\r
+\r
+       protected function getTagName() { return "entity"; }\r
+}\r
+\r
+/**\r
+ * ODD Metadata class.\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ * @author Curverider Ltd\r
+ */\r
+class ODDMetaData extends ODD {\r
+       function __construct($uuid, $entity_uuid, $name, $value, $type = "", $owner_uuid = "") {\r
+               parent::__construct();\r
+\r
+               $this->setAttribute('uuid', $uuid);\r
+               $this->setAttribute('entity_uuid', $entity_uuid);\r
+               $this->setAttribute('name', $name);\r
+               $this->setAttribute('type', $type);\r
+               $this->setAttribute('owner_uuid', $owner_uuid);\r
+               $this->setBody($value);\r
+       }\r
+\r
+       protected function getTagName() {\r
+               return "metadata";\r
+       }\r
+}\r
+\r
+/**\r
+ * ODD Relationship class.\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ * @author Curverider Ltd\r
+ */\r
+class ODDRelationship extends ODD {\r
+       function __construct($uuid1, $type, $uuid2) {\r
+               parent::__construct();\r
+\r
+               $this->setAttribute('uuid1', $uuid1);\r
+               $this->setAttribute('type', $type);\r
+               $this->setAttribute('uuid2', $uuid2);\r
+       }\r
+\r
+       protected function getTagName() { return "relationship"; }\r
+}
\ No newline at end of file
diff --git a/engine/classes/SuccessResult.php b/engine/classes/SuccessResult.php
new file mode 100644 (file)
index 0000000..db5769d
--- /dev/null
@@ -0,0 +1,22 @@
+<?php\r
+/**\r
+ * SuccessResult\r
+ * Generic success result class, extend if you want to do something special.\r
+ *\r
+ * @author Curverider Ltd <info@elgg.com>\r
+ * @package Elgg\r
+ * @subpackage Core\r
+ */\r
+class SuccessResult extends GenericResult {\r
+       public static $RESULT_SUCCESS = 0;  // Do not change this from 0\r
+\r
+       public function SuccessResult($result) {\r
+               $this->setResult($result);\r
+               $this->setStatusCode(SuccessResult::$RESULT_SUCCESS);\r
+       }\r
+\r
+       public static function getInstance($result) {\r
+               // Return a new error object.\r
+               return new SuccessResult($result);\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCArrayParameter.php b/engine/classes/XMLRPCArrayParameter.php
new file mode 100644 (file)
index 0000000..600f5d9
--- /dev/null
@@ -0,0 +1,48 @@
+<?php\r
+\r
+/**\r
+ * @class XMLRPCArrayParameter An array containing other XMLRPCParameter objects.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCArrayParameter extends XMLRPCParameter\r
+{\r
+       /**\r
+        * Construct an array.\r
+        *\r
+        * @param array $parameters Optional array of parameters, if not provided then addField must be used.\r
+        */\r
+       function __construct($parameters = NULL)\r
+       {\r
+               parent::__construct();\r
+               \r
+               if (is_array($parameters))\r
+               {\r
+                       foreach ($parameters as $v)\r
+                               $this->addField($v);\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Add a field to the container.\r
+        *\r
+        * @param XMLRPCParameter $value The value.\r
+        */\r
+       public function addField(XMLRPCParameter $value)\r
+       {\r
+               if (!is_array($this->value))\r
+                       $this->value = array();\r
+                       \r
+               $this->value[] = $value;\r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               $params = "";\r
+               foreach ($this->value as $value)\r
+               {\r
+                       $params .= "$value";\r
+               }\r
+               \r
+               return "<array><data>$params</data></array>";\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCBase64Parameter.php b/engine/classes/XMLRPCBase64Parameter.php
new file mode 100644 (file)
index 0000000..b32e7f3
--- /dev/null
@@ -0,0 +1,24 @@
+<?php\r
+/**\r
+ * @class XMLRPCBase64Parameter A base 64 encoded blob of binary.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCBase64Parameter extends XMLRPCParameter\r
+{\r
+       /**\r
+        * Construct a base64 encoded block\r
+        *\r
+        * @param string $blob Unencoded binary blob\r
+        */\r
+       function __construct($blob)\r
+       {\r
+               parent::__construct();\r
+               \r
+               $this->value = base64_encode($blob);\r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               return "<value><base64>{$value}</base64></value>";\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCBoolParameter.php b/engine/classes/XMLRPCBoolParameter.php
new file mode 100644 (file)
index 0000000..c2714ce
--- /dev/null
@@ -0,0 +1,20 @@
+<?php\r
+/**\r
+ * @class XMLRPCBoolParameter A boolean.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCBoolParameter extends XMLRPCParameter\r
+{\r
+       function __construct($value)\r
+       {\r
+               parent::__construct();\r
+               \r
+               $this->value = (bool)$value; \r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               $code = ($this->value) ? "1" : "0";\r
+               return "<value><boolean>{$code}</boolean></value>";\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCCall.php b/engine/classes/XMLRPCCall.php
new file mode 100644 (file)
index 0000000..09e8e6d
--- /dev/null
@@ -0,0 +1,60 @@
+<?php\r
+/**\r
+ * @class XMLRPCCall\r
+ * This class represents \r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCCall\r
+{\r
+       /** Method name */\r
+       private $methodname;\r
+       /** Parameters */\r
+       private $params;\r
+       \r
+       /**\r
+        * Construct a new XML RPC Call\r
+        *\r
+        * @param string $xml\r
+        */\r
+       function __construct($xml)\r
+       {\r
+               $this->parse($xml);\r
+       }\r
+       \r
+       /**\r
+        * Return the method name associated with the call.\r
+        *\r
+        * @return string\r
+        */\r
+       public function getMethodName() { return $this->methodname; }\r
+       \r
+       /**\r
+        * Return the parameters.\r
+        * Returns a nested array of XmlElement.\r
+        * \r
+        * @see XmlElement \r
+        * @return array\r
+        */\r
+       public function getParameters() { return $this->params; }\r
+       \r
+       /**\r
+        * Parse the xml into its components according to spec. \r
+        * This first version is a little primitive. \r
+        *\r
+        * @param string $xml\r
+        */\r
+       private function parse($xml)\r
+       {\r
+               $xml = xml_to_object($xml);\r
+               \r
+               // sanity check\r
+               if ((isset($xml->name)) && (strcasecmp($xml->name, "methodCall")!=0))\r
+                       throw new CallException(elgg_echo('CallException:NotRPCCall'));\r
+               \r
+               // method name\r
+               $this->methodname = $xml->children[0]->content;\r
+               \r
+               // parameters \r
+               $this->params = $xml->children[1]->children;                    \r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCDateParameter.php b/engine/classes/XMLRPCDateParameter.php
new file mode 100644 (file)
index 0000000..47ba88c
--- /dev/null
@@ -0,0 +1,27 @@
+<?php\r
+/**\r
+ * @class XMLRPCDateParameter An ISO8601 data and time.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCDateParameter extends XMLRPCParameter\r
+{\r
+       /**\r
+        * Construct a date\r
+        *\r
+        * @param int $timestamp The unix timestamp, or blank for "now".\r
+        */\r
+       function __construct($timestamp = 0)\r
+       {\r
+               parent::__construct();\r
+               \r
+               $this->value = $timestamp;\r
+               if (!$timestamp)\r
+                       $this->value = time(); \r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               $value = date('c', $this->value);\r
+               return "<value><dateTime.iso8601>{$value}</dateTime.iso8601></value>";\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCDoubleParameter.php b/engine/classes/XMLRPCDoubleParameter.php
new file mode 100644 (file)
index 0000000..64cbdff
--- /dev/null
@@ -0,0 +1,19 @@
+<?php\r
+/**\r
+ * @class XMLRPCDoubleParameter A double precision signed floating point number.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCDoubleParameter extends XMLRPCParameter\r
+{\r
+       function __construct($value)\r
+       {\r
+               parent::__construct();\r
+               \r
+               $this->value = (float)$value; \r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               return "<value><double>{$this->value}</double></value>";\r
+       }\r
+}\r
diff --git a/engine/classes/XMLRPCErrorResponse.php b/engine/classes/XMLRPCErrorResponse.php
new file mode 100644 (file)
index 0000000..4dfcfaf
--- /dev/null
@@ -0,0 +1,34 @@
+<?php\r
+\r
+/**\r
+ * @class XMLRPCErrorResponse\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCErrorResponse extends XMLRPCResponse\r
+{              \r
+       /**\r
+        * Set the error response and error code.\r
+        *\r
+        * @param string $message The message\r
+        * @param int $code Error code (default = system error as defined by http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php)\r
+        */\r
+       function __construct($message, $code = -32400)\r
+       {\r
+               $this->addParameter(\r
+                       new XMLRPCStructParameter(\r
+                               array (\r
+                                       'faultCode' => new XMLRPCIntParameter($code),\r
+                                       'faultString' => new XMLRPCStringParameter($message)\r
+                               )\r
+                       )\r
+               );\r
+       }\r
+       \r
+       /**\r
+        * Output to XML.\r
+        */\r
+       public function __toString()\r
+       {\r
+               return "<methodResponse><fault><value>{$this->parameters[0]}</value></fault></methodResponse>";\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCIntParameter.php b/engine/classes/XMLRPCIntParameter.php
new file mode 100644 (file)
index 0000000..2305a66
--- /dev/null
@@ -0,0 +1,19 @@
+<?php\r
+/**\r
+ * @class XMLRPCIntParameter An Integer.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCIntParameter extends XMLRPCParameter\r
+{\r
+       function __construct($value)\r
+       {\r
+               parent::__construct();\r
+               \r
+               $this->value = (int)$value; \r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               return "<value><i4>{$this->value}</i4></value>";\r
+       }\r
+}\r
diff --git a/engine/classes/XMLRPCParameter.php b/engine/classes/XMLRPCParameter.php
new file mode 100644 (file)
index 0000000..f9e04a0
--- /dev/null
@@ -0,0 +1,12 @@
+<?php\r
+/**\r
+ * @class XMLRPCParameter Superclass for all RPC parameters.\r
+ * @author Curverider Ltd\r
+ */\r
+abstract class XMLRPCParameter\r
+{\r
+       protected $value;\r
+\r
+       function __construct() { }\r
+               \r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCResponse.php b/engine/classes/XMLRPCResponse.php
new file mode 100644 (file)
index 0000000..1dea8d6
--- /dev/null
@@ -0,0 +1,29 @@
+<?php\r
+\r
+/**\r
+ * @class XMLRPCResponse XML-RPC Response. \r
+ * @author Curverider Ltd\r
+ */\r
+abstract class XMLRPCResponse\r
+{\r
+       /** An array of parameters */\r
+       protected $parameters = array();\r
+       \r
+       /**\r
+        * Add a parameter here.\r
+        *\r
+        * @param XMLRPCParameter $param The parameter.\r
+        */\r
+       public function addParameter(XMLRPCParameter $param)\r
+       {\r
+               if (!is_array($this->parameters))\r
+                       $this->parameters = array();\r
+                       \r
+               $this->parameters[] = $param;\r
+       }\r
+\r
+       public function addInt($value) { $this->addParameter(new XMLRPCIntParameter($value)); }\r
+       public function addString($value) { $this->addParameter(new XMLRPCStringParameter($value)); }\r
+       public function addDouble($value) { $this->addParameter(new XMLRPCDoubleParameter($value)); }\r
+       public function addBoolean($value) { $this->addParameter(new XMLRPCBoolParameter($value)); }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCStringParameter.php b/engine/classes/XMLRPCStringParameter.php
new file mode 100644 (file)
index 0000000..bf90977
--- /dev/null
@@ -0,0 +1,20 @@
+<?php\r
+/**\r
+ * @class XMLRPCStringParameter A string.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCStringParameter extends XMLRPCParameter\r
+{\r
+       function __construct($value)\r
+       {\r
+               parent::__construct();\r
+               \r
+               $this->value = $value; \r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               $value = htmlentities($this->value);\r
+               return "<value><string>{$value}</string></value>";\r
+       }\r
+}\r
diff --git a/engine/classes/XMLRPCStructParameter.php b/engine/classes/XMLRPCStructParameter.php
new file mode 100644 (file)
index 0000000..326a828
--- /dev/null
@@ -0,0 +1,49 @@
+<?php\r
+\r
+/**\r
+ * @class XMLRPCStructParameter A structure containing other XMLRPCParameter objects.\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCStructParameter extends XMLRPCParameter\r
+{\r
+       /**\r
+        * Construct a struct.\r
+        *\r
+        * @param array $parameters Optional associated array of parameters, if not provided then addField must be used.\r
+        */\r
+       function __construct($parameters = NULL)\r
+       {\r
+               parent::__construct();\r
+               \r
+               if (is_array($parameters))\r
+               {\r
+                       foreach ($parameters as $k => $v)\r
+                               $this->addField($k, $v);\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Add a field to the container.\r
+        *\r
+        * @param string $name The name of the field.\r
+        * @param XMLRPCParameter $value The value.\r
+        */\r
+       public function addField($name, XMLRPCParameter $value)\r
+       {\r
+               if (!is_array($this->value))\r
+                       $this->value = array();\r
+                       \r
+               $this->value[$name] = $value;\r
+       }\r
+       \r
+       function __toString() \r
+       {\r
+               $params = "";\r
+               foreach ($this->value as $k => $v)\r
+               {\r
+                       $params .= "<member><name>$k</name>$v</member>";\r
+               }\r
+               \r
+               return "<value><struct>$params</struct></value>";\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XMLRPCSuccessResponse.php b/engine/classes/XMLRPCSuccessResponse.php
new file mode 100644 (file)
index 0000000..cffa644
--- /dev/null
@@ -0,0 +1,19 @@
+<?php\r
+/**\r
+ * @class XMLRPCSuccessResponse\r
+ * @author Curverider Ltd\r
+ */\r
+class XMLRPCSuccessResponse extends XMLRPCResponse\r
+{\r
+       /**\r
+        * Output to XML.\r
+        */\r
+       public function __toString()\r
+       {\r
+               $params = "";\r
+               foreach ($this->parameters as $param)\r
+                       $params .= "<param>$param</param>\n";\r
+               \r
+               return "<methodResponse><params>$params</params></methodResponse>";\r
+       }\r
+}
\ No newline at end of file
diff --git a/engine/classes/XmlElement.php b/engine/classes/XmlElement.php
new file mode 100644 (file)
index 0000000..17e3151
--- /dev/null
@@ -0,0 +1,19 @@
+<?php\r
+/**\r
+ * @class XmlElement\r
+ * A class representing an XML element for import.\r
+ */\r
+class XmlElement \r
+{\r
+       /** The name of the element */\r
+       public $name;\r
+       \r
+       /** The attributes */\r
+       public $attributes;\r
+       \r
+       /** CData */\r
+       public $content;\r
+       \r
+       /** Child elements */\r
+       public $children;\r
+};
\ No newline at end of file
index c7a87ced574569c04e9475d50d995f009f2950cd..4155fc4084bbad22cba280f4a79755e764d6e04f 100644 (file)
  * @link http://elgg.org/
  */
 
-/**
- * Temporary class used to determing if access is being ignored
- */
-class ElggAccess {
-       /**
-        * Bypass Elgg's access control if true.
-        * @var bool
-        */
-       private $ignore_access;
-
-       /**
-        * Get current ignore access setting.
-        * @return bool
-        */
-       public function get_ignore_access() {
-               return $this->ignore_access;
-       }
-
-       /**
-        * Set ignore access.
-        *
-        * @param $ignore bool true || false to ignore
-        * @return bool Previous setting
-        */
-       public function set_ignore_access($ignore = true) {
-               $prev = $this->ignore_access;
-               $this->ignore_access = $ignore;
-
-               return $prev;
-       }
-}
+include dirname(dirname(__FILE__)).'/classes/ElggAccess.php';
 
 
 /**
index 806e3699fb09f814bc96af45542f42eaf0eac053..3c8bb2aade267daba0c5fb6b4e00d78f97079376 100644 (file)
@@ -9,118 +9,9 @@
  * @link http://elgg.org/
  */
 
-/**
- * Include the ElggExtender superclass
- *
- */
-require_once('extender.php');
-
-/**
- * ElggAnnotation
- *
- * An annotation is similar to metadata.
- * Each entity can have more than one of each type of annotation.
- *
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd <info@elgg.com>
- */
-class ElggAnnotation extends ElggExtender {
-
-       /**
-        * Construct a new annotation, optionally from a given id value or db object.
-        *
-        * @param mixed $id
-        */
-       function __construct($id = null) {
-               $this->attributes = array();
-
-               if (!empty($id)) {
-                       if ($id instanceof stdClass) {
-                               $annotation = $id;
-                       } else {
-                               $annotation = get_annotation($id);
-                       }
-
-                       if ($annotation) {
-                               $objarray = (array) $annotation;
-
-                               foreach($objarray as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-
-                               $this->attributes['type'] = "annotation";
-                       }
-               }
-       }
-
-       /**
-        * Class member get overloading
-        *
-        * @param string $name
-        * @return mixed
-        */
-       function __get($name) {
-               return $this->get($name);
-       }
-
-       /**
-        * Class member set overloading
-        *
-        * @param string $name
-        * @param mixed $value
-        * @return void
-        */
-       function __set($name, $value) {
-               return $this->set($name, $value);
-       }
-
-       /**
-        * Save this instance
-        *
-        * @return int an object id
-        */
-       function save() {
-               if ($this->id > 0) {
-                       return update_annotation($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
-               } else {
-                       $this->id = create_annotation($this->entity_guid, $this->name, $this->value,
-                               $this->value_type, $this->owner_guid, $this->access_id);
-
-                       if (!$this->id) {
-                               throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));
-                       }
-                       return $this->id;
-               }
-       }
-
-       /**
-        * Delete the annotation.
-        */
-       function delete() {
-               return delete_annotation($this->id);
-       }
-
-       /**
-        * Get a url for this annotation.
-        *
-        * @return string
-        */
-       public function getURL() {
-               return get_annotation_url($this->id);
-       }
-
-       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
+require_once 'extender.php';
 
-       /**
-        * For a given ID, return the object associated with it.
-        * This is used by the river functionality primarily.
-        * This is useful for checking access permissions etc on objects.
-        */
-       public function getObjectFromID($id) {
-               return get_annotation($id);
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggAnnotation.php';
 
 /**
  * Convert a database row to a new ElggAnnotation
index 82377410892ab6de2ed4546eb833d8c83d4d2905..7a6fd54af8d1eb9884a5b14c881f548c5febe003 100644 (file)
 
 // Result classes /////////////////////////////////////////////////////////////////////////
 
-/**
- * GenericResult Result superclass.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-abstract class GenericResult {
-       /**
-        * The status of the result.
-        * @var int
-        */
-       private $status_code;
-
-       /**
-        * Message returned along with the status which is almost always an error message.
-        * This must be human readable, understandable and localised.
-        * @var string
-        */
-       private $message;
-
-       /**
-        * Result store.
-        * Attach result specific informaton here.
-        *
-        * @var mixed. Should probably be an object of some sort.
-        */
-       private $result;
-
-       /**
-        * Set a status code and optional message.
-        *
-        * @param int $status The status code.
-        * @param string $message The message.
-        */
-       protected function setStatusCode($status, $message = "") {
-               $this->status_code = $status;
-               $this->message = $message;
-       }
-
-       /**
-        * Set the result.
-        *
-        * @param mixed $result
-        */
-       protected function setResult($result) {
-               $this->result = $result;
-       }
-
-       protected function getStatusCode() {
-               return $this->status_code;
-       }
-
-       protected function getStatusMessage() {
-               return $this->message;
-       }
-
-       protected function getResult() {
-               return $this->result;
-       }
-
-       /**
-        * Serialise to a standard class.
-        *
-        * DEVNOTE: The API is only interested in data, we can not easily serialise
-        * custom classes without the need for 1) the other side being PHP, 2) you need to have the class
-        * definition installed, 3) its the right version!
-        *
-        * Therefore, I'm not bothering.
-        *
-        * Override this to include any more specific information, however api results should be attached to the
-        * class using setResult().
-        *
-        * if $CONFIG->debug is set then additional information about the runtime environment and authentication will be
-        * returned.
-        *
-        * @return stdClass Object containing the serialised result.
-        */
-       public function export() {
-               global $ERRORS, $CONFIG, $_PAM_HANDLERS_MSG;
-
-               $result = new stdClass;
-
-               $result->status = $this->getStatusCode();
-               if ($this->getStatusMessage()!="") {
-                       $result->message = $this->getStatusMessage();
-               }
-
-               $resultdata = $this->getResult();
-               if (isset($resultdata)) {
-                       $result->result = $resultdata;
-               }
-
-               if (isset($CONFIG->debug)) {
-                       if (count($ERRORS)) {
-                               $result->runtime_errors = $ERRORS;
-                       }
-
-                       if (count($_PAM_HANDLERS_MSG)) {
-                               $result->pam = $_PAM_HANDLERS_MSG;
-                       }
-               }
-
-               return $result;
-       }
-}
-
-/**
- * SuccessResult
- * Generic success result class, extend if you want to do something special.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-class SuccessResult extends GenericResult {
-       public static $RESULT_SUCCESS = 0;  // Do not change this from 0
-
-       public function SuccessResult($result) {
-               $this->setResult($result);
-               $this->setStatusCode(SuccessResult::$RESULT_SUCCESS);
-       }
-
-       public static function getInstance($result) {
-               // Return a new error object.
-               return new SuccessResult($result);
-       }
-}
-
-/**
- * ErrorResult
- * The error result class.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-class ErrorResult extends GenericResult {
-       // Fail with no specific code
-       public static $RESULT_FAIL = -1 ;
-
-       public static $RESULT_FAIL_APIKEY_DISABLED = -30;
-       public static $RESULT_FAIL_APIKEY_INACTIVE = -31;
-       public static $RESULT_FAIL_APIKEY_INVALID = -32;
-
-       // Invalid, expired or missing auth token
-       public static $RESULT_FAIL_AUTHTOKEN = -20;
-
-       public function ErrorResult($message, $code = "", Exception $exception = NULL) {
-               if ($code == "") {
-                       $code = ErrorResult::$RESULT_FAIL;
-               }
-
-               if ($exception!=NULL) {
-                       $this->setResult($exception->__toString());
-               }
-
-               $this->setStatusCode($code, $message);
-       }
-
-       /**
-        * Get a new instance of the ErrorResult.
-        *
-        * @param string $message
-        * @param int $code
-        * @param Exception $exception Optional exception for generating a stack trace.
-        */
-       public static function getInstance($message, $code = "", Exception $exception = NULL) {
-               // Return a new error object.
-               return new ErrorResult($message, $code, $exception);
-       }
-}
-
-// Caching of HMACs ///////////////////////////////////////////////////////////////////////
-
-/**
- * ElggHMACCache
- * Store cached data in a temporary database, only used by the HMAC stuff.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage API
- */
-class ElggHMACCache extends ElggCache {
-       /**
-        * Set the Elgg cache.
-        *
-        * @param int $max_age Maximum age in seconds, 0 if no limit.
-        */
-       function __construct($max_age = 0) {
-               $this->set_variable("max_age", $max_age);
-       }
-
-       /**
-        * Save a key
-        *
-        * @param string $key
-        * @param string $data
-        * @return boolean
-        */
-       public function save($key, $data) {
-               global $CONFIG;
-
-               $key = sanitise_string($key);
-               $time = time();
-
-               return insert_data("INSERT into {$CONFIG->dbprefix}hmac_cache (hmac, ts) VALUES ('$key', '$time')");
-       }
-
-       /**
-        * Load a key
-        *
-        * @param string $key
-        * @param int $offset
-        * @param int $limit
-        * @return string
-        */
-       public function load($key, $offset = 0, $limit = null) {
-               global $CONFIG;
-
-               $key = sanitise_string($key);
-
-               $row = get_data_row("SELECT * from {$CONFIG->dbprefix}hmac_cache where hmac='$key'");
-               if ($row) {
-                       return $row->hmac;
-               }
-
-               return false;
-       }
-
-       /**
-        * Invalidate a given key.
-        *
-        * @param string $key
-        * @return bool
-        */
-       public function delete($key) {
-               global $CONFIG;
-
-               $key = sanitise_string($key);
-
-               return delete_data("DELETE from {$CONFIG->dbprefix}hmac_cache where hmac='$key'");
-       }
-
-       /**
-        * Clear out all the contents of the cache.
-        *
-        * Not currently implemented in this cache type.
-        */
-       public function clear() {
-               return true;
-       }
-
-       /**
-        * Clean out old stuff.
-        *
-        */
-       public function __destruct() {
-               global $CONFIG;
-
-               $time = time();
-               $age = (int)$this->get_variable("max_age");
-
-               $expires = $time-$age;
-
-               delete_data("DELETE from {$CONFIG->dbprefix}hmac_cache where ts<$expires");
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/GenericResult.php';
+require_once dirname(dirname(__FILE__)).'/classes/SuccessResult.php';
+require_once dirname(dirname(__FILE__)).'/classes/ErrorResult.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggHMACCache.php';
 
 // Primary Services API Server functions /////////////////////////////////////////////////////////////////////
 
index e227ba7709388bd01355d15fb8b03c925ffe5fa9..3e8a75d7b24d67923982df6be35cadccba9f094a 100644 (file)
@@ -9,429 +9,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * ElggCache The elgg cache superclass.
- * This defines the interface for a cache (wherever that cache is stored).
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage API
- */
-abstract class ElggCache implements
-       // Override for array access
-       ArrayAccess  {
-       /**
-        * Variables for the cache object.
-        *
-        * @var array
-        */
-       private $variables;
-
-       /**
-        * Set the constructor.
-        */
-       function __construct() {
-               $this->variables = array();
-       }
-
-       /**
-        * Set a cache variable.
-        *
-        * @param string $variable
-        * @param string $value
-        */
-       public function set_variable($variable, $value) {
-               if (!is_array($this->variables)) {
-                       $this->variables = array();
-               }
-
-               $this->variables[$variable] = $value;
-       }
-
-       /**
-        * Get variables for this cache.
-        *
-        * @param string $variable
-        * @return mixed The variable or null;
-        */
-       public function get_variable($variable) {
-               if (isset($this->variables[$variable])) {
-                       return $this->variables[$variable];
-               }
-
-               return null;
-       }
-
-       /**
-        * Class member get overloading, returning key using $this->load defaults.
-        *
-        * @param string $key
-        * @return mixed
-        */
-       function __get($key) {
-               return $this->load($key);
-       }
-
-       /**
-        * Class member set overloading, setting a key using $this->save defaults.
-        *
-        * @param string $key
-        * @param mixed $value
-        * @return mixed
-        */
-       function __set($key, $value) {
-               return $this->save($key, $value);
-       }
-
-       /**
-        * Supporting isset, using $this->load() with default values.
-        *
-        * @param string $key The name of the attribute or metadata.
-        * @return bool
-        */
-       function __isset($key) {
-               return (bool)$this->load($key);
-       }
-
-       /**
-        * Supporting unsetting of magic attributes.
-        *
-        * @param string $key The name of the attribute or metadata.
-        */
-       function __unset($key) {
-               return $this->delete($key);
-       }
-
-       /**
-        * Save data in a cache.
-        *
-        * @param string $key
-        * @param string $data
-        * @return bool
-        */
-       abstract public function save($key, $data);
-
-       /**
-        * Load data from the cache using a given key.
-        *
-        * @param string $key
-        * @param int $offset
-        * @param int $limit
-        * @return mixed The stored data or false.
-        */
-       abstract public function load($key, $offset = 0, $limit = null);
-
-       /**
-        * Invalidate a key
-        *
-        * @param string $key
-        * @return bool
-        */
-       abstract public function delete($key);
-
-       /**
-        * Clear out all the contents of the cache.
-        *
-        */
-       abstract public function clear();
-
-       /**
-        * Add a key only if it doesn't already exist.
-        * Implemented simply here, if you extend this class and your caching engine provides a better way then
-        * override this accordingly.
-        *
-        * @param string $key
-        * @param string $data
-        * @return bool
-        */
-       public function add($key, $data) {
-               if (!isset($this[$key])) {
-                       return $this->save($key, $data);
-               }
-
-               return false;
-       }
-
-       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
-       function offsetSet($key, $value) {
-               $this->save($key, $value);
-       }
-
-       function offsetGet($key) {
-               return $this->load($key);
-       }
-
-       function offsetUnset($key) {
-               if ( isset($this->key) ) {
-                       unset($this->key);
-               }
-       }
-
-       function offsetExists($offset) {
-               return isset($this->$offset);
-       }
-}
-
-/**
- * Shared memory cache description.
- * Extends ElggCache with functions useful to shared memory style caches (static variables, memcache etc)
- */
-abstract class ElggSharedMemoryCache extends ElggCache {
-       /**
-        * Namespace variable used to keep various bits of the cache
-        * separate.
-        *
-        * @var string
-        */
-       private $namespace;
-
-       /**
-        * Set the namespace of this cache.
-        * This is useful for cache types (like memcache or static variables) where there is one large
-        * flat area of memory shared across all instances of the cache.
-        *
-        * @param string $namespace
-        */
-       public function setNamespace($namespace = "default") {
-               $this->namespace = $namespace;
-       }
-
-       /**
-        * Get the namespace currently defined.
-        *
-        * @return string
-        */
-       public function getNamespace() {
-               return $this->namespace;
-       }
-}
-
-/**
- * ElggStaticVariableCache
- * Dummy cache which stores values in a static array. Using this makes future replacements to other caching back
- * ends (eg memcache) much easier.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage API
- */
-class ElggStaticVariableCache extends ElggSharedMemoryCache {
-       /**
-        * The cache.
-        *
-        * @var unknown_type
-        */
-       private static $__cache;
-
-       /**
-        * Create the variable cache.
-        *
-        * This function creates a variable cache in a static variable in memory, optionally with a given namespace (to avoid overlap).
-        *
-        * @param string $namespace The namespace for this cache to write to - note, namespaces of the same name are shared!
-        */
-       function __construct($namespace = 'default') {
-               $this->setNamespace($namespace);
-               $this->clear();
-       }
-
-       public function save($key, $data) {
-               $namespace = $this->getNamespace();
-
-               ElggStaticVariableCache::$__cache[$namespace][$key] = $data;
-
-               return true;
-       }
-
-       public function load($key, $offset = 0, $limit = null) {
-               $namespace = $this->getNamespace();
-
-               if (isset(ElggStaticVariableCache::$__cache[$namespace][$key])) {
-                       return ElggStaticVariableCache::$__cache[$namespace][$key];
-               }
-
-               return false;
-       }
-
-       public function delete($key) {
-               $namespace = $this->getNamespace();
-
-               unset(ElggStaticVariableCache::$__cache[$namespace][$key]);
-
-               return true;
-       }
-
-       public function clear() {
-               $namespace = $this->getNamespace();
-
-               if (!isset(ElggStaticVariableCache::$__cache)) {
-                       ElggStaticVariableCache::$__cache = array();
-               }
-
-               ElggStaticVariableCache::$__cache[$namespace] = array();
-       }
-}
-
-/**
- * ElggFileCache
- * Store cached data in a file store.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage API
- */
-class ElggFileCache extends ElggCache {
-       /**
-        * Set the Elgg cache.
-        *
-        * @param string $cache_path The cache path.
-        * @param int $max_age Maximum age in seconds, 0 if no limit.
-        * @param int $max_size Maximum size of cache in seconds, 0 if no limit.
-        */
-       function __construct($cache_path, $max_age = 0, $max_size = 0) {
-               $this->set_variable("cache_path", $cache_path);
-               $this->set_variable("max_age", $max_age);
-               $this->set_variable("max_size", $max_size);
-
-               if ($cache_path=="") {
-                       throw new ConfigurationException(elgg_echo('ConfigurationException:NoCachePath'));
-               }
-       }
-
-       /**
-        * Create and return a handle to a file.
-        *
-        * @param string $filename
-        * @param string $rw
-        */
-       protected function create_file($filename, $rw = "rb") {
-               // Create a filename matrix
-               $matrix = "";
-               $depth = strlen($filename);
-               if ($depth > 5) {
-                       $depth = 5;
-               }
-
-               // Create full path
-               $path = $this->get_variable("cache_path") . $matrix;
-               if (!is_dir($path)) {
-                       mkdir($path, 0700, true);
-               }
-
-               // Open the file
-               if ((!file_exists($path . $filename)) && ($rw=="rb")) {
-                       return false;
-               }
-
-               return fopen($path . $filename, $rw);
-       }
-
-       /**
-        * Create a sanitised filename for the file.
-        *
-        * @param string $filename
-        */
-       protected function sanitise_filename($filename) {
-               // @todo : Writeme
-
-               return $filename;
-       }
-
-       /**
-        * Save a key
-        *
-        * @param string $key
-        * @param string $data
-        * @return boolean
-        */
-       public function save($key, $data) {
-               $f = $this->create_file($this->sanitise_filename($key), "wb");
-               if ($f) {
-                       $result = fwrite($f, $data);
-                       fclose($f);
-
-                       return $result;
-               }
-
-               return false;
-       }
-
-       /**
-        * Load a key
-        *
-        * @param string $key
-        * @param int $offset
-        * @param int $limit
-        * @return string
-        */
-       public function load($key, $offset = 0, $limit = null) {
-               $f = $this->create_file($this->sanitise_filename($key));
-               if ($f) {
-                       //fseek($f, $offset);
-                       if (!$limit) {
-                               $limit = -1;
-                       }
-                       $data = stream_get_contents($f, $limit, $offset);
-
-                       fclose($f);
-
-                       return $data;
-               }
-
-               return false;
-       }
-
-       /**
-        * Invalidate a given key.
-        *
-        * @param string $key
-        * @return bool
-        */
-       public function delete($key) {
-               $dir = $this->get_variable("cache_path");
-               
-               if (file_exists($dir.$key)) {
-                       return unlink($dir.$key);
-               }
-               return TRUE;
-       }
-
-       public function clear() {
-               // @todo writeme
-       }
-
-       public function __destruct() {
-               // @todo Check size and age, clean up accordingly
-               $size = 0;
-               $dir = $this->get_variable("cache_path");
-
-               // Short circuit if both size and age are unlimited
-               if (($this->get_variable("max_age")==0) && ($this->get_variable("max_size")==0)) {
-                       return;
-               }
-
-               $exclude = array(".","..");
-
-               $files = scandir($dir);
-               if (!$files) {
-                       throw new IOException(sprintf(elgg_echo('IOException:NotDirectory'), $dir));
-               }
-
-               // Perform cleanup
-               foreach ($files as $f) {
-                       if (!in_array($f, $exclude)) {
-                               $stat = stat($dir.$f);
-
-                               // Add size
-                               $size .= $stat['size'];
-
-                               // Is this older than my maximum date?
-                               if (($this->get_variable("max_age")>0) && (time() - $stat['mtime'] > $this->get_variable("max_age"))) {
-                                       unlink($dir.$f);
-                               }
-
-                               // @todo Size
-                       }
-               }
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggCache.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggSharedMemoryCache.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggStaticVariableCache.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggFileCache.php';
index a9d6dfadff4a01914171fc685f9d3e856af8789a..5e4584515a614b82da01de9b3a5d46204fed5e43 100644 (file)
@@ -8,35 +8,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * Calendar interface for events.
- *
- */
-interface Notable {
-       /**
-        * Calendar functionality.
-        * This function sets the time of an object on a calendar listing.
-        *
-        * @param int $hour If ommitted, now is assumed.
-        * @param int $minute If ommitted, now is assumed.
-        * @param int $second If ommitted, now is assumed.
-        * @param int $day If ommitted, now is assumed.
-        * @param int $month If ommitted, now is assumed.
-        * @param int $year If ommitted, now is assumed.
-        * @param int $duration Duration of event, remainder of the day is assumed.
-        */
-       public function setCalendarTimeAndDuration($hour = NULL, $minute = NULL, $second = NULL, $day = NULL, $month = NULL, $year = NULL, $duration = NULL);
-
-       /**
-        * Return the start timestamp.
-        */
-       public function getCalendarStartTime();
-
-       /**
-        * Return the end timestamp.
-        */
-       public function getCalendarEndTime();
-}
+require_once dirname(dirname(__FILE__)).'/classes/Notable.php';
 
 /**
  * Return a timestamp for the start of a given day (defaults today).
index 223b6774f66c9860b976b246782ce1fd292bbd7c..408a5c51fa937cd5d0f5af5e2636a5d43e70b5af 100644 (file)
@@ -8,8 +8,7 @@
  * @link http://elgg.org/
  */
 
-/** The cron exception. */
-class CronException extends Exception {}
+require_once dirname(dirname(__FILE__)).'/classes/CronException.php';
 
 /**
  * Initialisation
index 9a09d4f72443c2f56caafe1bfc054ad77d57723a..d4aa37a537ea215e5f2f7c9197cc9ca4fa09b07e 100644 (file)
@@ -1750,88 +1750,7 @@ function is_ip_in_array(array $networks, $ip) {
        return false;
 }
 
-/**
- * An interface for objects that behave as elements within a social network that have a profile.
- *
- */
-interface Friendable {
-       /**
-        * Adds a user as a friend
-        *
-        * @param int $friend_guid The GUID of the user to add
-        */
-       public function addFriend($friend_guid);
-
-       /**
-        * Removes a user as a friend
-        *
-        * @param int $friend_guid The GUID of the user to remove
-        */
-       public function removeFriend($friend_guid);
-
-       /**
-        * Determines whether or not the current user is a friend of this entity
-        *
-        */
-       public function isFriend();
-
-       /**
-        * Determines whether or not this entity is friends with a particular entity
-        *
-        * @param int $user_guid The GUID of the entity this entity may or may not be friends with
-        */
-       public function isFriendsWith($user_guid);
-
-       /**
-        * Determines whether or not a foreign entity has made this one a friend
-        *
-        * @param int $user_guid The GUID of the foreign entity
-        */
-       public function isFriendOf($user_guid);
-
-       /**
-        * Returns this entity's friends
-        *
-        * @param string $subtype The subtype of entity to return
-        * @param int $limit The number of entities to return
-        * @param int $offset Indexing offset
-        */
-       public function getFriends($subtype = "", $limit = 10, $offset = 0);
-
-       /**
-        * Returns entities that have made this entity a friend
-        *
-        * @param string $subtype The subtype of entity to return
-        * @param int $limit The number of entities to return
-        * @param int $offset Indexing offset
-        */
-       public function getFriendsOf($subtype = "", $limit = 10, $offset = 0);
-
-       /**
-        * Returns objects in this entity's container
-        *
-        * @param string $subtype The subtype of entity to return
-        * @param int $limit The number of entities to return
-        * @param int $offset Indexing offset
-        */
-       public function getObjects($subtype="", $limit = 10, $offset = 0);
-
-       /**
-        * Returns objects in the containers of this entity's friends
-        *
-        * @param string $subtype The subtype of entity to return
-        * @param int $limit The number of entities to return
-        * @param int $offset Indexing offset
-        */
-       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0);
-
-       /**
-        * Returns the number of object entities in this entity's container
-        *
-        * @param string $subtype The subtype of entity to count
-        */
-       public function countObjects($subtype = "");
-}
+require_once dirname(dirname(__FILE__)).'/classes/Friendable.php';
 
 /**
  * Rebuilds a parsed (partial) URL
index 813759c8b0a2f885e6ee6494d991a7f8aaae8a99..2ba762c2cdd0b96a5ab986a9d39a4bc3a5071eb0 100644 (file)
@@ -19,1215 +19,7 @@ $SUBTYPE_CACHE = NULL;
 // @todo Move this into start.php?
 require_once('location.php');
 
-/**
- * ElggEntity The elgg entity superclass
- * This class holds methods for accessing the main entities table.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-abstract class ElggEntity implements
-       Notable,    // Calendar interface
-       Locatable,  // Geocoding interface
-       Exportable, // Allow export of data
-       Importable, // Allow import of data
-       Loggable,       // Can events related to this object class be logged
-       Iterator,       // Override foreach behaviour
-       ArrayAccess // Override for array access
-{
-       /**
-        * The main attributes of an entity.
-        * Blank entries for all database fields should be created by the constructor.
-        * Subclasses should add to this in their constructors.
-        * Any field not appearing in this will be viewed as a
-        */
-       protected $attributes;
-
-       /**
-        * If set, overrides the value of getURL()
-        */
-       protected $url_override;
-
-       /**
-        * Icon override, overrides the value of getIcon().
-        */
-       protected $icon_override;
-
-       /**
-        * Temporary cache for metadata, permitting meta data access before a guid has obtained.
-        */
-       protected $temp_metadata;
-
-       /**
-        * Temporary cache for annotations, permitting meta data access before a guid has obtained.
-        */
-       protected $temp_annotations;
-
-
-       /**
-        * Volatile data structure for this object, allows for storage of data
-        * in-memory that isn't sync'd back to the metadata table.
-        */
-       protected $volatile;
-
-       /**
-        * Initialise the attributes array.
-        * This is vital to distinguish between metadata and base parameters.
-        *
-        * Place your base parameters here.
-        *
-        * @return void
-        */
-       protected function initialise_attributes() {
-               initialise_entity_cache();
-
-               // Create attributes array if not already created
-               if (!is_array($this->attributes)) {
-                       $this->attributes = array();
-               }
-               if (!is_array($this->temp_metadata)) {
-                       $this->temp_metadata = array();
-               }
-               if (!is_array($this->temp_annotations)) {
-                       $this->temp_annotations = array();
-               }
-               if (!is_array($this->volatile)) {
-                       $this->volatile = array();
-               }
-
-               $this->attributes['guid'] = "";
-               $this->attributes['type'] = "";
-               $this->attributes['subtype'] = "";
-
-               $this->attributes['owner_guid'] = get_loggedin_userid();
-               $this->attributes['container_guid'] = get_loggedin_userid();
-
-               $this->attributes['site_guid'] = 0;
-               $this->attributes['access_id'] = ACCESS_PRIVATE;
-               $this->attributes['time_created'] = "";
-               $this->attributes['time_updated'] = "";
-               $this->attributes['last_action'] = '';
-               $this->attributes['enabled'] = "yes";
-
-               // There now follows a bit of a hack
-               /* Problem: To speed things up, some objects are split over several tables, this means that it requires
-                * n number of database reads to fully populate an entity. This causes problems for caching and create events
-                * since it is not possible to tell whether a subclassed entity is complete.
-                * Solution: We have two counters, one 'tables_split' which tells whatever is interested how many tables
-                * are going to need to be searched in order to fully populate this object, and 'tables_loaded' which is how
-                * many have been loaded thus far.
-                * If the two are the same then this object is complete.
-                *
-                * Use: isFullyLoaded() to check
-                */
-               $this->attributes['tables_split'] = 1;
-               $this->attributes['tables_loaded'] = 0;
-       }
-
-       /**
-        * Clone an entity
-        *
-        * Resets the guid so that the entity can be saved as a distinct entity from
-        * the original. Creation time will be set when this new entity is saved.
-        * The owner and container guids come from the original entity. The clone
-        * method copies metadata but does not copy over annotations, or private settings.
-        *
-        * Note: metadata will have its owner and access id set when the entity is saved
-        * and it will be the same as that of the entity.
-        */
-       public function __clone() {
-
-               $orig_entity = get_entity($this->guid);
-               if (!$orig_entity) {
-                       elgg_log("Failed to clone entity with GUID $this->guid", "ERROR");
-                       return;
-               }
-
-               $metadata_array = get_metadata_for_entity($this->guid);
-
-               $this->attributes['guid'] = "";
-
-               $this->attributes['subtype'] = $orig_entity->getSubtype();
-
-               // copy metadata over to new entity - slightly convoluted due to
-               // handling of metadata arrays
-               if (is_array($metadata_array)) {
-                       // create list of metadata names
-                       $metadata_names = array();
-                       foreach ($metadata_array as $metadata) {
-                               $metadata_names[] = $metadata['name'];
-                       }
-                       // arrays are stored with multiple enties per name
-                       $metadata_names = array_unique($metadata_names);
-
-                       // move the metadata over
-                       foreach ($metadata_names as $name) {
-                               $this->set($name, $orig_entity->$name);
-                       }
-               }
-       }
-
-       /**
-        * Return the value of a given key.
-        * If $name is a key field (as defined in $this->attributes) that value is returned, otherwise it will
-        * then look to see if the value is in this object's metadata.
-        *
-        * Q: Why are we not using __get overload here?
-        * A: Because overload operators cause problems during subclassing, so we put the code here and
-        * create overloads in subclasses.
-        *
-        * subtype is returned as an id rather than the subtype string. Use getSubtype()
-        * to get the subtype string.
-        *
-        * @param string $name
-        * @return mixed Returns the value of a given value, or null.
-        */
-       public function get($name) {
-               // See if its in our base attribute
-               if (isset($this->attributes[$name])) {
-                       return $this->attributes[$name];
-               }
-
-               // No, so see if its in the meta data for this entity
-               $meta = $this->getMetaData($name);
-
-               // getMetaData returns NULL if $name is not found
-               return $meta;
-       }
-
-       /**
-        * Set the value of a given key, replacing it if necessary.
-        * If $name is a base attribute (as defined in $this->attributes) that value is set, otherwise it will
-        * set the appropriate item of metadata.
-        *
-        * Note: It is important that your class populates $this->attributes with keys for all base attributes, anything
-        * not in their gets set as METADATA.
-        *
-        * Q: Why are we not using __set overload here?
-        * A: Because overload operators cause problems during subclassing, so we put the code here and
-        * create overloads in subclasses.
-        *
-        * @param string $name
-        * @param mixed $value
-        */
-       public function set($name, $value) {
-               if (array_key_exists($name, $this->attributes)) {
-                       // Certain properties should not be manually changed!
-                       switch ($name) {
-                               case 'guid':
-                               case 'time_created':
-                               case 'time_updated':
-                               case 'last_action':
-                                       return FALSE;
-                                       break;
-                               default:
-                                       $this->attributes[$name] = $value;
-                                       break;
-                       }
-               } else {
-                       return $this->setMetaData($name, $value);
-               }
-
-               return TRUE;
-       }
-
-       /**
-        * Get a given piece of metadata.
-        *
-        * @param string $name
-        */
-       public function getMetaData($name) {
-               if ((int) ($this->guid) > 0) {
-                       $md = get_metadata_byname($this->getGUID(), $name);
-               } else {
-                       if (isset($this->temp_metadata[$name])) {
-                               return $this->temp_metadata[$name];
-                       }
-               }
-
-               if ($md && !is_array($md)) {
-                       return $md->value;
-               } else if ($md && is_array($md)) {
-                       return metadata_array_to_values($md);
-               }
-
-               return null;
-       }
-
-       /**
-        * Class member get overloading
-        *
-        * @param string $name
-        * @return mixed
-        */
-       function __get($name) {
-               return $this->get($name);
-       }
-
-       /**
-        * Class member set overloading
-        *
-        * @param string $name
-        * @param mixed $value
-        * @return mixed
-        */
-       function __set($name, $value) {
-               return $this->set($name, $value);
-       }
-
-       /**
-        * Supporting isset.
-        *
-        * @param string $name The name of the attribute or metadata.
-        * @return bool
-        */
-       function __isset($name) {
-               return $this->$name !== NULL;
-       }
-
-       /**
-        * Supporting unsetting of magic attributes.
-        *
-        * @param string $name The name of the attribute or metadata.
-        */
-       function __unset($name) {
-               if (array_key_exists($name, $this->attributes)) {
-                       $this->attributes[$name] = "";
-               }
-               else {
-                       $this->clearMetaData($name);
-               }
-       }
-
-       /**
-        * Set a piece of metadata.
-        *
-        * @param string $name Name of the metadata
-        * @param mixed $value Value of the metadata
-        * @param string $value_type Types supported: integer and string. Will auto-identify if not set
-        * @param bool $multiple (does not support associative arrays)
-        * @return bool
-        */
-       public function setMetaData($name, $value, $value_type = "", $multiple = false) {
-               if (is_array($value)) {
-                       unset($this->temp_metadata[$name]);
-                       remove_metadata($this->getGUID(), $name);
-                       foreach ($value as $v) {
-                               if ((int) $this->guid > 0) {
-                                       $multiple = true;
-                                       if (!create_metadata($this->getGUID(), $name, $v, $value_type,
-                                       $this->getOwner(), $this->getAccessID(), $multiple)) {
-                                               return false;
-                                       }
-                               } else {
-                                       if (($multiple) && (isset($this->temp_metadata[$name]))) {
-                                               if (!is_array($this->temp_metadata[$name])) {
-                                                       $tmp = $this->temp_metadata[$name];
-                                                       $this->temp_metadata[$name] = array();
-                                                       $this->temp_metadata[$name][] = $tmp;
-                                               }
-
-                                               $this->temp_metadata[$name][] = $value;
-                                       }
-                                       else {
-                                               $this->temp_metadata[$name] = $value;
-                                       }
-                               }
-                       }
-
-                       return true;
-               } else {
-                       unset($this->temp_metadata[$name]);
-                       if ((int) $this->guid > 0) {
-                               $result = create_metadata($this->getGUID(), $name, $value, $value_type, $this->getOwner(), $this->getAccessID(), $multiple);
-                               return (bool)$result;
-                       } else {
-                               if (($multiple) && (isset($this->temp_metadata[$name]))) {
-                                       if (!is_array($this->temp_metadata[$name])) {
-                                               $tmp = $this->temp_metadata[$name];
-                                               $this->temp_metadata[$name] = array();
-                                               $this->temp_metadata[$name][] = $tmp;
-                                       }
-
-                                       $this->temp_metadata[$name][] = $value;
-                               }
-                               else {
-                                       $this->temp_metadata[$name] = $value;
-                               }
-
-                               return true;
-                       }
-               }
-       }
-
-       /**
-        * Clear metadata.
-        */
-       public function clearMetaData($name = "") {
-               if (empty($name)) {
-                       return clear_metadata($this->getGUID());
-               } else {
-                       return remove_metadata($this->getGUID(),$name);
-               }
-       }
-
-
-       /**
-        * Get a piece of volatile (non-persisted) data on this entity
-        */
-       public function getVolatileData($name) {
-               if (!is_array($this->volatile)) {
-                       $this->volatile = array();
-               }
-
-               if (array_key_exists($name, $this->volatile)) {
-                       return $this->volatile[$name];
-               } else {
-                       return NULL;
-               }
-       }
-
-
-       /**
-        * Set a piece of volatile (non-persisted) data on this entity
-        */
-       public function setVolatileData($name, $value) {
-               if (!is_array($this->volatile)) {
-                       $this->volatile = array();
-               }
-
-               $this->volatile[$name] = $value;
-       }
-
-
-       /**
-        * Remove all entities associated with this entity
-        *
-        * @return true
-        */
-       public function clearRelationships() {
-               remove_entity_relationships($this->getGUID());
-               remove_entity_relationships($this->getGUID(),"",true);
-               return true;
-       }
-
-       /**
-        * Add a relationship.
-        *
-        * @param int $guid Relationship to link to.
-        * @param string $relationship The type of relationship.
-        * @return bool
-        */
-       public function addRelationship($guid, $relationship) {
-               return add_entity_relationship($this->getGUID(), $relationship, $guid);
-       }
-
-       /**
-        * Remove a relationship
-        *
-        * @param int $guid
-        * @param str $relationship
-        * @return bool
-        */
-       public function removeRelationship($guid, $relationship) {
-               return remove_entity_relationship($this->getGUID(), $relationship, $guid);
-       }
-
-       /**
-        * Adds a private setting to this entity.
-        *
-        * @param $name
-        * @param $value
-        * @return unknown_type
-        */
-       function setPrivateSetting($name, $value) {
-               return set_private_setting($this->getGUID(), $name, $value);
-       }
-
-       /**
-        * Gets private setting for this entity
-        *
-        * @param $name
-        * @return unknown_type
-        */
-       function getPrivateSetting($name) {
-               return get_private_setting($this->getGUID(), $name);
-       }
-
-       /**
-        * Removes private setting for this entity.
-        *
-        * @param $name
-        * @return unknown_type
-        */
-       function removePrivateSetting($name) {
-               return remove_private_setting($this->getGUID(), $name);
-       }
-
-       /**
-        * Adds an annotation to an entity. By default, the type is detected automatically; however,
-        * it can also be set. Note that by default, annotations are private.
-        *
-        * @param string $name
-        * @param mixed $value
-        * @param int $access_id
-        * @param int $owner_id
-        * @param string $vartype
-        */
-       function annotate($name, $value, $access_id = ACCESS_PRIVATE, $owner_id = 0, $vartype = "") {
-               if ((int) $this->guid > 0) {
-                       return create_annotation($this->getGUID(), $name, $value, $vartype, $owner_id, $access_id);
-               } else {
-                       $this->temp_annotations[$name] = $value;
-               }
-               return true;
-       }
-
-       /**
-        * Get the annotations for an entity.
-        *
-        * @param string $name
-        * @param int $limit
-        * @param int $offset
-        * @param string $order
-        */
-       function getAnnotations($name, $limit = 50, $offset = 0, $order="asc") {
-               if ((int) ($this->guid) > 0) {
-                       return get_annotations($this->getGUID(), "", "", $name, "", 0, $limit, $offset, $order);
-               } else {
-                       return $this->temp_annotations[$name];
-               }
-       }
-
-       /**
-        * Remove all annotations or all annotations for this entity.
-        *
-        * @param string $name
-        */
-       function clearAnnotations($name = "") {
-               return clear_annotations($this->getGUID(), $name);
-       }
-
-       /**
-        * Return the annotations for the entity.
-        *
-        * @param string $name The type of annotation.
-        */
-       function countAnnotations($name = "") {
-               return count_annotations($this->getGUID(), "", "", $name);
-       }
-
-       /**
-        * Get the average of an integer type annotation.
-        *
-        * @param string $name
-        */
-       function getAnnotationsAvg($name) {
-               return get_annotations_avg($this->getGUID(), "", "", $name);
-       }
-
-       /**
-        * Get the sum of integer type annotations of a given name.
-        *
-        * @param string $name
-        */
-       function getAnnotationsSum($name) {
-               return get_annotations_sum($this->getGUID(), "", "", $name);
-       }
-
-       /**
-        * Get the minimum of integer type annotations of given name.
-        *
-        * @param string $name
-        */
-       function getAnnotationsMin($name) {
-               return get_annotations_min($this->getGUID(), "", "", $name);
-       }
-
-       /**
-        * Get the maximum of integer type annotations of a given name.
-        *
-        * @param string $name
-        */
-       function getAnnotationsMax($name) {
-               return get_annotations_max($this->getGUID(), "", "", $name);
-       }
-
-       /**
-        * Gets an array of entities from a specific relationship type
-        *
-        * @param string $relationship Relationship type (eg "friends")
-        * @param true|false $inverse Is this an inverse relationship?
-        * @param int $limit Number of elements to return
-        * @param int $offset Indexing offset
-        * @return array|false An array of entities or false on failure
-        */
-       function getEntitiesFromRelationship($relationship, $inverse = false, $limit = 50, $offset = 0) {
-               return elgg_get_entities_from_relationship(array(
-                       'relationship' => $relationship,
-                       'relationship_guid' => $this->getGUID(),
-                       'inverse_relationship' => $inverse,
-                       'limit' => $limit,
-                       'offset' => $offset
-               ));
-       }
-
-       /**
-        * Gets the number of of entities from a specific relationship type
-        *
-        * @param string $relationship Relationship type (eg "friends")
-        * @param bool $inverse_relationship
-        * @return int|false The number of entities or false on failure
-        */
-       function countEntitiesFromRelationship($relationship, $inverse_relationship = FALSE) {
-               return elgg_get_entities_from_relationship(array(
-                       'relationship' => $relationship,
-                       'relationship_guid' => $this->getGUID(),
-                       'inverse_relationship' => $inverse_relationship,
-                       'count' => TRUE
-               ));
-       }
-
-       /**
-        * Determines whether or not the specified user (by default the current one) can edit the entity
-        *
-        * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user)
-        * @return true|false
-        */
-       function canEdit($user_guid = 0) {
-               return can_edit_entity($this->getGUID(), $user_guid);
-       }
-
-       /**
-        * Determines whether or not the specified user (by default the current one) can edit metadata on the entity
-        *
-        * @param ElggMetadata $metadata The piece of metadata to specifically check
-        * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user)
-        * @return true|false
-        */
-       function canEditMetadata($metadata = null, $user_guid = 0) {
-               return can_edit_entity_metadata($this->getGUID(), $user_guid, $metadata);
-       }
-
-       /**
-        * Returns whether the given user (or current user) has the ability to write to this container.
-        *
-        * @param int $user_guid The user.
-        * @return bool
-        */
-       public function canWriteToContainer($user_guid = 0) {
-               return can_write_to_container($user_guid, $this->getGUID());
-       }
-
-       /**
-        * Obtain this entity's access ID
-        *
-        * @return int The access ID
-        */
-       public function getAccessID() {
-               return $this->get('access_id');
-       }
-
-       /**
-        * Obtain this entity's GUID
-        *
-        * @return int GUID
-        */
-       public function getGUID() {
-               return $this->get('guid');
-       }
-
-       /**
-        * Get the owner of this entity
-        *
-        * @return int The owner GUID
-        */
-       public function getOwner() {
-               return $this->get('owner_guid');
-       }
-
-       /**
-        * Returns the actual entity of the user who owns this entity, if any
-        *
-        * @return ElggEntity The owning user
-        */
-       public function getOwnerEntity() {
-               return get_entity($this->get('owner_guid'));
-       }
-
-       /**
-        * Gets the type of entity this is
-        *
-        * @return string Entity type
-        */
-       public function getType() {
-               return $this->get('type');
-       }
-
-       /**
-        * Returns the subtype of this entity
-        *
-        * @return string The entity subtype
-        */
-       public function getSubtype() {
-               // If this object hasn't been saved, then return the subtype string.
-               if (!((int) $this->guid > 0)) {
-                       return $this->get('subtype');
-               }
-
-               return get_subtype_from_id($this->get('subtype'));
-       }
-
-       /**
-        * Gets the UNIX epoch time that this entity was created
-        *
-        * @return int UNIX epoch time
-        */
-       public function getTimeCreated() {
-               return $this->get('time_created');
-       }
-
-       /**
-        * Gets the UNIX epoch time that this entity was last updated
-        *
-        * @return int UNIX epoch time
-        */
-       public function getTimeUpdated() {
-               return $this->get('time_updated');
-       }
-
-       /**
-        * Gets the display URL for this entity
-        *
-        * @return string The URL
-        */
-       public function getURL() {
-               if (!empty($this->url_override)) {
-                       return $this->url_override;
-               }
-               return get_entity_url($this->getGUID());
-       }
-
-       /**
-        * Overrides the URL returned by getURL
-        *
-        * @param string $url The new item URL
-        * @return string The URL
-        */
-       public function setURL($url) {
-               $this->url_override = $url;
-               return $url;
-       }
-
-       /**
-        * Return a url for the entity's icon, trying multiple alternatives.
-        *
-        * @param string $size Either 'large','medium','small' or 'tiny'
-        * @return string The url or false if no url could be worked out.
-        */
-       public function getIcon($size = 'medium') {
-               if (isset($this->icon_override[$size])) {
-                       return $this->icon_override[$size];
-               }
-               return get_entity_icon_url($this, $size);
-       }
-
-       /**
-        * Set an icon override for an icon and size.
-        *
-        * @param string $url The url of the icon.
-        * @param string $size The size its for.
-        * @return bool
-        */
-       public function setIcon($url, $size = 'medium') {
-               $url = sanitise_string($url);
-               $size = sanitise_string($size);
-
-               if (!$this->icon_override) {
-                       $this->icon_override = array();
-               }
-               $this->icon_override[$size] = $url;
-
-               return true;
-       }
-
-       /**
-        * Tests to see whether the object has been fully loaded.
-        *
-        * @return bool
-        */
-       public function isFullyLoaded() {
-               return ! ($this->attributes['tables_loaded'] < $this->attributes['tables_split']);
-       }
-
-       /**
-        * Save generic attributes to the entities table.
-        */
-       public function save() {
-               $guid = (int) $this->guid;
-               if ($guid > 0) {
-                       cache_entity($this);
-
-                       return update_entity(
-                               $this->get('guid'),
-                               $this->get('owner_guid'),
-                               $this->get('access_id'),
-                               $this->get('container_guid')
-                       );
-               } else {
-                       // Create a new entity (nb: using attribute array directly 'cos set function does something special!)
-                       $this->attributes['guid'] = create_entity($this->attributes['type'], $this->attributes['subtype'], $this->attributes['owner_guid'], $this->attributes['access_id'], $this->attributes['site_guid'], $this->attributes['container_guid']);
-                       if (!$this->attributes['guid']) {
-                               throw new IOException(elgg_echo('IOException:BaseEntitySaveFailed'));
-                       }
-
-                       // Save any unsaved metadata
-                       // @todo How to capture extra information (access id etc)
-                       if (sizeof($this->temp_metadata) > 0) {
-                               foreach($this->temp_metadata as $name => $value) {
-                                       $this->$name = $value;
-                                       unset($this->temp_metadata[$name]);
-                               }
-                       }
-
-                       // Save any unsaved annotations metadata.
-                       // @todo How to capture extra information (access id etc)
-                       if (sizeof($this->temp_annotations) > 0) {
-                               foreach($this->temp_annotations as $name => $value) {
-                                       $this->annotate($name, $value);
-                                       unset($this->temp_annotations[$name]);
-                               }
-                       }
-
-                       // set the subtype to id now rather than a string
-                       $this->attributes['subtype'] = get_subtype_id($this->attributes['type'], $this->attributes['subtype']);
-
-                       // Cache object handle
-                       if ($this->attributes['guid']) {
-                               cache_entity($this);
-                       }
-
-                       return $this->attributes['guid'];
-               }
-       }
-
-       /**
-        * Load the basic entity information and populate base attributes array.
-        *
-        * @param int $guid
-        */
-       protected function load($guid) {
-               $row = get_entity_as_row($guid);
-
-               if ($row) {
-                       // Create the array if necessary - all subclasses should test before creating
-                       if (!is_array($this->attributes)) {
-                               $this->attributes = array();
-                       }
-
-                       // Now put these into the attributes array as core values
-                       $objarray = (array) $row;
-                       foreach($objarray as $key => $value) {
-                               $this->attributes[$key] = $value;
-                       }
-
-                       // Increment the portion counter
-                       if (!$this->isFullyLoaded()) {
-                               $this->attributes['tables_loaded']++;
-                       }
-
-                       // Cache object handle
-                       if ($this->attributes['guid']) {
-                               cache_entity($this);
-                       }
-
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Disable this entity.
-        *
-        * @param string $reason Optional reason
-        * @param bool $recursive Recursively disable all contained entities?
-        */
-       public function disable($reason = "", $recursive = true) {
-               return disable_entity($this->get('guid'), $reason, $recursive);
-       }
-
-       /**
-        * Re-enable this entity.
-        */
-       public function enable() {
-               return enable_entity($this->get('guid'));
-       }
-
-       /**
-        * Is this entity enabled?
-        *
-        * @return boolean
-        */
-       public function isEnabled() {
-               if ($this->enabled == 'yes') {
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Delete this entity.
-        */
-       public function delete() {
-               return delete_entity($this->get('guid'));
-       }
-
-       // LOCATABLE INTERFACE /////////////////////////////////////////////////////////////
-
-       /** Interface to set the location */
-       public function setLocation($location) {
-               $location = sanitise_string($location);
-
-               $this->location = $location;
-
-               return true;
-       }
-
-       /**
-        * Set latitude and longitude tags for a given entity.
-        *
-        * @param float $lat
-        * @param float $long
-        */
-       public function setLatLong($lat, $long) {
-               $lat = sanitise_string($lat);
-               $long = sanitise_string($long);
-
-               $this->set('geo:lat', $lat);
-               $this->set('geo:long', $long);
-
-               return true;
-       }
-
-       /**
-        * Get the contents of the ->geo:lat field.
-        *
-        */
-       public function getLatitude() {
-               return $this->get('geo:lat');
-       }
-
-       /**
-        * Get the contents of the ->geo:lat field.
-        *
-        */
-       public function getLongitude() {
-               return $this->get('geo:long');
-       }
-
-       /**
-        * Get the ->location metadata.
-        *
-        */
-       public function getLocation() {
-               return $this->get('location');
-       }
-
-       // NOTABLE INTERFACE ///////////////////////////////////////////////////////////////
-
-       /**
-        * Calendar functionality.
-        * This function sets the time of an object on a calendar listing.
-        *
-        * @param int $hour If ommitted, now is assumed.
-        * @param int $minute If ommitted, now is assumed.
-        * @param int $second If ommitted, now is assumed.
-        * @param int $day If ommitted, now is assumed.
-        * @param int $month If ommitted, now is assumed.
-        * @param int $year If ommitted, now is assumed.
-        * @param int $duration Duration of event, remainder of the day is assumed.
-        */
-       public function setCalendarTimeAndDuration($hour = NULL, $minute = NULL, $second = NULL, $day = NULL, $month = NULL, $year = NULL, $duration = NULL) {
-               $start = mktime($hour, $minute, $second, $month, $day, $year);
-               $end = $start + abs($duration);
-               if (!$duration) {
-                       $end = get_day_end($day,$month,$year);
-               }
-
-               $this->calendar_start = $start;
-               $this->calendar_end = $end;
-
-               return true;
-       }
-
-       /**
-        * Return the start timestamp.
-        */
-       public function getCalendarStartTime() {
-               return (int)$this->calendar_start;
-       }
-
-       /**
-        * Return the end timestamp.
-        */
-       public function getCalendarEndTime() {
-               return (int)$this->calendar_end;
-       }
-
-       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an array of fields which can be exported.
-        */
-       public function getExportableValues() {
-               return array(
-                       'guid',
-                       'type',
-                       'subtype',
-                       'time_created',
-                       'time_updated',
-                       'container_guid',
-                       'owner_guid',
-                       'site_guid'
-               );
-       }
-
-       /**
-        * Export this class into an array of ODD Elements containing all necessary fields.
-        * Override if you wish to return more information than can be found in $this->attributes (shouldn't happen)
-        */
-       public function export() {
-               $tmp = array();
-
-               // Generate uuid
-               $uuid = guid_to_uuid($this->getGUID());
-
-               // Create entity
-               $odd = new ODDEntity(
-                       $uuid,
-                       $this->attributes['type'],
-                       get_subtype_from_id($this->attributes['subtype'])
-               );
-
-               $tmp[] = $odd;
-
-               $exportable_values = $this->getExportableValues();
-
-               // Now add its attributes
-               foreach ($this->attributes as $k => $v) {
-                       $meta = NULL;
-
-                       if (in_array( $k, $exportable_values)) {
-                               switch ($k) {
-                                       case 'guid' :                   // Dont use guid in OpenDD
-                                       case 'type' :                   // Type and subtype already taken care of
-                                       case 'subtype' :
-                                       break;
-
-                                       case 'time_created' :   // Created = published
-                                               $odd->setAttribute('published', date("r", $v));
-                                       break;
-
-                                       case 'site_guid' : // Container
-                                               $k = 'site_uuid';
-                                               $v = guid_to_uuid($v);
-                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
-                                       break;
-
-                                       case 'container_guid' : // Container
-                                               $k = 'container_uuid';
-                                               $v = guid_to_uuid($v);
-                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
-                                       break;
-
-                                       case 'owner_guid' :                     // Convert owner guid to uuid, this will be stored in metadata
-                                               $k = 'owner_uuid';
-                                               $v = guid_to_uuid($v);
-                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
-                                       break;
-
-                                       default :
-                                               $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
-                               }
-
-                               // set the time of any metadata created
-                               if ($meta) {
-                                       $meta->setAttribute('published', date("r",$this->time_created));
-                                       $tmp[] = $meta;
-                               }
-                       }
-               }
-
-               // Now we do something a bit special.
-               /*
-                * This provides a rendered view of the entity to foreign sites.
-                */
-
-               elgg_set_viewtype('default');
-               $view = elgg_view_entity($this, true);
-               elgg_set_viewtype();
-
-               $tmp[] = new ODDMetaData($uuid . "volatile/renderedentity/", $uuid, 'renderedentity', $view , 'volatile');
-
-               return $tmp;
-       }
-
-       // IMPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Import data from an parsed xml data array.
-        *
-        * @param array $data
-        * @param int $version
-        */
-       public function import(ODD $data) {
-               if (!($data instanceof ODDEntity)) {
-                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass'));
-               }
-
-               // Set type and subtype
-               $this->attributes['type'] = $data->getAttribute('class');
-               $this->attributes['subtype'] = $data->getAttribute('subclass');
-
-               // Set owner
-               $this->attributes['owner_guid'] = get_loggedin_userid(); // Import as belonging to importer.
-
-               // Set time
-               $this->attributes['time_created'] = strtotime($data->getAttribute('published'));
-               $this->attributes['time_updated'] = time();
-
-               return true;
-       }
-
-       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an identification for the object for storage in the system log.
-        * This id must be an integer.
-        *
-        * @return int
-        */
-       public function getSystemLogID() {
-               return $this->getGUID();
-       }
-
-       /**
-        * Return the class name of the object.
-        */
-       public function getClassName() {
-               return get_class($this);
-       }
-
-       /**
-        * For a given ID, return the object associated with it.
-        * This is used by the river functionality primarily.
-        * This is useful for checking access permissions etc on objects.
-        */
-       public function getObjectFromID($id) {
-               return get_entity($id);
-       }
-
-       /**
-        * Return the GUID of the owner of this object.
-        */
-       public function getObjectOwnerGUID() {
-               return $this->owner_guid;
-       }
-
-       /**
-        * Returns tags for this entity.
-        *
-        * @param array $tag_names Optionally restrict by tag metadata names.
-        * @return array
-        */
-       public function getTags($tag_names = NULL) {
-               global $CONFIG;
-
-               if ($tag_names && !is_array($tag_names)) {
-                       $tag_names = array($tag_names);
-               }
-
-               $valid_tags = elgg_get_registered_tag_metadata_names();
-               $entity_tags = array();
-
-               foreach ($valid_tags as $tag_name) {
-                       if (is_array($tag_names) && !in_array($tag_name, $tag_names)) {
-                               continue;
-                       }
-
-                       if ($tags = $this->$tag_name) {
-                               // if a single tag, metadata returns a string.
-                               // if multiple tags, metadata returns an array.
-                               if (is_array($tags)) {
-                                       $entity_tags = array_merge($entity_tags, $tags);
-                               } else {
-                                       $entity_tags[] = $tags;
-                               }
-                       }
-               }
-
-               return $entity_tags;
-       }
-
-       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////
-       /*
-        * This lets an entity's attributes be displayed using foreach as a normal array.
-        * Example: http://www.sitepoint.com/print/php5-standard-library
-        */
-
-       private $valid = FALSE;
-
-       function rewind() {
-               $this->valid = (FALSE !== reset($this->attributes));
-       }
-
-       function current() {
-               return current($this->attributes);
-       }
-
-       function key() {
-               return key($this->attributes);
-       }
-
-       function next() {
-               $this->valid = (FALSE !== next($this->attributes));
-       }
-
-       function valid() {
-               return $this->valid;
-       }
-
-       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
-       /*
-        * This lets an entity's attributes be accessed like an associative array.
-        * Example: http://www.sitepoint.com/print/php5-standard-library
-        */
-
-       function offsetSet($key, $value) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       $this->attributes[$key] = $value;
-               }
-       }
-
-       function offsetGet($key) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       return $this->attributes[$key];
-               }
-       }
-
-       function offsetUnset($key) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects
-               }
-       }
-
-       function offsetExists($offset) {
-               return array_key_exists($offset, $this->attributes);
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggEntity.php';
 
 /**
  * Initialise the entity cache.
index 1b09016b01738ca69730dfbd8385d857bcc4b5a3..9fbd62a4d1d4729fbb0d89006d36cfe9915ac7cf 100644 (file)
@@ -8,59 +8,10 @@
  * @link http://elgg.org/
  */
 
-/**
- * Define an interface for all ODD exportable objects.
- *
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd
- */
-interface Exportable {
-       /**
-        * This must take the contents of the object and convert it to exportable ODD
-        * @return object or array of objects.
-        */
-       public function export();
-
-       /**
-        * Return a list of all fields that can be exported.
-        * This should be used as the basis for the values returned by export()
-        */
-       public function getExportableValues();
-}
-
-/**
- * Define an interface for all ODD importable objects.
- * @author Curverider Ltd
- */
-interface Importable {
-       /**
-        * Accepts an array of data to import, this data is parsed from the XML produced by export.
-        * The function should return the constructed object data, or NULL.
-        *
-        * @param ODD $data
-        * @return bool
-        * @throws ImportException if there was a critical error importing data.
-        */
-       public function import(ODD $data);
-}
-
-/**
- * Export exception
- *
- * @package Elgg
- * @subpackage Exceptions
- *
- */
-class ExportException extends DataFormatException {}
-
-/**
- * Import exception
- *
- * @package Elgg
- * @subpackage Exceptions
- */
-class ImportException extends DataFormatException {}
+require_once dirname(dirname(__FILE__)).'/classes/Exportable.php';
+require_once dirname(dirname(__FILE__)).'/classes/Importable.php';
+require_once dirname(dirname(__FILE__)).'/classes/ExportException.php';
+require_once dirname(dirname(__FILE__)).'/classes/ImportException.php';
 
 /**
  * Get a UUID from a given object.
index 7b54a784223b7c6be9f0497434e55b02eb6a1708..e222c29268a33ad04e96ffb4fe5f70ade5efad7c 100644 (file)
@@ -9,256 +9,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * ElggExtender
- *
- * @author Curverider Ltd
- * @package Elgg
- * @subpackage Core
- */
-abstract class ElggExtender implements
-       Exportable,
-       Loggable,       // Can events related to this object class be logged
-       Iterator,       // Override foreach behaviour
-       ArrayAccess // Override for array access
-{
-       /**
-        * This contains the site's main properties (id, etc)
-        * @var array
-        */
-       protected $attributes;
-
-       /**
-        * Get an attribute
-        *
-        * @param string $name
-        * @return mixed
-        */
-       protected function get($name) {
-               if (isset($this->attributes[$name])) {
-                       // Sanitise value if necessary
-                       if ($name=='value') {
-                               switch ($this->attributes['value_type']) {
-                                       case 'integer' :
-                                               return (int)$this->attributes['value'];
-
-                                       //case 'tag' :
-                                       //case 'file' :
-                                       case 'text' :
-                                               return ($this->attributes['value']);
-
-                                       default :
-                                               throw new InstallationException(sprintf(elgg_echo('InstallationException:TypeNotSupported'), $this->attributes['value_type']));
-                               }
-                       }
-
-                       return $this->attributes[$name];
-               }
-               return null;
-       }
-
-       /**
-        * Set an attribute
-        *
-        * @param string $name
-        * @param mixed $value
-        * @param string $value_type
-        * @return boolean
-        */
-       protected function set($name, $value, $value_type = "") {
-               $this->attributes[$name] = $value;
-               if ($name == 'value') {
-                       $this->attributes['value_type'] = detect_extender_valuetype($value, $value_type);
-               }
-
-               return true;
-       }
-
-       /**
-        * Return the owner of this annotation.
-        *
-        * @return mixed
-        */
-       public function getOwner() {
-               return $this->owner_guid;
-       }
-
-       /**
-        * Return the owner entity
-        *
-        * @return mixed
-        * @since 1.7.0
-        */
-       public function getOwnerEntity() {
-               return get_user($this->owner_guid);
-       }
-
-       /**
-        * Returns the entity this is attached to
-        *
-        * @return ElggEntity The enttiy
-        */
-       public function getEntity() {
-               return get_entity($this->entity_guid);
-       }
-
-       /**
-        * Save this data to the appropriate database table.
-        */
-       abstract public function save();
-
-       /**
-        * Delete this data.
-        */
-       abstract public function delete();
-
-       /**
-        * Determines whether or not the specified user can edit this
-        *
-        * @param int $user_guid The GUID of the user (defaults to currently logged in user)
-        * @return true|false
-        */
-       public function canEdit($user_guid = 0) {
-               return can_edit_extender($this->id,$this->type,$user_guid);
-       }
-
-       /**
-        * Return a url for this extender.
-        *
-        * @return string
-        */
-       public abstract function getURL();
-
-       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an array of fields which can be exported.
-        */
-       public function getExportableValues() {
-               return array(
-                       'id',
-                       'entity_guid',
-                       'name',
-                       'value',
-                       'value_type',
-                       'owner_guid',
-                       'type',
-               );
-       }
-
-       /**
-        * Export this object
-        *
-        * @return array
-        */
-       public function export() {
-               $uuid = get_uuid_from_object($this);
-
-               $meta = new ODDMetadata($uuid, guid_to_uuid($this->entity_guid), $this->attributes['name'], $this->attributes['value'], $this->attributes['type'], guid_to_uuid($this->owner_guid));
-               $meta->setAttribute('published', date("r", $this->time_created));
-
-               return $meta;
-       }
-
-       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an identification for the object for storage in the system log.
-        * This id must be an integer.
-        *
-        * @return int
-        */
-       public function getSystemLogID() {
-               return $this->id;
-       }
-
-       /**
-        * Return the class name of the object.
-        */
-       public function getClassName() {
-               return get_class($this);
-       }
-
-       /**
-        * Return the GUID of the owner of this object.
-        */
-       public function getObjectOwnerGUID() {
-               return $this->owner_guid;
-       }
-
-       /**
-        * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc
-        */
-       public function getType() {
-               return $this->type;
-       }
-
-       /**
-        * Return a subtype. For metadata & annotations this is the 'name' and
-        * for relationship this is the relationship type.
-        */
-       public function getSubtype() {
-               return $this->name;
-       }
-
-
-       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////
-       /*
-        * This lets an entity's attributes be displayed using foreach as a normal array.
-        * Example: http://www.sitepoint.com/print/php5-standard-library
-        */
-
-       private $valid = FALSE;
-
-       function rewind() {
-               $this->valid = (FALSE !== reset($this->attributes));
-       }
-
-       function current() {
-               return current($this->attributes);
-       }
-
-       function key() {
-               return key($this->attributes);
-       }
-
-       function next() {
-               $this->valid = (FALSE !== next($this->attributes));
-       }
-
-       function valid() {
-               return $this->valid;
-       }
-
-       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
-       /*
-        * This lets an entity's attributes be accessed like an associative array.
-        * Example: http://www.sitepoint.com/print/php5-standard-library
-        */
-
-       function offsetSet($key, $value) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       $this->attributes[$key] = $value;
-               }
-       }
-
-       function offsetGet($key) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       return $this->attributes[$key];
-               }
-       }
-
-       function offsetUnset($key) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       // Full unsetting is dangerious for our objects
-                       $this->attributes[$key] = "";
-               }
-       }
-
-       function offsetExists($offset) {
-               return array_key_exists($offset, $this->attributes);
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggExtender.php';
 
 /**
  * Detect the value_type for a given value.
index 31fc9ab0d89d2348d8d30bd135536cc29ac612c5..74a8b0315aa38d9adf99127ba259ae8d7fafd38a 100644 (file)
 
 include_once("objects.php");
 
-/**
- * @class ElggFilestore
- * This class defines the interface for all elgg data repositories.
- * @author Curverider Ltd
- */
-abstract class ElggFilestore {
-       /**
-        * Attempt to open the file $file for storage or writing.
-        *
-        * @param ElggFile $file
-        * @param string $mode "read", "write", "append"
-        * @return mixed A handle to the opened file or false on error.
-        */
-       abstract public function open(ElggFile $file, $mode);
-
-       /**
-        * Write data to a given file handle.
-        *
-        * @param mixed $f The file handle - exactly what this is depends on the file system
-        * @param string $data The binary string of data to write
-        * @return int Number of bytes written.
-        */
-       abstract public function write($f, $data);
-
-       /**
-        * Read data from a filestore.
-        *
-        * @param mixed $f The file handle
-        * @param int $length Length in bytes to read.
-        * @param int $offset The optional offset.
-        * @return mixed String of data or false on error.
-        */
-       abstract public function read($f, $length, $offset = 0);
-
-       /**
-        * Seek a given position within a file handle.
-        *
-        * @param mixed $f The file handle.
-        * @param int $position The position.
-        */
-       abstract public function seek($f, $position);
-
-       /**
-        * Return a whether the end of a file has been reached.
-        *
-        * @param mixed $f The file handle.
-        * @return boolean
-        */
-       abstract public function eof($f);
-
-       /**
-        * Return the current position in an open file.
-        *
-        * @param mixed $f The file handle.
-        * @return int
-        */
-       abstract public function tell($f);
-
-       /**
-        * Close a given file handle.
-        *
-        * @param mixed $f
-        */
-       abstract public function close($f);
-
-       /**
-        * Delete the file associated with a given file handle.
-        *
-        * @param ElggFile $file
-        */
-       abstract public function delete(ElggFile $file);
-
-       /**
-        * Return the size in bytes for a given file.
-        *
-        * @param ElggFile $file
-        */
-       abstract public function getFileSize(ElggFile $file);
-
-       /**
-        * Return the filename of a given file as stored on the filestore.
-        *
-        * @param ElggFile $file
-        */
-       abstract public function getFilenameOnFilestore(ElggFile $file);
-
-       /**
-        * Get the filestore's creation parameters as an associative array.
-        * Used for serialisation and for storing the creation details along side a file object.
-        *
-        * @return array
-        */
-       abstract public function getParameters();
-
-       /**
-        * Set the parameters from the associative array produced by $this->getParameters().
-        */
-       abstract public function setParameters(array $parameters);
-
-       /**
-        * Get the contents of the whole file.
-        *
-        * @param mixed $file The file handle.
-        * @return mixed The file contents.
-        */
-       abstract public function grabFile(ElggFile $file);
-
-       /**
-        * Return whether a file physically exists or not.
-        *
-        * @param ElggFile $file
-        */
-       abstract public function exists(ElggFile $file);
-}
-
-/**
- * @class ElggDiskFilestore
- * This class uses disk storage to save data.
- * @author Curverider Ltd
- */
-class ElggDiskFilestore extends ElggFilestore {
-       /**
-        * Directory root.
-        */
-       private $dir_root;
-
-       /**
-        * Default depth of file directory matrix
-        */
-       private $matrix_depth = 5;
-
-       /**
-        * Construct a disk filestore using the given directory root.
-        *
-        * @param string $directory_root Root directory, must end in "/"
-        */
-       public function __construct($directory_root = "") {
-               global $CONFIG;
-
-               if ($directory_root) {
-                       $this->dir_root = $directory_root;
-               } else {
-                       $this->dir_root = $CONFIG->dataroot;
-               }
-       }
-
-       public function open(ElggFile $file, $mode) {
-               $fullname = $this->getFilenameOnFilestore($file);
-
-               // Split into path and name
-               $ls = strrpos($fullname,"/");
-               if ($ls===false) {
-                       $ls = 0;
-               }
-
-               $path = substr($fullname, 0, $ls);
-               $name = substr($fullname, $ls);
-
-               // Try and create the directory
-               try {
-                       $this->make_directory_root($path);
-               } catch (Exception $e) {
-
-               }
-
-               if (($mode!='write') && (!file_exists($fullname))) {
-                       return false;
-               }
-
-               switch ($mode) {
-                       case "read" :
-                               $mode = "rb";
-                               break;
-                       case "write" :
-                               $mode = "w+b";
-                               break;
-                       case "append" :
-                               $mode = "a+b";
-                               break;
-                       default:
-                               throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode));
-               }
-
-               return fopen($fullname, $mode);
-
-       }
-
-       public function write($f, $data) {
-               return fwrite($f, $data);
-       }
-
-       public function read($f, $length, $offset = 0) {
-               if ($offset) {
-                       $this->seek($f, $offset);
-               }
-
-               return fread($f, $length);
-       }
-
-       public function close($f) {
-               return fclose($f);
-       }
-
-       public function delete(ElggFile $file) {
-               $filename = $this->getFilenameOnFilestore($file);
-               if (file_exists($filename)) {
-                       return unlink($filename);
-               } else {
-                       return true;
-               }
-       }
-
-       public function seek($f, $position) {
-               return fseek($f, $position);
-       }
-
-       public function tell($f) {
-               return ftell($f);
-       }
-
-       public function eof($f) {
-               return feof($f);
-       }
-
-       public function getFileSize(ElggFile $file) {
-               return filesize($this->getFilenameOnFilestore($file));
-       }
-
-       public function getFilenameOnFilestore(ElggFile $file) {
-               $owner = $file->getOwnerEntity();
-               if (!$owner) {
-                       $owner = get_loggedin_user();
-               }
-
-               if ((!$owner) || (!$owner->username)) {
-                       throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:MissingOwner'), $file->getFilename(), $file->guid));
-               }
-
-               return $this->dir_root . $this->make_file_matrix($owner->guid) . $file->getFilename();
-       }
-
-       public function grabFile(ElggFile $file) {
-               return file_get_contents($file->getFilenameOnFilestore());
-       }
-
-       public function exists(ElggFile $file) {
-               return file_exists($this->getFilenameOnFilestore($file));
-       }
-
-       public function getSize($prefix,$container_guid) {
-               if ($container_guid) {
-                       return get_dir_size($this->dir_root.$this->make_file_matrix($container_guid).$prefix);
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Make the directory root.
-        *
-        * @param string $dirroot
-        */
-       protected function make_directory_root($dirroot) {
-               if (!file_exists($dirroot)) {
-                       if (!@mkdir($dirroot, 0700, true)) {
-                               throw new IOException(sprintf(elgg_echo('IOException:CouldNotMake'), $dirroot));
-                       }
-               }
-
-               return true;
-       }
-
-       /**
-        * Multibyte string tokeniser.
-        *
-        * Splits a string into an array. Will fail safely if mbstring is not installed (although this may still
-        * not handle .
-        *
-        * @param string $string String
-        * @param string $charset The charset, defaults to UTF8
-        * @return array
-        */
-       private function mb_str_split($string, $charset = 'UTF8') {
-               if (is_callable('mb_substr')) {
-                       $length = mb_strlen($string);
-                       $array = array();
-
-                       while ($length) {
-                               $array[] = mb_substr($string, 0, 1, $charset);
-                               $string = mb_substr($string, 1, $length, $charset);
-
-                               $length = mb_strlen($string);
-                       }
-
-                       return $array;
-               } else {
-                       return str_split($string);
-               }
-
-               return false;
-       }
-
-       /**
-        * Construct the filename matrix.
-        *
-        * @param int | string $identifier
-        * @return str
-        */
-       protected function make_file_matrix($identifier) {
-               if (is_numeric($identifier)) {
-                       return $this->user_file_matrix($identifier);
-               }
-
-               return $this->deprecated_file_matrix($identifier);
-       }
-
-       /**
-        * Construct the filename matrix with user info
-        *
-        * This method will generate a matrix using the entity's creation time and
-        * unique guid. This is intended only to determine a user's data directory.
-        *
-        * @param int $guid
-        * @return str
-        */
-       protected function user_file_matrix($guid) {
-               // lookup the entity
-               $user = get_entity($guid);
-               if ($user->type != 'user')
-               {
-                       // only to be used for user directories
-                       return FALSE;
-               }
-
-               if (!$user->time_created) {
-                       // fall back to deprecated method
-                       return $this->deprecated_file_matrix($user->username);
-               }
-
-               $time_created = date('Y/m/d', $user->time_created);
-               return "$time_created/$user->guid/";
-       }
-
-       /**
-        * Construct the filename matrix using a string
-        *
-        * Particularly, this is used with a username to generate the file storage
-        * location.
-        *
-        * @deprecated for user directories: use user_file_matrix() instead.
-        *
-        * @param str $filename
-        * @return str
-        */
-       protected function deprecated_file_matrix($filename) {
-               // throw a warning for using deprecated method
-               $error  = 'Deprecated use of ElggDiskFilestore::make_file_matrix. ';
-               $error .= 'Username passed instead of guid.';
-               elgg_log($error, WARNING);
-
-               $user = new ElggUser($filename);
-               return $this->user_file_matrix($user->guid);
-       }
-
-       public function getParameters() {
-               return array("dir_root" => $this->dir_root);
-       }
-
-       public function setParameters(array $parameters) {
-               if (isset($parameters['dir_root'])) {
-                       $this->dir_root = $parameters['dir_root'];
-                       return true;
-               }
-
-               return false;
-       }
-}
-
-/**
- * @class ElggFile
- * This class represents a physical file.
- *
- * Usage:
- *             Create a new ElggFile object and specify a filename, and optionally a FileStore (if one isn't specified
- *             then the default is assumed.
- *
- *             Open the file using the appropriate mode, and you will be able to read and write to the file.
- *
- *             Optionally, you can also call the file's save() method, this will turn the file into an entity in the
- *             system and permit you to do things like attach tags to the file etc. This is not done automatically since
- *             there are many occasions where you may want access to file data on datastores using the ElggFile interface
- *             but do not want to create an Entity reference to it in the system (temporary files for example).
- *
- * @author Curverider Ltd
- */
-class ElggFile extends ElggObject {
-       /** Filestore */
-       private $filestore;
-
-       /** File handle used to identify this file in a filestore. Created by open. */
-       private $handle;
-
-       protected function initialise_attributes() {
-               parent::initialise_attributes();
-
-               $this->attributes['subtype'] = "file";
-       }
-
-       public function __construct($guid = null) {
-               parent::__construct($guid);
-
-               // Set default filestore
-               $this->filestore = $this->getFilestore();
-       }
-
-       /**
-        * Set the filename of this file.
-        *
-        * @param string $name The filename.
-        */
-       public function setFilename($name) {
-               $this->filename = $name;
-       }
-
-       /**
-        * Return the filename.
-        */
-       public function getFilename() {
-               return $this->filename;
-       }
-
-       /**
-        * Return the filename of this file as it is/will be stored on the filestore, which may be different
-        * to the filename.
-        */
-       public function getFilenameOnFilestore() {
-               return $this->filestore->getFilenameOnFilestore($this);
-       }
-
-       /*
-        * Return the size of the filestore associated with this file
-        *
-        */
-       public function getFilestoreSize($prefix='',$container_guid=0) {
-               if (!$container_guid) {
-                       $container_guid = $this->container_guid;
-               }
-               $fs = $this->getFilestore();
-               return $fs->getSize($prefix,$container_guid);
-       }
-
-       /**
-        * Get the mime type of the file.
-        */
-       public function getMimeType() {
-               if ($this->mimetype) {
-                       return $this->mimetype;
-               }
-
-               // @todo Guess mimetype if not here
-       }
-
-       /**
-        * Set the mime type of the file.
-        *
-        * @param $mimetype The mimetype
-        */
-       public function setMimeType($mimetype) {
-               return $this->mimetype = $mimetype;
-       }
-
-       /**
-        * Set the optional file description.
-        *
-        * @param string $description The description.
-        */
-       public function setDescription($description) {
-               $this->description = $description;
-       }
-
-       /**
-        * Open the file with the given mode
-        *
-        * @param string $mode Either read/write/append
-        */
-       public function open($mode) {
-               if (!$this->getFilename()) {
-                       throw new IOException(elgg_echo('IOException:MissingFileName'));
-               }
-
-               // See if file has already been saved
-               // seek on datastore, parameters and name?
-
-               // Sanity check
-               if (
-                       ($mode!="read") &&
-                       ($mode!="write") &&
-                       ($mode!="append")
-               ) {
-                       throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode));
-               }
-
-               // Get the filestore
-               $fs = $this->getFilestore();
-
-               // Ensure that we save the file details to object store
-               //$this->save();
-
-               // Open the file handle
-               $this->handle = $fs->open($this, $mode);
-
-               return $this->handle;
-       }
-
-       /**
-        * Write some data.
-        *
-        * @param string $data The data
-        */
-       public function write($data) {
-               $fs = $this->getFilestore();
-
-               return $fs->write($this->handle, $data);
-       }
-
-       /**
-        * Read some data.
-        *
-        * @param int $length Amount to read.
-        * @param int $offset The offset to start from.
-        */
-       public function read($length, $offset = 0) {
-               $fs = $this->getFilestore();
-
-               return $fs->read($this->handle, $length, $offset);
-       }
-
-       /**
-        * Gets the full contents of this file.
-        *
-        * @return mixed The file contents.
-        */
-       public function grabFile() {
-               $fs = $this->getFilestore();
-               return $fs->grabFile($this);
-       }
-
-       /**
-        * Close the file and commit changes
-        */
-       public function close() {
-               $fs = $this->getFilestore();
-
-               if ($fs->close($this->handle)) {
-                       $this->handle = NULL;
-
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Delete this file.
-        */
-       public function delete() {
-               $fs = $this->getFilestore();
-               if ($fs->delete($this)) {
-                       return parent::delete();
-               }
-       }
-
-       /**
-        * Seek a position in the file.
-        *
-        * @param int $position
-        */
-       public function seek($position) {
-               $fs = $this->getFilestore();
-
-               return $fs->seek($this->handle, $position);
-       }
-
-       /**
-        * Return the current position of the file.
-        *
-        * @return int The file position
-        */
-       public function tell() {
-               $fs = $this->getFilestore();
-
-               return $fs->tell($this->handle);
-       }
-
-       /**
-        * Return the size of the file in bytes.
-        */
-       public function size() {
-               return $this->filestore->getFileSize($this);
-       }
-
-       /**
-        * Return a boolean value whether the file handle is at the end of the file
-        */
-       public function eof() {
-               $fs = $this->getFilestore();
-
-               return $fs->eof($this->handle);
-       }
-
-       public function exists() {
-               $fs = $this->getFilestore();
-
-               return $fs->exists($this);
-       }
-
-       /**
-        * Set a filestore.
-        *
-        * @param ElggFilestore $filestore The file store.
-        */
-       public function setFilestore(ElggFilestore $filestore) {
-               $this->filestore = $filestore;
-       }
-
-       /**
-        * Return a filestore suitable for saving this file.
-        * This filestore is either a pre-registered filestore, a filestore loaded from metatags saved
-        * along side this file, or the system default.
-        */
-       protected function getFilestore() {
-               // Short circuit if already set.
-               if ($this->filestore) {
-                       return $this->filestore;
-               }
-
-               // If filestore meta set then retrieve filestore
-               // @todo Better way of doing this?
-               $metas = get_metadata_for_entity($this->guid);
-               $parameters = array();
-               if (is_array($metas)) {
-                       foreach ($metas as $meta) {
-                               if (strpos($meta->name, "filestore::")!==false) {
-                                       // Filestore parameter tag
-                                       $comp = explode("::", $meta->name);
-                                       $name = $comp[1];
-
-                                       $parameters[$name] = $meta->value;
-                               }
-                       }
-               }
-
-               if (isset($parameters['filestore'])) {
-                       if (!class_exists($parameters['filestore'])) {
-                               $msg = sprintf(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile'),
-                                                               $parameters['filestore'],
-                                                               $this->guid);
-                               throw new ClassNotFoundException($msg);
-                       }
-
-                       // Create new filestore object
-                       $this->filestore = new $parameters['filestore']();
-
-                       $this->filestore->setParameters($parameters);
-               } else {
-                       // @todo - should we log error if filestore not set
-               }
-
-
-               // if still nothing then set filestore to default
-               if (!$this->filestore) {
-                       $this->filestore = get_default_filestore();
-               }
-
-               return $this->filestore;
-       }
-
-       public function save() {
-               if (!parent::save()) {
-                       return false;
-               }
-
-               // Save datastore metadata
-               $params = $this->filestore->getParameters();
-               foreach ($params as $k => $v) {
-                       $this->setMetaData("filestore::$k", $v);
-               }
-
-               // Now make a note of the filestore class
-               $this->setMetaData("filestore::filestore", get_class($this->filestore));
-
-               return true;
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggFilestore.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggDiskFilestore.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggFile.php';
 
 /**
  * Get the size of the specified directory.
index ab6c9112d5602bf67ecc3b09dfb388d008efe4bb..22badc4b9c9d87125de72c1c63257daecd7bbc92 100644 (file)
  * @link http://elgg.org/
  */
 
-/**
- * @class ElggGroup Class representing a container for other elgg entities.
- * @author Curverider Ltd
- */
-class ElggGroup extends ElggEntity
-       implements Friendable {
-
-       protected function initialise_attributes() {
-               parent::initialise_attributes();
-
-               $this->attributes['type'] = "group";
-               $this->attributes['name'] = "";
-               $this->attributes['description'] = "";
-               $this->attributes['tables_split'] = 2;
-       }
-
-       /**
-        * Construct a new user entity, optionally from a given id value.
-        *
-        * @param mixed $guid If an int, load that GUID.
-        *      If a db row then will attempt to load the rest of the data.
-        * @throws Exception if there was a problem creating the user.
-        */
-       function __construct($guid = null) {
-               $this->initialise_attributes();
-
-               if (!empty($guid)) {
-                       // Is $guid is a DB row - either a entity row, or a user table row.
-                       if ($guid instanceof stdClass) {
-                               // Load the rest
-                               if (!$this->load($guid->guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));
-                               }
-                       }
-                       // Is $guid is an ElggGroup? Use a copy constructor
-                       else if ($guid instanceof ElggGroup) {
-                               elgg_deprecated_notice('This type of usage of the ElggGroup constructor was deprecated. Please use the clone method.', 1.7);
-
-                               foreach ($guid->attributes as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                       }
-                       // Is this is an ElggEntity but not an ElggGroup = ERROR!
-                       else if ($guid instanceof ElggEntity) {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggGroup'));
-                       }
-                       // We assume if we have got this far, $guid is an int
-                       else if (is_numeric($guid)) {
-                               if (!$this->load($guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
-                               }
-                       }
-
-                       else {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
-                       }
-               }
-       }
-
-       /**
-        * Add an ElggObject to this group.
-        *
-        * @param ElggObject $object The object.
-        * @return bool
-        */
-       public function addObjectToGroup(ElggObject $object) {
-               return add_object_to_group($this->getGUID(), $object->getGUID());
-       }
-
-       /**
-        * Remove an object from the containing group.
-        *
-        * @param int $guid The guid of the object.
-        * @return bool
-        */
-       public function removeObjectFromGroup($guid) {
-               return remove_object_from_group($this->getGUID(), $guid);
-       }
-
-       public function get($name) {
-               if ($name == 'username') {
-                       return 'group:' . $this->getGUID();
-               }
-               return parent::get($name);
-       }
-
-/**
- * Start friendable compatibility block:
- *
- *     public function addFriend($friend_guid);
-       public function removeFriend($friend_guid);
-       public function isFriend();
-       public function isFriendsWith($user_guid);
-       public function isFriendOf($user_guid);
-       public function getFriends($subtype = "", $limit = 10, $offset = 0);
-       public function getFriendsOf($subtype = "", $limit = 10, $offset = 0);
-       public function getObjects($subtype="", $limit = 10, $offset = 0);
-       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0);
-       public function countObjects($subtype = "");
- */
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function addFriend($friend_guid) {
-               return $this->join(get_entity($friend_guid));
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function removeFriend($friend_guid) {
-               return $this->leave(get_entity($friend_guid));
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function isFriend() {
-               return $this->isMember();
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function isFriendsWith($user_guid) {
-               return $this->isMember($user_guid);
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function isFriendOf($user_guid) {
-               return $this->isMember($user_guid);
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function getFriends($subtype = "", $limit = 10, $offset = 0) {
-               return get_group_members($this->getGUID(), $limit, $offset);
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function getFriendsOf($subtype = "", $limit = 10, $offset = 0) {
-               return get_group_members($this->getGUID(), $limit, $offset);
-       }
-
-       /**
-        * Get objects contained in this group.
-        *
-        * @param string $subtype
-        * @param int $limit
-        * @param int $offset
-        * @return mixed
-        */
-       public function getObjects($subtype="", $limit = 10, $offset = 0) {
-               return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false);
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) {
-               return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false);
-       }
-
-       /**
-        * For compatibility with Friendable
-        */
-       public function countObjects($subtype = "") {
-               return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", 10, 0, true);
-       }
-
-/**
- * End friendable compatibility block
- */
-
-       /**
-        * Get a list of group members.
-        *
-        * @param int $limit
-        * @param int $offset
-        * @return mixed
-        */
-       public function getMembers($limit = 10, $offset = 0, $count = false) {
-               return get_group_members($this->getGUID(), $limit, $offset, 0 , $count);
-       }
-
-       /**
-        * Returns whether the current group is public membership or not.
-        * @return bool
-        */
-       public function isPublicMembership() {
-               if ($this->membership == ACCESS_PUBLIC) {
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Return whether a given user is a member of this group or not.
-        *
-        * @param ElggUser $user The user
-        * @return bool
-        */
-       public function isMember($user = 0) {
-               if (!($user instanceof ElggUser)) {
-                       $user = get_loggedin_user();
-               }
-               if (!($user instanceof ElggUser)) {
-                       return false;
-               }
-               return is_group_member($this->getGUID(), $user->getGUID());
-       }
-
-       /**
-        * Join an elgg user to this group.
-        *
-        * @param ElggUser $user
-        * @return bool
-        */
-       public function join(ElggUser $user) {
-               return join_group($this->getGUID(), $user->getGUID());
-       }
-
-       /**
-        * Remove a user from the group.
-        *
-        * @param ElggUser $user
-        */
-       public function leave(ElggUser $user) {
-               return leave_group($this->getGUID(), $user->getGUID());
-       }
-
-       /**
-        * Override the load function.
-        * This function will ensure that all data is loaded (were possible), so
-        * if only part of the ElggGroup is loaded, it'll load the rest.
-        *
-        * @param int $guid
-        */
-       protected function load($guid) {
-               // Test to see if we have the generic stuff
-               if (!parent::load($guid)) {
-                       return false;
-               }
-
-               // Check the type
-               if ($this->attributes['type']!='group') {
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
-               }
-
-               // Load missing data
-               $row = get_group_entity_as_row($guid);
-               if (($row) && (!$this->isFullyLoaded())) {
-                       // If $row isn't a cached copy then increment the counter
-                       $this->attributes['tables_loaded'] ++;
-               }
-
-               // Now put these into the attributes array as core values
-               $objarray = (array) $row;
-               foreach($objarray as $key => $value) {
-                       $this->attributes[$key] = $value;
-               }
-
-               return true;
-       }
-
-       /**
-        * Override the save function.
-        */
-       public function save() {
-               // Save generic stuff
-               if (!parent::save()) {
-                       return false;
-               }
-
-               // Now save specific stuff
-               return create_group_entity($this->get('guid'), $this->get('name'), $this->get('description'));
-       }
-
-       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an array of fields which can be exported.
-        */
-       public function getExportableValues() {
-               return array_merge(parent::getExportableValues(), array(
-                       'name',
-                       'description',
-               ));
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggGroup.php';
 
 /**
  * Get the group entity.
index 7b96f4a9157e1e21f8a6ea0f79a78e849f6c25f9..a424ece25ee2a4b7ba94d1613f523c81cac8f6fe 100644 (file)
@@ -8,40 +8,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * Define an interface for geo-tagging entities.
- *
- */
-interface Locatable {
-       /** Set a location text */
-       public function setLocation($location);
-
-       /**
-        * Set latitude and longitude tags for a given entity.
-        *
-        * @param float $lat
-        * @param float $long
-        */
-       public function setLatLong($lat, $long);
-
-       /**
-        * Get the contents of the ->geo:lat field.
-        *
-        */
-       public function getLatitude();
-
-       /**
-        * Get the contents of the ->geo:lat field.
-        *
-        */
-       public function getLongitude();
-
-       /**
-        * Get the ->location metadata.
-        *
-        */
-       public function getLocation();
-}
+require_once dirname(dirname(__FILE__)).'/classes/Locatable.php';
 
 /**
  * Encode a location into a latitude and longitude, caching the result.
index 1a428dac5e8322ccb7ac95fe4acb7eb471c3a67b..de1c001b58bd9a20cc05b8c464c282a6753f8478 100644 (file)
  * @link http://elgg.org/
  */
 
-/**
- * Memcache wrapper class.
- * @author Curverider Ltd <info@elgg.com>
- */
-class ElggMemcache extends ElggSharedMemoryCache {
-       /**
-        * Minimum version of memcached needed to run
-        *
-        */
-       private static $MINSERVERVERSION = '1.1.12';
-
-       /**
-        * Memcache object
-        */
-       private $memcache;
-
-       /**
-        * Expiry of saved items (default timeout after a day to prevent anything getting too stale)
-        */
-       private $expires = 86400;
-
-       /**
-        * The version of memcache running
-        */
-       private $version = 0;
-
-       /**
-        * Connect to memcache.
-        *
-        * @param string $cache_id The namespace for this cache to write to - note, namespaces of the same name are shared!
-        */
-       function __construct($namespace = 'default') {
-               global $CONFIG;
-
-               $this->setNamespace($namespace);
-
-               // Do we have memcache?
-               if (!class_exists('Memcache')) {
-                       throw new ConfigurationException(elgg_echo('memcache:notinstalled'));
-               }
-
-               // Create memcache object
-               $this->memcache = new Memcache;
-
-               // Now add servers
-               if (!$CONFIG->memcache_servers) {
-                       throw new ConfigurationException(elgg_echo('memcache:noservers'));
-               }
-
-               if (is_callable($this->memcache, 'addServer')) {
-                       foreach ($CONFIG->memcache_servers as $server) {
-                               if (is_array($server)) {
-                                       $this->memcache->addServer(
-                                               $server[0],
-                                               isset($server[1]) ? $server[1] : 11211,
-                                               isset($server[2]) ? $server[2] : true,
-                                               isset($server[3]) ? $server[3] : null,
-                                               isset($server[4]) ? $server[4] : 1,
-                                               isset($server[5]) ? $server[5] : 15,
-                                               isset($server[6]) ? $server[6] : true
-                                       );
-
-                               } else {
-                                       $this->memcache->addServer($server, 11211);
-                               }
-                       }
-               } else {
-                       elgg_log(elgg_echo('memcache:noaddserver'), 'ERROR');
-
-                       $server = $CONFIG->memcache_servers[0];
-                       if (is_array($server)) {
-                               $this->memcache->connect($server[0], $server[1]);
-                       } else {
-                               $this->memcache->addServer($server, 11211);
-                       }
-               }
-
-               // Get version
-               $this->version = $this->memcache->getversion();
-               if (version_compare($this->version, ElggMemcache::$MINSERVERVERSION, '<')) {
-                       throw new ConfigurationException(sprintf(elgg_echo('memcache:versiontoolow'), ElggMemcache::$MINSERVERVERSION, $this->version));
-               }
-
-               // Set some defaults
-               if (isset($CONFIG->memcache_expires)) {
-                       $this->expires = $CONFIG->memcache_expires;
-               }
-       }
-
-       /**
-        * Set the default expiry.
-        *
-        * @param int $expires The lifetime as a unix timestamp or time from now. Defaults forever.
-        */
-       public function setDefaultExpiry($expires = 0) {
-               $this->expires = $expires;
-       }
-
-       /**
-        * Combine a key with the namespace.
-        * Memcache can only accept <250 char key. If the given key is too long it is shortened.
-        *
-        * @param string $key The key
-        * @return string The new key.
-        */
-       private function make_memcache_key($key) {
-               $prefix = $this->getNamespace() . ":";
-
-               if (strlen($prefix.$key)> 250) {
-                       $key = md5($key);
-               }
-
-               return $prefix.$key;
-       }
-
-       public function save($key, $data) {
-               $key = $this->make_memcache_key($key);
-
-               $result = $this->memcache->set($key, $data, null, $this->expires);
-               if (!$result) {
-                       elgg_log("MEMCACHE: FAILED TO SAVE $key", 'ERROR');
-               }
-
-               return $result;
-       }
-
-       public function load($key, $offset = 0, $limit = null) {
-               $key = $this->make_memcache_key($key);
-
-               $result = $this->memcache->get($key);
-               if (!$result) {
-                       elgg_log("MEMCACHE: FAILED TO LOAD $key", 'ERROR');
-               }
-
-               return $result;
-       }
-
-       public function delete($key) {
-               $key = $this->make_memcache_key($key);
-
-               return $this->memcache->delete($key, 0);
-       }
-
-       public function clear() {
-               // DISABLE clearing for now - you must use delete on a specific key.
-               return true;
-
-               // @todo Namespaces as in #532
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggMemcache.php';
 
 /**
  * Return true if memcache is available and configured.
index dd2e341d482f8513b9f76fb21662df40aca8e187..9ab32912a0656334ed5528e5550112d7ef459f80 100644 (file)
@@ -9,118 +9,9 @@
  * @link http://elgg.org/
  */
 
-/**
- * ElggMetadata
- * This class describes metadata that can be attached to ElggEntities.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-class ElggMetadata extends ElggExtender {
-       /**
-        * Construct a new site object, optionally from a given id value or row.
-        *
-        * @param mixed $id
-        */
-       function __construct($id = null) {
-               $this->attributes = array();
-
-               if (!empty($id)) {
-                       // Create from db row
-                       if ($id instanceof stdClass) {
-                               $metadata = $id;
-                       } else {
-                               $metadata = get_metadata($id);
-                       }
+require_once 'extender.php';
 
-                       if ($metadata) {
-                               $objarray = (array) $metadata;
-                               foreach($objarray as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                               $this->attributes['type'] = "metadata";
-                       }
-               }
-       }
-
-       /**
-        * Class member get overloading
-        *
-        * @param string $name
-        * @return mixed
-        */
-       function __get($name) {
-               return $this->get($name);
-       }
-
-       /**
-        * Class member set overloading
-        *
-        * @param string $name
-        * @param mixed $value
-        * @return mixed
-        */
-       function __set($name, $value) {
-               return $this->set($name, $value);
-       }
-
-       /**
-        * Determines whether or not the user can edit this piece of metadata
-        *
-        * @return true|false Depending on permissions
-        */
-       function canEdit() {
-               if ($entity = get_entity($this->get('entity_guid'))) {
-                       return $entity->canEditMetadata($this);
-               }
-               return false;
-       }
-
-       /**
-        * Save matadata object
-        *
-        * @return int the metadata object id
-        */
-       function save() {
-               if ($this->id > 0) {
-                       return update_metadata($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
-               } else {
-                       $this->id = create_metadata($this->entity_guid, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
-                       if (!$this->id) {
-                               throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));
-                       }
-                       return $this->id;
-               }
-       }
-
-       /**
-        * Delete a given metadata.
-        */
-       function delete() {
-               return delete_metadata($this->id);
-       }
-
-       /**
-        * Get a url for this item of metadata.
-        *
-        * @return string
-        */
-       public function getURL() {
-               return get_metadata_url($this->id);
-       }
-
-       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * For a given ID, return the object associated with it.
-        * This is used by the river functionality primarily.
-        * This is useful for checking access permissions etc on objects.
-        */
-       public function getObjectFromID($id) {
-               return get_metadata($id);
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggMetadata.php';
 
 /**
  * Convert a database row to a new ElggMetadata
index 63376c72dbe6a0a8845cffa171c11a7ae54e2dd1..1c7f1640ccaeaf8e169839a3170ead2432177031 100644 (file)
  * @link http://elgg.org/
  */
 
-/**
- * ElggObject
- * Representation of an "object" in the system.
- *
- * @package Elgg
- * @subpackage Core
- */
-class ElggObject extends ElggEntity {
-       /**
-        * Initialise the attributes array.
-        * This is vital to distinguish between metadata and base parameters.
-        *
-        * Place your base parameters here.
-        */
-       protected function initialise_attributes() {
-               parent::initialise_attributes();
-
-               $this->attributes['type'] = "object";
-               $this->attributes['title'] = "";
-               $this->attributes['description'] = "";
-               $this->attributes['tables_split'] = 2;
-       }
-
-       /**
-        * Construct a new object entity, optionally from a given id value.
-        *
-        * @param mixed $guid If an int, load that GUID.
-        *      If a db row then will attempt to load the rest of the data.
-        * @throws Exception if there was a problem creating the object.
-        */
-       function __construct($guid = null) {
-               $this->initialise_attributes();
-
-               if (!empty($guid)) {
-                       // Is $guid is a DB row - either a entity row, or a object table row.
-                       if ($guid instanceof stdClass) {
-                               // Load the rest
-                               if (!$this->load($guid->guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));
-                               }
-                       }
-
-                       // Is $guid is an ElggObject? Use a copy constructor
-                       else if ($guid instanceof ElggObject) {
-                               elgg_deprecated_notice('This type of usage of the ElggObject constructor was deprecated. Please use the clone method.', 1.7);
-
-                               foreach ($guid->attributes as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                       }
-
-                       // Is this is an ElggEntity but not an ElggObject = ERROR!
-                       else if ($guid instanceof ElggEntity) {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggObject'));
-                       }
-
-                       // We assume if we have got this far, $guid is an int
-                       else if (is_numeric($guid)) {
-                               if (!$this->load($guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
-                               }
-                       }
-
-                       else {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
-                       }
-               }
-       }
-
-       /**
-        * Override the load function.
-        * This function will ensure that all data is loaded (were possible), so
-        * if only part of the ElggObject is loaded, it'll load the rest.
-        *
-        * @param int $guid
-        * @return true|false
-        */
-       protected function load($guid) {
-               // Test to see if we have the generic stuff
-               if (!parent::load($guid)) {
-                       return false;
-               }
-
-               // Check the type
-               if ($this->attributes['type']!='object') {
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
-               }
-
-               // Load missing data
-               $row = get_object_entity_as_row($guid);
-               if (($row) && (!$this->isFullyLoaded())) {
-                       // If $row isn't a cached copy then increment the counter
-                       $this->attributes['tables_loaded'] ++;
-               }
-
-               // Now put these into the attributes array as core values
-               $objarray = (array) $row;
-               foreach($objarray as $key => $value) {
-                       $this->attributes[$key] = $value;
-               }
-
-               return true;
-       }
-
-       /**
-        * Override the save function.
-        * @return true|false
-        */
-       public function save() {
-               // Save generic stuff
-               if (!parent::save()) {
-                       return false;
-               }
-
-               // Now save specific stuff
-               return create_object_entity($this->get('guid'), $this->get('title'), $this->get('description'), $this->get('container_guid'));
-       }
-
-       /**
-        * Get sites that this object is a member of
-        *
-        * @param string $subtype Optionally, the subtype of result we want to limit to
-        * @param int $limit The number of results to return
-        * @param int $offset Any indexing offset
-        */
-       function getSites($subtype="", $limit = 10, $offset = 0) {
-               return get_site_objects($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * Add this object to a particular site
-        *
-        * @param int $site_guid The guid of the site to add it to
-        * @return true|false
-        */
-       function addToSite($site_guid) {
-               return add_site_object($this->getGUID(), $site_guid);
-       }
-
-       /**
-        * Set the container for this object.
-        *
-        * @param int $container_guid The ID of the container.
-        * @return bool
-        */
-       function setContainer($container_guid) {
-               $container_guid = (int)$container_guid;
-
-               return $this->set('container_guid', $container_guid);
-       }
-
-       /**
-        * Return the container GUID of this object.
-        *
-        * @return int
-        */
-       function getContainer() {
-               return $this->get('container_guid');
-       }
-
-       /**
-        * As getContainer(), but returns the whole entity.
-        *
-        * @return mixed ElggGroup object or false.
-        */
-       function getContainerEntity() {
-               $result = get_entity($this->getContainer());
-
-               if (($result) && ($result instanceof ElggGroup)) {
-                       return $result;
-               }
-
-               return false;
-       }
-
-       /**
-        * Get the collections associated with a object.
-        *
-        * @param string $subtype Optionally, the subtype of result we want to limit to
-        * @param int $limit The number of results to return
-        * @param int $offset Any indexing offset
-        * @return unknown
-        */
-       //public function getCollections($subtype="", $limit = 10, $offset = 0) { get_object_collections($this->getGUID(), $subtype, $limit, $offset); }
-
-       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an array of fields which can be exported.
-        */
-       public function getExportableValues() {
-               return array_merge(parent::getExportableValues(), array(
-                       'title',
-                       'description',
-               ));
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggObject.php';
 
 /**
  * Return the object specific details of a object by a row.
index c582e6f771a8cf58cb92757cb6ca498b204185b2..dae6bc9d0fe637ad52fb3ea6abda12756602b555 100644 (file)
 
 include_once("xml.php");
 
-/**
- * @class ODDDocument ODD Document container.
- * This class is used during import and export to construct.
- * @author Curverider Ltd
- */
-class ODDDocument implements Iterator {
-       /**
-        * ODD Version
-        *
-        * @var string
-        */
-       private $ODDSupportedVersion = "1.0";
-
-       /**
-        * Elements of the document.
-        */
-       private $elements;
-
-       /**
-        * Optional wrapper factory.
-        */
-       private $wrapperfactory;
-
-       public function __construct(array $elements = NULL) {
-               if ($elements) {
-                       if (is_array($elements)) {
-                               $this->elements = $elements;
-                       } else {
-                               $this->addElement($elements);
-                       }
-               } else {
-                       $this->elements = array();
-               }
-       }
-
-       /**
-        * Return the version of ODD being used.
-        *
-        * @return string
-        */
-       public function getVersion() {
-               return $this->ODDSupportedVersion;
-       }
-
-       public function getNumElements() {
-               return count($this->elements);
-       }
-
-       public function addElement(ODD $element) {
-               if (!is_array($this->elements)) {
-                       $this->elements = array();
-                       $this->elements[] = $element;
-               }
-       }
-
-       public function addElements(array $elements) {
-               foreach ($elements as $element) {
-                       $this->addElement($element);
-               }
-       }
-
-       public function getElements() {
-               return $this->elements;
-       }
-
-       /**
-        * Set an optional wrapper factory to optionally embed the ODD document in another format.
-        */
-       public function setWrapperFactory(ODDWrapperFactory $factory) {
-               $this->wrapperfactory = $factory;
-       }
-
-       /**
-        * Magic function to generate valid ODD XML for this item.
-        */
-       public function __toString() {
-               $xml = "";
-
-               if ($this->wrapperfactory) {
-                       // A wrapper has been provided
-                       $wrapper = $this->wrapperfactory->getElementWrapper($this); // Get the wrapper for this element
-
-                       $xml = $wrapper->wrap($this); // Wrap this element (and subelements)
-               } else {
-                       // Output begin tag
-                       $generated = date("r");
-                       $xml .= "<odd version=\"{$this->ODDSupportedVersion}\" generated=\"$generated\">\n";
-
-                       // Get XML for elements
-                       foreach ($this->elements as $element) {
-                               $xml .= "$element";
-                       }
-
-                       // Output end tag
-                       $xml .= "</odd>\n";
-               }
-
-               return $xml;
-       }
-
-       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////
-       /*
-        * This lets an entity's attributes be displayed using foreach as a normal array.
-        * Example: http://www.sitepoint.com/print/php5-standard-library
-        */
-
-       private $valid = FALSE;
-
-       function rewind() {
-               $this->valid = (FALSE !== reset($this->elements));
-       }
-
-       function current() {
-               return current($this->elements);
-       }
-
-       function key() {
-               return key($this->elements);
-       }
-
-       function next() {
-               $this->valid = (FALSE !== next($this->elements));
-       }
-
-       function valid() {
-               return $this->valid;
-       }
-}
-
-/**
- * Open Data Definition (ODD) superclass.
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd
- */
-abstract class ODD {
-       /**
-        * Attributes.
-        */
-       private $attributes = array();
-
-       /**
-        * Optional body.
-        */
-       private $body;
-
-       /**
-        * Construct an ODD document with initial values.
-        */
-       public function __construct() {
-               $this->body = "";
-       }
-
-       public function getAttributes() {
-               return $this->attributes;
-       }
-
-       public function setAttribute($key, $value) {
-               $this->attributes[$key] = $value;
-       }
-
-       public function getAttribute($key) {
-               if (isset($this->attributes[$key])) {
-                       return $this->attributes[$key];
-               }
-
-               return NULL;
-       }
-
-       public function setBody($value) {
-               $this->body = $value;
-       }
-
-       public function getBody() {
-               return $this->body;
-       }
-
-       /**
-        * Set the published time.
-        *
-        * @param int $time Unix timestamp
-        */
-       public function setPublished($time) {
-               $this->attributes['published'] = date("r", $time);
-       }
-
-       /**
-        * Return the published time as a unix timestamp.
-        *
-        * @return int or false on failure.
-        */
-       public function getPublishedAsTime() {
-               return strtotime($this->attributes['published']);
-       }
-
-       /**
-        * For serialisation, implement to return a string name of the tag eg "header" or "metadata".
-        * @return string
-        */
-       abstract protected function getTagName();
-
-       /**
-        * Magic function to generate valid ODD XML for this item.
-        */
-       public function __toString() {
-               // Construct attributes
-               $attr = "";
-               foreach ($this->attributes as $k => $v) {
-                       $attr .= ($v!="") ? "$k=\"$v\" " : "";
-               }
-
-               $body = $this->getBody();
-               $tag = $this->getTagName();
-
-               $end = "/>";
-               if ($body!="") {
-                       $end = "><![CDATA[$body]]></{$tag}>";
-               }
-
-               return "<{$tag} $attr" . $end . "\n";
-       }
-}
-
-/**
- * ODD Entity class.
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd
- */
-class ODDEntity extends ODD {
-       function __construct($uuid, $class, $subclass = "") {
-               parent::__construct();
-
-               $this->setAttribute('uuid', $uuid);
-               $this->setAttribute('class', $class);
-               $this->setAttribute('subclass', $subclass);
-       }
-
-       protected function getTagName() { return "entity"; }
-}
-
-/**
- * ODD Metadata class.
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd
- */
-class ODDMetaData extends ODD {
-       function __construct($uuid, $entity_uuid, $name, $value, $type = "", $owner_uuid = "") {
-               parent::__construct();
-
-               $this->setAttribute('uuid', $uuid);
-               $this->setAttribute('entity_uuid', $entity_uuid);
-               $this->setAttribute('name', $name);
-               $this->setAttribute('type', $type);
-               $this->setAttribute('owner_uuid', $owner_uuid);
-               $this->setBody($value);
-       }
-
-       protected function getTagName() {
-               return "metadata";
-       }
-}
-
-/**
- * ODD Relationship class.
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd
- */
-class ODDRelationship extends ODD {
-       function __construct($uuid1, $type, $uuid2) {
-               parent::__construct();
-
-               $this->setAttribute('uuid1', $uuid1);
-               $this->setAttribute('type', $type);
-               $this->setAttribute('uuid2', $uuid2);
-       }
-
-       protected function getTagName() { return "relationship"; }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ODDDocument.php';
+require_once dirname(dirname(__FILE__)).'/classes/ODD.php';
+require_once dirname(dirname(__FILE__)).'/classes/ODDEntity.php';
 
 /**
  * Attempt to construct an ODD object out of a XmlElement or sub-elements.
index c2427c655825e15ab4d06242ed740bf74e2395de..e89e6007a83ae28cae63011b2dee24bd45b8eebd 100644 (file)
@@ -23,61 +23,7 @@ $ENABLED_PLUGINS_CACHE = NULL;
  */
 class PluginException extends Exception {}
 
-/**
- * @class ElggPlugin Object representing a plugin's settings for a given site.
- * This class is currently a stub, allowing a plugin to saving settings in an object's metadata for each site.
- * @author Curverider Ltd
- */
-class ElggPlugin extends ElggObject {
-       protected function initialise_attributes() {
-               parent::initialise_attributes();
-
-               $this->attributes['subtype'] = "plugin";
-       }
-
-       public function __construct($guid = null) {
-               parent::__construct($guid);
-       }
-
-       /**
-        * Override entity get and sets in order to save data to private data store.
-        */
-       public function get($name) {
-               // See if its in our base attribute
-               if (isset($this->attributes[$name])) {
-                       return $this->attributes[$name];
-               }
-
-               // No, so see if its in the private data store.
-               // get_private_setting() returns false if it doesn't exist
-               $meta = get_private_setting($this->guid, $name);
-
-               if ($meta === false) {
-                       // Can't find it, so return null
-                       return NULL;
-               }
-
-               return $meta;
-       }
-
-       /**
-        * Override entity get and sets in order to save data to private data store.
-        */
-       public function set($name, $value) {
-               if (array_key_exists($name, $this->attributes)) {
-                       // Check that we're not trying to change the guid!
-                       if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) {
-                               return false;
-                       }
-
-                       $this->attributes[$name] = $value;
-               } else {
-                       return set_private_setting($this->guid, $name, $value);
-               }
-
-               return true;
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggPlugin.php';
 
 /**
  * Returns a list of plugins to load, in the order that they should be loaded.
index dd8a2b188fea830de8fdfa0f52827b16cd92e5c9..81d18d1ca7faffd18f7969f82141481a06101789 100644 (file)
@@ -9,292 +9,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * Relationship class.
- *
- * @author Curverider Ltd
- * @package Elgg
- * @subpackage Core
- */
-class ElggRelationship implements
-       Importable,
-       Exportable,
-       Loggable,       // Can events related to this object class be logged
-       Iterator,       // Override foreach behaviour
-       ArrayAccess // Override for array access
-       {
-       /**
-        * This contains the site's main properties (id, etc)
-        * @var array
-        */
-       protected $attributes;
-
-       /**
-        * Construct a new site object, optionally from a given id value or row.
-        *
-        * @param mixed $id
-        */
-       function __construct($id = null) {
-               $this->attributes = array();
-
-               if (!empty($id)) {
-                       if ($id instanceof stdClass) {
-                               $relationship = $id; // Create from db row
-                       } else {
-                               $relationship = get_relationship($id);
-                       }
-
-                       if ($relationship) {
-                               $objarray = (array) $relationship;
-                               foreach($objarray as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Class member get overloading
-        *
-        * @param string $name
-        * @return mixed
-        */
-       function __get($name) {
-               if (isset($this->attributes[$name])) {
-                       return $this->attributes[$name];
-               }
-
-               return null;
-       }
-
-       /**
-        * Class member set overloading
-        *
-        * @param string $name
-        * @param mixed $value
-        * @return mixed
-        */
-       function __set($name, $value) {
-               $this->attributes[$name] = $value;
-               return true;
-       }
-
-       /**
-        * Save the relationship
-        *
-        * @return int the relationship id
-        */
-       public function save() {
-               if ($this->id > 0) {
-                       delete_relationship($this->id);
-               }
-
-               $this->id = add_entity_relationship($this->guid_one, $this->relationship, $this->guid_two);
-               if (!$this->id) {
-                       throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));
-               }
-
-               return $this->id;
-       }
-
-       /**
-        * Delete a given relationship.
-        */
-       public function delete() {
-               return delete_relationship($this->id);
-       }
-
-       /**
-        * Get a URL for this relationship.
-        *
-        * @return string
-        */
-       public function getURL() {
-               return get_relationship_url($this->id);
-       }
-
-       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an array of fields which can be exported.
-        */
-       public function getExportableValues() {
-               return array(
-                       'id',
-                       'guid_one',
-                       'relationship',
-                       'guid_two'
-               );
-       }
-
-       /**
-        * Export this relationship
-        *
-        * @return array
-        */
-       public function export() {
-               $uuid = get_uuid_from_object($this);
-               $relationship = new ODDRelationship(
-                       guid_to_uuid($this->guid_one),
-                       $this->relationship,
-                       guid_to_uuid($this->guid_two)
-               );
-
-               $relationship->setAttribute('uuid', $uuid);
-
-               return $relationship;
-       }
-
-       // IMPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Import a relationship
-        *
-        * @param array $data
-        * @param int $version
-        * @return ElggRelationship
-        * @throws ImportException
-        */
-       public function import(ODD $data) {
-               if (!($element instanceof ODDRelationship)) {
-                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass'));
-               }
-
-               $uuid_one = $data->getAttribute('uuid1');
-               $uuid_two = $data->getAttribute('uuid2');
-
-               // See if this entity has already been imported, if so then we need to link to it
-               $entity1 = get_entity_from_uuid($uuid_one);
-               $entity2 = get_entity_from_uuid($uuid_two);
-               if (($entity1) && ($entity2)) {
-                       // Set the item ID
-                       $this->attributes['guid_one'] = $entity1->getGUID();
-                       $this->attributes['guid_two'] = $entity2->getGUID();
-
-                       // Map verb to relationship
-                       //$verb = $data->getAttribute('verb');
-                       //$relationship = get_relationship_from_verb($verb);
-                       $relationship = $data->getAttribute('type');
-
-                       if ($relationship) {
-                               $this->attributes['relationship'] = $relationship;
-                               // save
-                               $result = $this->save();
-                               if (!$result) {
-                                       throw new ImportException(sprintf(elgg_echo('ImportException:ProblemSaving'), get_class()));
-                               }
-
-                               return $this;
-                       }
-               }
-       }
-
-       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an identification for the object for storage in the system log.
-        * This id must be an integer.
-        *
-        * @return int
-        */
-       public function getSystemLogID() {
-               return $this->id;
-       }
-
-       /**
-        * Return the class name of the object.
-        */
-       public function getClassName() {
-               return get_class($this);
-       }
-
-       /**
-        * For a given ID, return the object associated with it.
-        * This is used by the river functionality primarily.
-        * This is useful for checking access permissions etc on objects.
-        */
-       public function getObjectFromID($id) {
-               return get_relationship($id);
-       }
-
-       /**
-        * Return the GUID of the owner of this object.
-        */
-       public function getObjectOwnerGUID() {
-               return $this->owner_guid;
-       }
-
-       /**
-        * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc
-        */
-       public function getType() {
-               return 'relationship';
-       }
-
-       /**
-        * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.
-        */
-       public function getSubtype() {
-               return $this->relationship;
-       }
-
-       // ITERATOR INTERFACE //////////////////////////////////////////////////////////////
-       /*
-        * This lets an entity's attributes be displayed using foreach as a normal array.
-        * Example: http://www.sitepoint.com/print/php5-standard-library
-        */
-
-       private $valid = FALSE;
-
-       function rewind() {
-               $this->valid = (FALSE !== reset($this->attributes));
-       }
-
-       function current() {
-               return current($this->attributes);
-       }
-
-       function key() {
-               return key($this->attributes);
-       }
-
-       function next() {
-               $this->valid = (FALSE !== next($this->attributes));
-       }
-
-       function valid() {
-               return $this->valid;
-       }
-
-       // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
-       /*
-        * This lets an entity's attributes be accessed like an associative array.
-        * Example: http://www.sitepoint.com/print/php5-standard-library
-        */
-
-       function offsetSet($key, $value) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       $this->attributes[$key] = $value;
-               }
-       }
-
-       function offsetGet($key) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       return $this->attributes[$key];
-               }
-       }
-
-       function offsetUnset($key) {
-               if ( array_key_exists($key, $this->attributes) ) {
-                       $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects
-               }
-       }
-
-       function offsetExists($offset) {
-               return array_key_exists($offset, $this->attributes);
-       }
-}
-
+require_once dirname(dirname(__FILE__)).'/classes/ElggRelationship.php';
 
 /**
  * Convert a database row to a new ElggRelationship
index 428a521a2be5f421749ee065a20c31e8dd2135b5..f2a5342948ddd66789ad91ed958d4fb1e984f33e 100644 (file)
 /** Elgg magic session */
 global $SESSION;
 
-/**
- * Magic session class.
- * This class is intended to extend the $_SESSION magic variable by providing an API hook
- * to plug in other values.
- *
- * Primarily this is intended to provide a way of supplying "logged in user" details without touching the session
- * (which can cause problems when accessed server side).
- *
- * If a value is present in the session then that value is returned, otherwise a plugin hook 'session:get', '$var' is called,
- * where $var is the variable being requested.
- *
- * Setting values will store variables in the session in the normal way.
- *
- * LIMITATIONS: You can not access multidimensional arrays
- *
- * This is EXPERIMENTAL.
- */
-class ElggSession implements ArrayAccess {
-       /** Local cache of trigger retrieved variables */
-       private static $__localcache;
-
-       function __isset($key) {
-               return $this->offsetExists($key);
-       }
-
-       /** Set a value, go straight to session. */
-       function offsetSet($key, $value) {
-               $_SESSION[$key] = $value;
-       }
-
-       /**
-        * Get a variable from either the session, or if its not in the session attempt to get it from
-        * an api call.
-        */
-       function offsetGet($key) {
-               if (!ElggSession::$__localcache) {
-                       ElggSession::$__localcache = array();
-               }
-
-               if (isset($_SESSION[$key])) {
-                       return $_SESSION[$key];
-               }
-
-               if (isset(ElggSession::$__localcache[$key])) {
-                       return ElggSession::$__localcache[$key];
-               }
-
-               $value = NULL;
-               $value = trigger_plugin_hook('session:get', $key, NULL, $value);
-
-               ElggSession::$__localcache[$key] = $value;
-
-               return ElggSession::$__localcache[$key];
-       }
-
-       /**
-       * Unset a value from the cache and the session.
-       */
-       function offsetUnset($key) {
-               unset(ElggSession::$__localcache[$key]);
-               unset($_SESSION[$key]);
-       }
-
-       /**
-       * Return whether the value is set in either the session or the cache.
-       */
-       function offsetExists($offset) {
-               if (isset(ElggSession::$__localcache[$offset])) {
-                       return true;
-               }
-
-               if (isset($_SESSION[$offset])) {
-                       return true;
-               }
-
-               if ($this->offsetGet($offset)){
-                       return true;
-               }
-       }
-
-
-       // Alias functions
-       function get($key) {
-               return $this->offsetGet($key);
-       }
-
-       function set($key, $value) {
-               return $this->offsetSet($key, $value);
-       }
-
-       function del($key) {
-               return $this->offsetUnset($key);
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggSession.php';
 
 
 /**
index 23a922757f29d1192c0af7b10e366664a925fdc5..ee556e86cb70e3826a01156beb056a990a358f11 100644 (file)
@@ -9,304 +9,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * ElggSite
- * Representation of a "site" in the system.
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-class ElggSite extends ElggEntity {
-       /**
-        * Initialise the attributes array.
-        * This is vital to distinguish between metadata and base parameters.
-        *
-        * Place your base parameters here.
-        */
-       protected function initialise_attributes() {
-               parent::initialise_attributes();
-
-               $this->attributes['type'] = "site";
-               $this->attributes['name'] = "";
-               $this->attributes['description'] = "";
-               $this->attributes['url'] = "";
-               $this->attributes['tables_split'] = 2;
-       }
-
-       /**
-        * Construct a new site object, optionally from a given id value.
-        *
-        * @param mixed $guid If an int, load that GUID.
-        *      If a db row then will attempt to load the rest of the data.
-        * @throws Exception if there was a problem creating the site.
-        */
-       function __construct($guid = null) {
-               $this->initialise_attributes();
-
-               if (!empty($guid)) {
-                       // Is $guid is a DB row - either a entity row, or a site table row.
-                       if ($guid instanceof stdClass) {
-                               // Load the rest
-                               if (!$this->load($guid->guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));
-                               }
-                       }
-
-                       // Is $guid is an ElggSite? Use a copy constructor
-                       else if ($guid instanceof ElggSite) {
-                               elgg_deprecated_notice('This type of usage of the ElggSite constructor was deprecated. Please use the clone method.', 1.7);
-                               
-                               foreach ($guid->attributes as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                       }
-
-                       // Is this is an ElggEntity but not an ElggSite = ERROR!
-                       else if ($guid instanceof ElggEntity) {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggSite'));
-                       }
-
-                       // See if this is a URL
-                       else if (strpos($guid, "http") !== false) {
-                               $guid = get_site_by_url($guid);
-                               foreach ($guid->attributes as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                       }
-
-                       // We assume if we have got this far, $guid is an int
-                       else if (is_numeric($guid)) {
-                               if (!$this->load($guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
-                               }
-                       }
-
-                       else {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
-                       }
-               }
-       }
-
-       /**
-        * Override the load function.
-        * This function will ensure that all data is loaded (were possible), so
-        * if only part of the ElggSite is loaded, it'll load the rest.
-        *
-        * @param int $guid
-        */
-       protected function load($guid) {
-               // Test to see if we have the generic stuff
-               if (!parent::load($guid)) {
-                       return false;
-               }
-
-               // Check the type
-               if ($this->attributes['type']!='site') {
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
-               }
-
-               // Load missing data
-               $row = get_site_entity_as_row($guid);
-               if (($row) && (!$this->isFullyLoaded())) {
-                       // If $row isn't a cached copy then increment the counter
-                       $this->attributes['tables_loaded'] ++;
-               }
-
-               // Now put these into the attributes array as core values
-               $objarray = (array) $row;
-               foreach($objarray as $key => $value) {
-                       $this->attributes[$key] = $value;
-               }
-
-               return true;
-       }
-
-       /**
-        * Override the save function.
-        */
-       public function save() {
-               // Save generic stuff
-               if (!parent::save()) {
-                       return false;
-               }
-
-               // Now save specific stuff
-               return create_site_entity($this->get('guid'), $this->get('name'), $this->get('description'), $this->get('url'));
-       }
-
-       /**
-        * Delete this site.
-        */
-       public function delete() {
-               global $CONFIG;
-               if ($CONFIG->site->getGUID() == $this->guid) {
-                       throw new SecurityException('SecurityException:deletedisablecurrentsite');
-               }
-
-               return parent::delete();
-       }
-
-       /**
-        * Disable override to add safety rail.
-        *
-        * @param unknown_type $reason
-        */
-       public function disable($reason = "") {
-               global $CONFIG;
-
-               if ($CONFIG->site->getGUID() == $this->guid) {
-                       throw new SecurityException('SecurityException:deletedisablecurrentsite');
-               }
-
-               return parent::disable($reason);
-       }
-
-       /**
-        * Return a list of users using this site.
-        *
-        * @param int $limit
-        * @param int $offset
-        * @return array of ElggUsers
-        */
-       public function getMembers($limit = 10, $offset = 0) {
-               get_site_members($this->getGUID(), $limit, $offset);
-       }
-
-       /**
-        * Add a user to the site.
-        *
-        * @param int $user_guid
-        */
-       public function addUser($user_guid) {
-               return add_site_user($this->getGUID(), $user_guid);
-       }
-
-       /**
-        * Remove a site user.
-        *
-        * @param int $user_guid
-        */
-       public function removeUser($user_guid) {
-               return remove_site_user($this->getGUID(), $user_guid);
-       }
-
-       /**
-        * Get an array of member ElggObjects.
-        *
-        * @param string $subtype
-        * @param int $limit
-        * @param int $offset
-        */
-       public function getObjects($subtype="", $limit = 10, $offset = 0) {
-               get_site_objects($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * Add an object to the site.
-        *
-        * @param int $user_id
-        */
-       public function addObject($object_guid) {
-               return add_site_object($this->getGUID(), $object_guid);
-       }
-
-       /**
-        * Remove a site user.
-        *
-        * @param int $user_id
-        */
-       public function removeObject($object_guid) {
-               return remove_site_object($this->getGUID(), $object_guid);
-       }
-
-       /**
-        * Get the collections associated with a site.
-        *
-        * @param string $type
-        * @param int $limit
-        * @param int $offset
-        * @return unknown
-        */
-       public function getCollections($subtype="", $limit = 10, $offset = 0) {
-               get_site_collections($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an array of fields which can be exported.
-        */
-       public function getExportableValues() {
-               return array_merge(parent::getExportableValues(), array(
-                       'name',
-                       'description',
-                       'url',
-               ));
-       }
-       
-       public function check_walled_garden() {
-               global $CONFIG;
-               
-               if ($CONFIG->walled_garden && !isloggedin()) {
-                       // hook into the index system call at the highest priority
-                       register_plugin_hook('index', 'system', 'elgg_walled_garden_index', 1);
-                       
-                       if (!$this->is_public_page()) {
-                               register_error(elgg_echo('loggedinrequired'));
-                               forward();
-                       }
-               }
-       }
-       
-       public function is_public_page($url='') {
-               global $CONFIG;
-               
-               if (empty($url)) {
-                       $url = current_page_url();
-                       
-                       // do not check against URL queries
-                       if ($pos = strpos($url, '?')) {
-                               $url = substr($url, 0, $pos);
-                       }
-               }
-               
-               // always allow index page
-               if ($url == $CONFIG->url) {
-                       return TRUE;
-               }
-               
-               // default public pages
-               $defaults = array(
-                       'action/login',
-                       'pg/register',
-                       'action/register',
-                       'account/forgotten_password\.php',
-                       'action/user/requestnewpassword',
-                       'pg/resetpassword',
-                       'upgrade\.php',
-                       'xml-rpc\.php',
-                       'mt/mt-xmlrpc\.cgi',
-                       '_css/css\.css',
-                       '_css/js\.php',
-               );
-               
-               // include a hook for plugin authors to include public pages
-               $plugins = trigger_plugin_hook('public_pages', 'walled_garden', NULL, array());
-               
-               // lookup admin-specific public pages
-               
-               // allow public pages
-               foreach (array_merge($defaults, $plugins) as $public) {
-                       $pattern = "`^{$CONFIG->url}$public/*$`i";
-                       if (preg_match($pattern, $url)) {
-                               return TRUE;
-                       }
-               }
-               
-               // non-public page
-               return FALSE;
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggSite.php';
 
 /**
  * Return the site specific details of a site by a row.
index 74597ed5d92fb5b80f278a475a9f655cac9d62cd..9a94fb94e2b43b783cb3444340eccb600750db52 100644 (file)
@@ -9,54 +9,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * Interface that provides an interface which must be implemented by all objects wishing to be
- * recorded in the system log (and by extension the river).
- *
- * This interface defines a set of methods that permit the system log functions to hook in and retrieve
- * the necessary information and to identify what events can actually be logged.
- *
- * To have events involving your object to be logged simply implement this interface.
- *
- * @author Curverider Ltd
- */
-interface Loggable {
-       /**
-        * Return an identification for the object for storage in the system log.
-        * This id must be an integer.
-        *
-        * @return int
-        */
-       public function getSystemLogID();
-
-       /**
-        * Return the class name of the object.
-        * Added as a function because get_class causes errors for some reason.
-        */
-       public function getClassName();
-
-       /**
-        * Return the type of the object - eg. object, group, user, relationship, metadata, annotation etc
-        */
-       public function getType();
-
-       /**
-        * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.
-        */
-       public function getSubtype();
-
-       /**
-        * For a given ID, return the object associated with it.
-        * This is used by the river functionality primarily.
-        * This is useful for checking access permissions etc on objects.
-        */
-       public function getObjectFromID($id);
-
-       /**
-        * Return the GUID of the owner of this object.
-        */
-       public function getObjectOwnerGUID();
-}
+require_once dirname(dirname(__FILE__)).'/classes/Loggable.php';
 
 /**
  * Retrieve the system log based on a number of parameters.
index 3722c8ed15e39a369560ecdfcd9149d3b18fd8a4..03d0d06c4d88cbb5f2d985e61b1932e51153dc84 100644 (file)
@@ -15,432 +15,7 @@ $USERNAME_TO_GUID_MAP_CACHE = array();
 /// Map a user code to a cached GUID
 $CODE_TO_GUID_MAP_CACHE = array();
 
-/**
- * ElggUser
- *
- * Representation of a "user" in the system.
- *
- * @package Elgg
- * @subpackage Core
- */
-class ElggUser extends ElggEntity
-       implements Friendable {
-       /**
-        * Initialise the attributes array.
-        * This is vital to distinguish between metadata and base parameters.
-        *
-        * Place your base parameters here.
-        */
-       protected function initialise_attributes() {
-               parent::initialise_attributes();
-
-               $this->attributes['type'] = "user";
-               $this->attributes['name'] = "";
-               $this->attributes['username'] = "";
-               $this->attributes['password'] = "";
-               $this->attributes['salt'] = "";
-               $this->attributes['email'] = "";
-               $this->attributes['language'] = "";
-               $this->attributes['code'] = "";
-               $this->attributes['banned'] = "no";
-               $this->attributes['admin'] = 'no';
-               $this->attributes['tables_split'] = 2;
-       }
-
-       /**
-        * Construct a new user entity, optionally from a given id value.
-        *
-        * @param mixed $guid If an int, load that GUID.
-        *      If a db row then will attempt to load the rest of the data.
-        * @throws Exception if there was a problem creating the user.
-        */
-       function __construct($guid = null) {
-               $this->initialise_attributes();
-
-               if (!empty($guid)) {
-                       // Is $guid is a DB row - either a entity row, or a user table row.
-                       if ($guid instanceof stdClass) {
-                               // Load the rest
-                               if (!$this->load($guid->guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));
-                               }
-                       }
-
-                       // See if this is a username
-                       else if (is_string($guid)) {
-                               $guid = get_user_by_username($guid);
-                               foreach ($guid->attributes as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                       }
-
-                       // Is $guid is an ElggUser? Use a copy constructor
-                       else if ($guid instanceof ElggUser) {
-                               elgg_deprecated_notice('This type of usage of the ElggUser constructor was deprecated. Please use the clone method.', 1.7);
-
-                               foreach ($guid->attributes as $key => $value) {
-                                       $this->attributes[$key] = $value;
-                               }
-                       }
-
-                       // Is this is an ElggEntity but not an ElggUser = ERROR!
-                       else if ($guid instanceof ElggEntity) {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggUser'));
-                       }
-
-                       // We assume if we have got this far, $guid is an int
-                       else if (is_numeric($guid)) {
-                               if (!$this->load($guid)) {
-                                       throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
-                               }
-                       }
-
-                       else {
-                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
-                       }
-               }
-       }
-
-       /**
-        * Override the load function.
-        * This function will ensure that all data is loaded (were possible), so
-        * if only part of the ElggUser is loaded, it'll load the rest.
-        *
-        * @param int $guid
-        * @return true|false
-        */
-       protected function load($guid) {
-               // Test to see if we have the generic stuff
-               if (!parent::load($guid)) {
-                       return false;
-               }
-
-               // Check the type
-               if ($this->attributes['type']!='user') {
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
-               }
-
-               // Load missing data
-               $row = get_user_entity_as_row($guid);
-               if (($row) && (!$this->isFullyLoaded())) {
-                       // If $row isn't a cached copy then increment the counter
-                       $this->attributes['tables_loaded'] ++;
-               }
-
-               // Now put these into the attributes array as core values
-               $objarray = (array) $row;
-               foreach($objarray as $key => $value) {
-                       $this->attributes[$key] = $value;
-               }
-
-               return true;
-       }
-
-       /**
-        * Saves this user to the database.
-        * @return true|false
-        */
-       public function save() {
-               // Save generic stuff
-               if (!parent::save()) {
-                       return false;
-               }
-
-               // Now save specific stuff
-               return create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'), $this->get('password'), $this->get('salt'), $this->get('email'), $this->get('language'), $this->get('code'));
-       }
-
-       /**
-        * User specific override of the entity delete method.
-        *
-        * @return bool
-        */
-       public function delete() {
-               global $USERNAME_TO_GUID_MAP_CACHE, $CODE_TO_GUID_MAP_CACHE;
-
-               // clear cache
-               if (isset($USERNAME_TO_GUID_MAP_CACHE[$this->username])) {
-                       unset($USERNAME_TO_GUID_MAP_CACHE[$this->username]);
-               }
-               if (isset($CODE_TO_GUID_MAP_CACHE[$this->code])) {
-                       unset($CODE_TO_GUID_MAP_CACHE[$this->code]);
-               }
-
-               // Delete owned data
-               clear_annotations_by_owner($this->guid);
-               clear_metadata_by_owner($this->guid);
-               clear_user_files($this);
-
-               // Delete entity
-               return parent::delete();
-       }
-
-       /**
-        * Ban this user.
-        *
-        * @param string $reason Optional reason
-        */
-       public function ban($reason = "") {
-               return ban_user($this->guid, $reason);
-       }
-
-       /**
-        * Unban this user.
-        */
-       public function unban() {
-               return unban_user($this->guid);
-       }
-
-       /**
-        * Is this user banned or not?
-        *
-        * @return bool
-        */
-       public function isBanned() {
-               return $this->banned == 'yes';
-       }
-
-       /**
-        * Is this user admin?
-        *
-        * @return bool
-        */
-       public function isAdmin() {
-
-               // for backward compatibility we need to pull this directly
-               // from the attributes instead of using the magic methods.
-               // this can be removed in 1.9
-               // return $this->admin == 'yes';
-               return $this->attributes['admin'] == 'yes';
-       }
-
-       /**
-        * Make the user an admin
-        *
-        * @return bool
-        */
-       public function makeAdmin() {
-               if (make_user_admin($this->guid)) {
-                       $this->attributes['admin'] = 'yes';
-                       return TRUE;
-               }
-               return FALSE;
-       }
-
-       /**
-        * Remove the admin flag for user
-        *
-        * @return bool
-        */
-       public function removeAdmin() {
-               if (remove_user_admin($this->guid)) {
-                       $this->attributes['admin'] = 'no';
-                       return TRUE;
-               }
-               return FALSE;
-       }
-
-       /**
-        * Get sites that this user is a member of
-        *
-        * @param string $subtype Optionally, the subtype of result we want to limit to
-        * @param int $limit The number of results to return
-        * @param int $offset Any indexing offset
-        */
-       function getSites($subtype="", $limit = 10, $offset = 0) {
-               // return get_site_users($this->getGUID(), $subtype, $limit, $offset);
-               return get_user_sites($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * Add this user to a particular site
-        *
-        * @param int $site_guid The guid of the site to add it to
-        * @return true|false
-        */
-       function addToSite($site_guid) {
-               // return add_site_user($this->getGUID(), $site_guid);
-               return add_site_user($site_guid, $this->getGUID());
-       }
-
-       /**
-        * Remove this user from a particular site
-        *
-        * @param int $site_guid The guid of the site to remove it from
-        * @return true|false
-        */
-       function removeFromSite($site_guid) {
-               //return remove_site_user($this->getGUID(), $site_guid);
-               return remove_site_user($site_guid, $this->getGUID());
-       }
-
-       /**
-        * Adds a user to this user's friends list
-        *
-        * @param int $friend_guid The GUID of the user to add
-        * @return true|false Depending on success
-        */
-       function addFriend($friend_guid) {
-               return user_add_friend($this->getGUID(), $friend_guid);
-       }
-
-       /**
-        * Removes a user from this user's friends list
-        *
-        * @param int $friend_guid The GUID of the user to remove
-        * @return true|false Depending on success
-        */
-       function removeFriend($friend_guid) {
-               return user_remove_friend($this->getGUID(), $friend_guid);
-       }
-
-       /**
-        * Determines whether or not this user is a friend of the currently logged in user
-        *
-        * @return true|false
-        */
-       function isFriend() {
-               return user_is_friend(get_loggedin_userid(), $this->getGUID());
-       }
-
-       /**
-        * Determines whether this user is friends with another user
-        *
-        * @param int $user_guid The GUID of the user to check is on this user's friends list
-        * @return true|false
-        */
-       function isFriendsWith($user_guid) {
-               return user_is_friend($this->getGUID(), $user_guid);
-       }
-
-       /**
-        * Determines whether or not this user is on another user's friends list
-        *
-        * @param int $user_guid The GUID of the user to check against
-        * @return true|false
-        */
-       function isFriendOf($user_guid) {
-               return user_is_friend($user_guid, $this->getGUID());
-       }
-
-       /**
-        * Retrieves a list of this user's friends
-        *
-        * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all)
-        * @param int $limit The number of users to retrieve
-        * @param int $offset Indexing offset, if any
-        * @return array|false Array of ElggUsers, or false, depending on success
-        */
-       function getFriends($subtype = "", $limit = 10, $offset = 0) {
-               return get_user_friends($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * Retrieves a list of people who have made this user a friend
-        *
-        * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all)
-        * @param int $limit The number of users to retrieve
-        * @param int $offset Indexing offset, if any
-        * @return array|false Array of ElggUsers, or false, depending on success
-        */
-       function getFriendsOf($subtype = "", $limit = 10, $offset = 0) {
-               return get_user_friends_of($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * Get an array of ElggObjects owned by this user.
-        *
-        * @param string $subtype The subtype of the objects, if any
-        * @param int $limit Number of results to return
-        * @param int $offset Any indexing offset
-        */
-       public function getObjects($subtype="", $limit = 10, $offset = 0) {
-               return get_user_objects($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * Get an array of ElggObjects owned by this user's friends.
-        *
-        * @param string $subtype The subtype of the objects, if any
-        * @param int $limit Number of results to return
-        * @param int $offset Any indexing offset
-        */
-       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) {
-               return get_user_friends_objects($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * Counts the number of ElggObjects owned by this user
-        *
-        * @param string $subtype The subtypes of the objects, if any
-        * @return int The number of ElggObjects
-        */
-       public function countObjects($subtype = "") {
-               return count_user_objects($this->getGUID(), $subtype);
-       }
-
-       /**
-        * Get the collections associated with a user.
-        *
-        * @param string $subtype Optionally, the subtype of result we want to limit to
-        * @param int $limit The number of results to return
-        * @param int $offset Any indexing offset
-        * @return unknown
-        */
-       public function getCollections($subtype="", $limit = 10, $offset = 0) {
-               return get_user_collections($this->getGUID(), $subtype, $limit, $offset);
-       }
-
-       /**
-        * If a user's owner is blank, return its own GUID as the owner
-        *
-        * @return int User GUID
-        */
-       function getOwner() {
-               if ($this->owner_guid == 0) {
-                       return $this->getGUID();
-               }
-
-               return $this->owner_guid;
-       }
-
-       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
-       /**
-        * Return an array of fields which can be exported.
-        */
-       public function getExportableValues() {
-               return array_merge(parent::getExportableValues(), array(
-                       'name',
-                       'username',
-                       'language',
-               ));
-       }
-
-       // backward compatibility with admin flag
-       // remove for 1.9
-       public function __set($name, $value) {
-               if ($name == 'admin' || $name == 'siteadmin') {
-                       elgg_deprecated_notice('The admin/siteadmin metadata are not longer used.  Use ElggUser->makeAdmin() and ElggUser->removeAdmin().', '1.7.1');
-
-                       if ($value == 'yes' || $value == '1') {
-                               $this->makeAdmin();
-                       } else {
-                               $this->removeAdmin();
-                       }
-               }
-               return parent::__set($name, $value);
-       }
-
-       public function __get($name) {
-               if ($name == 'admin' || $name == 'siteadmin') {
-                       elgg_deprecated_notice('The admin/siteadmin metadata are not longer used.  Use ElggUser->isAdmin().', '1.7.1');
-                       return $this->isAdmin();
-               }
-
-               return parent::__get($name);
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggUser.php';
 
 /**
  * Return the user specific details of a user by a row.
index 03524da6213a380dce0f16ce2e9352b439c49d28..210aa198fcd5895de270a3e4f647eb86f0bcfc2a 100644 (file)
@@ -8,57 +8,7 @@
  * @link http://elgg.org/
  */
 
-/**
- * Override ElggObject in order to store widget data in ultra-private stores.
- */
-class ElggWidget extends ElggObject {
-       protected function initialise_attributes() {
-               parent::initialise_attributes();
-
-               $this->attributes['subtype'] = "widget";
-       }
-
-       public function __construct($guid = null) {
-               parent::__construct($guid);
-       }
-
-       /**
-        * Override entity get and sets in order to save data to private data store.
-        */
-       public function get($name) {
-               // See if its in our base attribute
-               if (isset($this->attributes[$name])) {
-                       return $this->attributes[$name];
-               }
-
-               // No, so see if its in the private data store.
-               $meta = get_private_setting($this->guid, $name);
-               if ($meta) {
-                       return $meta;
-               }
-
-               // Can't find it, so return null
-               return null;
-       }
-
-       /**
-        * Override entity get and sets in order to save data to private data store.
-        */
-       public function set($name, $value) {
-               if (array_key_exists($name, $this->attributes)) {
-                       // Check that we're not trying to change the guid!
-                       if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) {
-                               return false;
-                       }
-
-                       $this->attributes[$name] = $value;
-               } else {
-                       return set_private_setting($this->guid, $name, $value);
-               }
-
-               return true;
-       }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggWidget.php';
 
 /**
  * Register a particular context for use with widgets.
index 110dd76ddd9d2d3f45f252b993189048b94e24eb..79c3eba0789a02b304461790a173886a82632271 100644 (file)
         */
 
        // XMLRPC Call ////////////////////////////////////////////////////////////////////////////
-       
-       /**
-        * @class XMLRPCCall
-        * This class represents 
-        * @author Curverider Ltd
-        */
-       class XMLRPCCall
-       {
-               /** Method name */
-               private $methodname;
-               /** Parameters */
-               private $params;
-               
-               /**
-                * Construct a new XML RPC Call
-                *
-                * @param string $xml
-                */
-               function __construct($xml)
-               {
-                       $this->parse($xml);
-               }
-               
-               /**
-                * Return the method name associated with the call.
-                *
-                * @return string
-                */
-               public function getMethodName() { return $this->methodname; }
-               
-               /**
-                * Return the parameters.
-                * Returns a nested array of XmlElement.
-                * 
-                * @see XmlElement 
-                * @return array
-                */
-               public function getParameters() { return $this->params; }
-               
-               /**
-                * Parse the xml into its components according to spec. 
-                * This first version is a little primitive. 
-                *
-                * @param string $xml
-                */
-               private function parse($xml)
-               {
-                       $xml = xml_to_object($xml);
-                       
-                       // sanity check
-                       if ((isset($xml->name)) && (strcasecmp($xml->name, "methodCall")!=0))
-                               throw new CallException(elgg_echo('CallException:NotRPCCall'));
-                       
-                       // method name
-                       $this->methodname = $xml->children[0]->content;
-                       
-                       // parameters 
-                       $this->params = $xml->children[1]->children;                    
-               }
-       }
-       
-       // Response classes ///////////////////////////////////////////////////////////////////////
 
-       /**
-        * @class XMLRPCParameter Superclass for all RPC parameters.
-        * @author Curverider Ltd
-        */
-       abstract class XMLRPCParameter
-       {
-               protected $value;
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCCall.php';
 
-               function __construct() { }
-                       
-       }
-       
-       /**
-        * @class XMLRPCIntParameter An Integer.
-        * @author Curverider Ltd
-        */
-       class XMLRPCIntParameter extends XMLRPCParameter
-       {
-               function __construct($value)
-               {
-                       parent::__construct();
-                       
-                       $this->value = (int)$value; 
-               }
-               
-               function __toString() 
-               {
-                       return "<value><i4>{$this->value}</i4></value>";
-               }
-       }
        
-       /**
-        * @class XMLRPCBoolParameter A boolean.
-        * @author Curverider Ltd
-        */
-       class XMLRPCBoolParameter extends XMLRPCParameter
-       {
-               function __construct($value)
-               {
-                       parent::__construct();
-                       
-                       $this->value = (bool)$value; 
-               }
-               
-               function __toString() 
-               {
-                       $code = ($this->value) ? "1" : "0";
-                       return "<value><boolean>{$code}</boolean></value>";
-               }
-       }
-       
-       /**
-        * @class XMLRPCStringParameter A string.
-        * @author Curverider Ltd
-        */
-       class XMLRPCStringParameter extends XMLRPCParameter
-       {
-               function __construct($value)
-               {
-                       parent::__construct();
-                       
-                       $this->value = $value; 
-               }
-               
-               function __toString() 
-               {
-                       $value = htmlentities($this->value);
-                       return "<value><string>{$value}</string></value>";
-               }
-       }
-       
-       /**
-        * @class XMLRPCDoubleParameter A double precision signed floating point number.
-        * @author Curverider Ltd
-        */
-       class XMLRPCDoubleParameter extends XMLRPCParameter
-       {
-               function __construct($value)
-               {
-                       parent::__construct();
-                       
-                       $this->value = (float)$value; 
-               }
-               
-               function __toString() 
-               {
-                       return "<value><double>{$this->value}</double></value>";
-               }
-       }
-       
-       /**
-        * @class XMLRPCDateParameter An ISO8601 data and time.
-        * @author Curverider Ltd
-        */
-       class XMLRPCDateParameter extends XMLRPCParameter
-       {
-               /**
-                * Construct a date
-                *
-                * @param int $timestamp The unix timestamp, or blank for "now".
-                */
-               function __construct($timestamp = 0)
-               {
-                       parent::__construct();
-                       
-                       $this->value = $timestamp;
-                       if (!$timestamp)
-                               $this->value = time(); 
-               }
-               
-               function __toString() 
-               {
-                       $value = date('c', $this->value);
-                       return "<value><dateTime.iso8601>{$value}</dateTime.iso8601></value>";
-               }
-       }
-       
-       /**
-        * @class XMLRPCBase64Parameter A base 64 encoded blob of binary.
-        * @author Curverider Ltd
-        */
-       class XMLRPCBase64Parameter extends XMLRPCParameter
-       {
-               /**
-                * Construct a base64 encoded block
-                *
-                * @param string $blob Unencoded binary blob
-                */
-               function __construct($blob)
-               {
-                       parent::__construct();
-                       
-                       $this->value = base64_encode($blob);
-               }
-               
-               function __toString() 
-               {
-                       return "<value><base64>{$value}</base64></value>";
-               }
-       }
-       
-       /**
-        * @class XMLRPCStructParameter A structure containing other XMLRPCParameter objects.
-        * @author Curverider Ltd
-        */
-       class XMLRPCStructParameter extends XMLRPCParameter
-       {
-               /**
-                * Construct a struct.
-                *
-                * @param array $parameters Optional associated array of parameters, if not provided then addField must be used.
-                */
-               function __construct($parameters = NULL)
-               {
-                       parent::__construct();
-                       
-                       if (is_array($parameters))
-                       {
-                               foreach ($parameters as $k => $v)
-                                       $this->addField($k, $v);
-                       }
-               }
-               
-               /**
-                * Add a field to the container.
-                *
-                * @param string $name The name of the field.
-                * @param XMLRPCParameter $value The value.
-                */
-               public function addField($name, XMLRPCParameter $value)
-               {
-                       if (!is_array($this->value))
-                               $this->value = array();
-                               
-                       $this->value[$name] = $value;
-               }
-               
-               function __toString() 
-               {
-                       $params = "";
-                       foreach ($this->value as $k => $v)
-                       {
-                               $params .= "<member><name>$k</name>$v</member>";
-                       }
-                       
-                       return "<value><struct>$params</struct></value>";
-               }
-       }
-       
-       /**
-        * @class XMLRPCArrayParameter An array containing other XMLRPCParameter objects.
-        * @author Curverider Ltd
-        */
-       class XMLRPCArrayParameter extends XMLRPCParameter
-       {
-               /**
-                * Construct an array.
-                *
-                * @param array $parameters Optional array of parameters, if not provided then addField must be used.
-                */
-               function __construct($parameters = NULL)
-               {
-                       parent::__construct();
-                       
-                       if (is_array($parameters))
-                       {
-                               foreach ($parameters as $v)
-                                       $this->addField($v);
-                       }
-               }
-               
-               /**
-                * Add a field to the container.
-                *
-                * @param XMLRPCParameter $value The value.
-                */
-               public function addField(XMLRPCParameter $value)
-               {
-                       if (!is_array($this->value))
-                               $this->value = array();
-                               
-                       $this->value[] = $value;
-               }
-               
-               function __toString() 
-               {
-                       $params = "";
-                       foreach ($this->value as $value)
-                       {
-                               $params .= "$value";
-                       }
-                       
-                       return "<array><data>$params</data></array>";
-               }
-       }
-       
-       /**
-        * @class XMLRPCResponse XML-RPC Response. 
-        * @author Curverider Ltd
-        */
-       abstract class XMLRPCResponse
-       {
-               /** An array of parameters */
-               protected $parameters = array();
-               
-               /**
-                * Add a parameter here.
-                *
-                * @param XMLRPCParameter $param The parameter.
-                */
-               public function addParameter(XMLRPCParameter $param)
-               {
-                       if (!is_array($this->parameters))
-                               $this->parameters = array();
-                               
-                       $this->parameters[] = $param;
-               }
-
-               public function addInt($value) { $this->addParameter(new XMLRPCIntParameter($value)); }
-               public function addString($value) { $this->addParameter(new XMLRPCStringParameter($value)); }
-               public function addDouble($value) { $this->addParameter(new XMLRPCDoubleParameter($value)); }
-               public function addBoolean($value) { $this->addParameter(new XMLRPCBoolParameter($value)); }
-       }
-
-       /**
-        * @class XMLRPCSuccessResponse
-        * @author Curverider Ltd
-        */
-       class XMLRPCSuccessResponse extends XMLRPCResponse
-       {
-               /**
-                * Output to XML.
-                */
-               public function __toString()
-               {
-                       $params = "";
-                       foreach ($this->parameters as $param)
-                               $params .= "<param>$param</param>\n";
-                       
-                       return "<methodResponse><params>$params</params></methodResponse>";
-               }
-       }
+       // Response classes ///////////////////////////////////////////////////////////////////////
 
-       /**
-        * @class XMLRPCErrorResponse
-        * @author Curverider Ltd
-        */
-       class XMLRPCErrorResponse extends XMLRPCResponse
-       {               
-               /**
-                * Set the error response and error code.
-                *
-                * @param string $message The message
-                * @param int $code Error code (default = system error as defined by http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php)
-                */
-               function __construct($message, $code = -32400)
-               {
-                       $this->addParameter(
-                               new XMLRPCStructParameter(
-                                       array (
-                                               'faultCode' => new XMLRPCIntParameter($code),
-                                               'faultString' => new XMLRPCStringParameter($message)
-                                       )
-                               )
-                       );
-               }
-               
-               /**
-                * Output to XML.
-                */
-               public function __toString()
-               {
-                       return "<methodResponse><fault><value>{$this->parameters[0]}</value></fault></methodResponse>";
-               }
-       }
-       
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCIntParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCBoolParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCStringParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCDoubleParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCDateParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCBase64Parameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCStructParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCArrayParameter.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCResponse.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCSuccessResponse.php';
+       require_once dirname(dirname(__FILE__)).'/classes/XMLRPCErrorResponse.php';
        
        // Helper functions ///////////////////////////////////////////////////////////////////////
        
index b21fdd92bd05f776cd8968d1b9c35ae2a43bd25c..f9c5985c9cae2f9be63b5cfc1ee5619451bfda36 100644 (file)
@@ -9,25 +9,8 @@
         * @link http://elgg.org/
         */
 
-       /**
-        * @class XmlElement
-        * A class representing an XML element for import.
-        */
-       class XmlElement 
-       {
-               /** The name of the element */
-               public $name;
-               
-               /** The attributes */
-               public $attributes;
-               
-               /** CData */
-               public $content;
-               
-               /** Child elements */
-               public $children;
-       };
-       
+       require_once dirname(dirname(__FILE__)).'/classes/XmlElement.php';
+
        /**
         * This function serialises an object recursively into an XML representation.
         * The function attempts to call $data->export() which expects a stdClass in return, otherwise it will attempt to