--- /dev/null
+<?php\r
+/** The cron exception. */\r
+class CronException extends Exception {}
\ No newline at end of file
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?php\r
+/**\r
+ * Import exception\r
+ *\r
+ * @package Elgg\r
+ * @subpackage Exceptions\r
+ */\r
+class ImportException extends DataFormatException {}
\ No newline at end of file
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
* @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';
/**
* @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
// 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 /////////////////////////////////////////////////////////////////////
* @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';
* @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).
* @link http://elgg.org/
*/
-/** The cron exception. */
-class CronException extends Exception {}
+require_once dirname(dirname(__FILE__)).'/classes/CronException.php';
/**
* Initialisation
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
// @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.
* @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.
* @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.
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.
* @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.
* @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.
* @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.
* @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
* @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.
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.
*/
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.
* @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
/** 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';
/**
* @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.
* @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.
/// 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.
* @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.
*/
// 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 ///////////////////////////////////////////////////////////////////////
* @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