aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorewinslow <ewinslow@36083f99-b078-4883-b0ff-0f9b5a30f544>2010-09-06 02:42:09 +0000
committerewinslow <ewinslow@36083f99-b078-4883-b0ff-0f9b5a30f544>2010-09-06 02:42:09 +0000
commit76dac45ebaf104b312a8527a05424601ca9d520a (patch)
tree7440558a893ebf1d3816829ecbb96c3b0df9b4f0
parent9e8baf614938dfd1687ddce39b409c3c0e5c5753 (diff)
downloadelgg-76dac45ebaf104b312a8527a05424601ca9d520a.tar.gz
elgg-76dac45ebaf104b312a8527a05424601ca9d520a.tar.bz2
Refs #2220: Pulled most classes / interfaces out of lib files (except query.php and exception.php) into "classes" folder. Replaced inline classes with "require_once" statements for now. Ran unit tests to verify functionality before committing.
git-svn-id: http://code.elgg.org/elgg/trunk@6908 36083f99-b078-4883-b0ff-0f9b5a30f544
-rw-r--r--engine/classes/CronException.php3
-rw-r--r--engine/classes/ElggAccess.php32
-rw-r--r--engine/classes/ElggAnnotation.php107
-rw-r--r--engine/classes/ElggCache.php164
-rw-r--r--engine/classes/ElggDiskFilestore.php263
-rw-r--r--engine/classes/ElggEntity.php1210
-rw-r--r--engine/classes/ElggExtender.php252
-rw-r--r--engine/classes/ElggFile.php318
-rw-r--r--engine/classes/ElggFileCache.php164
-rw-r--r--engine/classes/ElggFilestore.php115
-rw-r--r--engine/classes/ElggGroup.php299
-rw-r--r--engine/classes/ElggHMACCache.php94
-rw-r--r--engine/classes/ElggMemcache.php151
-rw-r--r--engine/classes/ElggMetadata.php114
-rw-r--r--engine/classes/ElggObject.php199
-rw-r--r--engine/classes/ElggPlugin.php56
-rw-r--r--engine/classes/ElggRelationship.php287
-rw-r--r--engine/classes/ElggSession.php95
-rw-r--r--engine/classes/ElggSharedMemoryCache.php34
-rw-r--r--engine/classes/ElggSite.php299
-rw-r--r--engine/classes/ElggStaticVariableCache.php66
-rw-r--r--engine/classes/ElggUser.php427
-rw-r--r--engine/classes/ElggWidget.php53
-rw-r--r--engine/classes/ErrorResult.php44
-rw-r--r--engine/classes/ExportException.php9
-rw-r--r--engine/classes/Exportable.php21
-rw-r--r--engine/classes/Friendable.php83
-rw-r--r--engine/classes/GenericResult.php107
-rw-r--r--engine/classes/ImportException.php8
-rw-r--r--engine/classes/Importable.php16
-rw-r--r--engine/classes/Locatable.php36
-rw-r--r--engine/classes/Loggable.php49
-rw-r--r--engine/classes/Notable.php30
-rw-r--r--engine/classes/ODD.php94
-rw-r--r--engine/classes/ODDDocument.php129
-rw-r--r--engine/classes/ODDEntity.php60
-rw-r--r--engine/classes/SuccessResult.php22
-rw-r--r--engine/classes/XMLRPCArrayParameter.php48
-rw-r--r--engine/classes/XMLRPCBase64Parameter.php24
-rw-r--r--engine/classes/XMLRPCBoolParameter.php20
-rw-r--r--engine/classes/XMLRPCCall.php60
-rw-r--r--engine/classes/XMLRPCDateParameter.php27
-rw-r--r--engine/classes/XMLRPCDoubleParameter.php19
-rw-r--r--engine/classes/XMLRPCErrorResponse.php34
-rw-r--r--engine/classes/XMLRPCIntParameter.php19
-rw-r--r--engine/classes/XMLRPCParameter.php12
-rw-r--r--engine/classes/XMLRPCResponse.php29
-rw-r--r--engine/classes/XMLRPCStringParameter.php20
-rw-r--r--engine/classes/XMLRPCStructParameter.php49
-rw-r--r--engine/classes/XMLRPCSuccessResponse.php19
-rw-r--r--engine/classes/XmlElement.php19
-rw-r--r--engine/lib/access.php32
-rw-r--r--engine/lib/annotations.php113
-rw-r--r--engine/lib/api.php272
-rw-r--r--engine/lib/cache.php430
-rw-r--r--engine/lib/calendar.php30
-rw-r--r--engine/lib/cron.php3
-rw-r--r--engine/lib/elgglib.php83
-rw-r--r--engine/lib/entities.php1210
-rw-r--r--engine/lib/export.php57
-rw-r--r--engine/lib/extender.php251
-rw-r--r--engine/lib/filestore.php697
-rw-r--r--engine/lib/group.php298
-rw-r--r--engine/lib/location.php35
-rw-r--r--engine/lib/memcache.php151
-rw-r--r--engine/lib/metadata.php113
-rw-r--r--engine/lib/objects.php198
-rw-r--r--engine/lib/opendd.php284
-rw-r--r--engine/lib/plugins.php56
-rw-r--r--engine/lib/relationships.php287
-rw-r--r--engine/lib/sessions.php95
-rw-r--r--engine/lib/sites.php299
-rw-r--r--engine/lib/system_log.php49
-rw-r--r--engine/lib/users.php427
-rw-r--r--engine/lib/widgets.php52
-rw-r--r--engine/lib/xml-rpc.php389
-rw-r--r--engine/lib/xml.php21
77 files changed, 5964 insertions, 5877 deletions
diff --git a/engine/classes/CronException.php b/engine/classes/CronException.php
new file mode 100644
index 000000000..3720c2c59
--- /dev/null
+++ b/engine/classes/CronException.php
@@ -0,0 +1,3 @@
+<?php
+/** The cron exception. */
+class CronException extends Exception {} \ No newline at end of file
diff --git a/engine/classes/ElggAccess.php b/engine/classes/ElggAccess.php
new file mode 100644
index 000000000..57cceef03
--- /dev/null
+++ b/engine/classes/ElggAccess.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * 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;
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggAnnotation.php b/engine/classes/ElggAnnotation.php
new file mode 100644
index 000000000..fe85ca082
--- /dev/null
+++ b/engine/classes/ElggAnnotation.php
@@ -0,0 +1,107 @@
+<?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 ////////////////////////////////////////////////////////////
+
+ /**
+ * 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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggCache.php b/engine/classes/ElggCache.php
new file mode 100644
index 000000000..c59285467
--- /dev/null
+++ b/engine/classes/ElggCache.php
@@ -0,0 +1,164 @@
+<?php
+
+/**
+ * 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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggDiskFilestore.php b/engine/classes/ElggDiskFilestore.php
new file mode 100644
index 000000000..6b0fa2554
--- /dev/null
+++ b/engine/classes/ElggDiskFilestore.php
@@ -0,0 +1,263 @@
+<?php
+/**
+ * @class ElggDiskFilestore
+ * This class uses disk storage to save data.
+ * @author Curverider Ltd
+ */
+class ElggDiskFilestore extends ElggFilestore {
+ /**
+ * Directory root.
+ */
+ private $dir_root;
+
+ /**
+ * Default depth of file directory matrix
+ */
+ private $matrix_depth = 5;
+
+ /**
+ * Construct a disk filestore using the given directory root.
+ *
+ * @param string $directory_root Root directory, must end in "/"
+ */
+ public function __construct($directory_root = "") {
+ global $CONFIG;
+
+ if ($directory_root) {
+ $this->dir_root = $directory_root;
+ } else {
+ $this->dir_root = $CONFIG->dataroot;
+ }
+ }
+
+ public function open(ElggFile $file, $mode) {
+ $fullname = $this->getFilenameOnFilestore($file);
+
+ // Split into path and name
+ $ls = strrpos($fullname,"/");
+ if ($ls===false) {
+ $ls = 0;
+ }
+
+ $path = substr($fullname, 0, $ls);
+ $name = substr($fullname, $ls);
+
+ // Try and create the directory
+ try {
+ $this->make_directory_root($path);
+ } catch (Exception $e) {
+
+ }
+
+ if (($mode!='write') && (!file_exists($fullname))) {
+ return false;
+ }
+
+ switch ($mode) {
+ case "read" :
+ $mode = "rb";
+ break;
+ case "write" :
+ $mode = "w+b";
+ break;
+ case "append" :
+ $mode = "a+b";
+ break;
+ default:
+ throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode));
+ }
+
+ return fopen($fullname, $mode);
+
+ }
+
+ public function write($f, $data) {
+ return fwrite($f, $data);
+ }
+
+ public function read($f, $length, $offset = 0) {
+ if ($offset) {
+ $this->seek($f, $offset);
+ }
+
+ return fread($f, $length);
+ }
+
+ public function close($f) {
+ return fclose($f);
+ }
+
+ public function delete(ElggFile $file) {
+ $filename = $this->getFilenameOnFilestore($file);
+ if (file_exists($filename)) {
+ return unlink($filename);
+ } else {
+ return true;
+ }
+ }
+
+ public function seek($f, $position) {
+ return fseek($f, $position);
+ }
+
+ public function tell($f) {
+ return ftell($f);
+ }
+
+ public function eof($f) {
+ return feof($f);
+ }
+
+ public function getFileSize(ElggFile $file) {
+ return filesize($this->getFilenameOnFilestore($file));
+ }
+
+ public function getFilenameOnFilestore(ElggFile $file) {
+ $owner = $file->getOwnerEntity();
+ if (!$owner) {
+ $owner = get_loggedin_user();
+ }
+
+ if ((!$owner) || (!$owner->username)) {
+ throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:MissingOwner'), $file->getFilename(), $file->guid));
+ }
+
+ return $this->dir_root . $this->make_file_matrix($owner->guid) . $file->getFilename();
+ }
+
+ public function grabFile(ElggFile $file) {
+ return file_get_contents($file->getFilenameOnFilestore());
+ }
+
+ public function exists(ElggFile $file) {
+ return file_exists($this->getFilenameOnFilestore($file));
+ }
+
+ public function getSize($prefix,$container_guid) {
+ if ($container_guid) {
+ return get_dir_size($this->dir_root.$this->make_file_matrix($container_guid).$prefix);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Make the directory root.
+ *
+ * @param string $dirroot
+ */
+ protected function make_directory_root($dirroot) {
+ if (!file_exists($dirroot)) {
+ if (!@mkdir($dirroot, 0700, true)) {
+ throw new IOException(sprintf(elgg_echo('IOException:CouldNotMake'), $dirroot));
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Multibyte string tokeniser.
+ *
+ * Splits a string into an array. Will fail safely if mbstring is not installed (although this may still
+ * not handle .
+ *
+ * @param string $string String
+ * @param string $charset The charset, defaults to UTF8
+ * @return array
+ */
+ private function mb_str_split($string, $charset = 'UTF8') {
+ if (is_callable('mb_substr')) {
+ $length = mb_strlen($string);
+ $array = array();
+
+ while ($length) {
+ $array[] = mb_substr($string, 0, 1, $charset);
+ $string = mb_substr($string, 1, $length, $charset);
+
+ $length = mb_strlen($string);
+ }
+
+ return $array;
+ } else {
+ return str_split($string);
+ }
+
+ return false;
+ }
+
+ /**
+ * Construct the filename matrix.
+ *
+ * @param int | string $identifier
+ * @return str
+ */
+ protected function make_file_matrix($identifier) {
+ if (is_numeric($identifier)) {
+ return $this->user_file_matrix($identifier);
+ }
+
+ return $this->deprecated_file_matrix($identifier);
+ }
+
+ /**
+ * Construct the filename matrix with user info
+ *
+ * This method will generate a matrix using the entity's creation time and
+ * unique guid. This is intended only to determine a user's data directory.
+ *
+ * @param int $guid
+ * @return str
+ */
+ protected function user_file_matrix($guid) {
+ // lookup the entity
+ $user = get_entity($guid);
+ if ($user->type != 'user')
+ {
+ // only to be used for user directories
+ return FALSE;
+ }
+
+ if (!$user->time_created) {
+ // fall back to deprecated method
+ return $this->deprecated_file_matrix($user->username);
+ }
+
+ $time_created = date('Y/m/d', $user->time_created);
+ return "$time_created/$user->guid/";
+ }
+
+ /**
+ * Construct the filename matrix using a string
+ *
+ * Particularly, this is used with a username to generate the file storage
+ * location.
+ *
+ * @deprecated for user directories: use user_file_matrix() instead.
+ *
+ * @param str $filename
+ * @return str
+ */
+ protected function deprecated_file_matrix($filename) {
+ // throw a warning for using deprecated method
+ $error = 'Deprecated use of ElggDiskFilestore::make_file_matrix. ';
+ $error .= 'Username passed instead of guid.';
+ elgg_log($error, WARNING);
+
+ $user = new ElggUser($filename);
+ return $this->user_file_matrix($user->guid);
+ }
+
+ public function getParameters() {
+ return array("dir_root" => $this->dir_root);
+ }
+
+ public function setParameters(array $parameters) {
+ if (isset($parameters['dir_root'])) {
+ $this->dir_root = $parameters['dir_root'];
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php
new file mode 100644
index 000000000..f0d58d1bd
--- /dev/null
+++ b/engine/classes/ElggEntity.php
@@ -0,0 +1,1210 @@
+<?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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggExtender.php b/engine/classes/ElggExtender.php
new file mode 100644
index 000000000..ec7a21f35
--- /dev/null
+++ b/engine/classes/ElggExtender.php
@@ -0,0 +1,252 @@
+<?php
+
+/**
+ * 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);
+ }
+}
diff --git a/engine/classes/ElggFile.php b/engine/classes/ElggFile.php
new file mode 100644
index 000000000..68ed2f2f2
--- /dev/null
+++ b/engine/classes/ElggFile.php
@@ -0,0 +1,318 @@
+<?php
+
+/**
+ * @class ElggFile
+ * This class represents a physical file.
+ *
+ * Usage:
+ * Create a new ElggFile object and specify a filename, and optionally a FileStore (if one isn't specified
+ * then the default is assumed.
+ *
+ * Open the file using the appropriate mode, and you will be able to read and write to the file.
+ *
+ * Optionally, you can also call the file's save() method, this will turn the file into an entity in the
+ * system and permit you to do things like attach tags to the file etc. This is not done automatically since
+ * there are many occasions where you may want access to file data on datastores using the ElggFile interface
+ * but do not want to create an Entity reference to it in the system (temporary files for example).
+ *
+ * @author Curverider Ltd
+ */
+class ElggFile extends ElggObject {
+ /** Filestore */
+ private $filestore;
+
+ /** File handle used to identify this file in a filestore. Created by open. */
+ private $handle;
+
+ protected function initialise_attributes() {
+ parent::initialise_attributes();
+
+ $this->attributes['subtype'] = "file";
+ }
+
+ public function __construct($guid = null) {
+ parent::__construct($guid);
+
+ // Set default filestore
+ $this->filestore = $this->getFilestore();
+ }
+
+ /**
+ * Set the filename of this file.
+ *
+ * @param string $name The filename.
+ */
+ public function setFilename($name) {
+ $this->filename = $name;
+ }
+
+ /**
+ * Return the filename.
+ */
+ public function getFilename() {
+ return $this->filename;
+ }
+
+ /**
+ * Return the filename of this file as it is/will be stored on the filestore, which may be different
+ * to the filename.
+ */
+ public function getFilenameOnFilestore() {
+ return $this->filestore->getFilenameOnFilestore($this);
+ }
+
+ /*
+ * Return the size of the filestore associated with this file
+ *
+ */
+ public function getFilestoreSize($prefix='',$container_guid=0) {
+ if (!$container_guid) {
+ $container_guid = $this->container_guid;
+ }
+ $fs = $this->getFilestore();
+ return $fs->getSize($prefix,$container_guid);
+ }
+
+ /**
+ * Get the mime type of the file.
+ */
+ public function getMimeType() {
+ if ($this->mimetype) {
+ return $this->mimetype;
+ }
+
+ // @todo Guess mimetype if not here
+ }
+
+ /**
+ * Set the mime type of the file.
+ *
+ * @param $mimetype The mimetype
+ */
+ public function setMimeType($mimetype) {
+ return $this->mimetype = $mimetype;
+ }
+
+ /**
+ * Set the optional file description.
+ *
+ * @param string $description The description.
+ */
+ public function setDescription($description) {
+ $this->description = $description;
+ }
+
+ /**
+ * Open the file with the given mode
+ *
+ * @param string $mode Either read/write/append
+ */
+ public function open($mode) {
+ if (!$this->getFilename()) {
+ throw new IOException(elgg_echo('IOException:MissingFileName'));
+ }
+
+ // See if file has already been saved
+ // seek on datastore, parameters and name?
+
+ // Sanity check
+ if (
+ ($mode!="read") &&
+ ($mode!="write") &&
+ ($mode!="append")
+ ) {
+ throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode));
+ }
+
+ // Get the filestore
+ $fs = $this->getFilestore();
+
+ // Ensure that we save the file details to object store
+ //$this->save();
+
+ // Open the file handle
+ $this->handle = $fs->open($this, $mode);
+
+ return $this->handle;
+ }
+
+ /**
+ * Write some data.
+ *
+ * @param string $data The data
+ */
+ public function write($data) {
+ $fs = $this->getFilestore();
+
+ return $fs->write($this->handle, $data);
+ }
+
+ /**
+ * Read some data.
+ *
+ * @param int $length Amount to read.
+ * @param int $offset The offset to start from.
+ */
+ public function read($length, $offset = 0) {
+ $fs = $this->getFilestore();
+
+ return $fs->read($this->handle, $length, $offset);
+ }
+
+ /**
+ * Gets the full contents of this file.
+ *
+ * @return mixed The file contents.
+ */
+ public function grabFile() {
+ $fs = $this->getFilestore();
+ return $fs->grabFile($this);
+ }
+
+ /**
+ * Close the file and commit changes
+ */
+ public function close() {
+ $fs = $this->getFilestore();
+
+ if ($fs->close($this->handle)) {
+ $this->handle = NULL;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Delete this file.
+ */
+ public function delete() {
+ $fs = $this->getFilestore();
+ if ($fs->delete($this)) {
+ return parent::delete();
+ }
+ }
+
+ /**
+ * Seek a position in the file.
+ *
+ * @param int $position
+ */
+ public function seek($position) {
+ $fs = $this->getFilestore();
+
+ return $fs->seek($this->handle, $position);
+ }
+
+ /**
+ * Return the current position of the file.
+ *
+ * @return int The file position
+ */
+ public function tell() {
+ $fs = $this->getFilestore();
+
+ return $fs->tell($this->handle);
+ }
+
+ /**
+ * Return the size of the file in bytes.
+ */
+ public function size() {
+ return $this->filestore->getFileSize($this);
+ }
+
+ /**
+ * Return a boolean value whether the file handle is at the end of the file
+ */
+ public function eof() {
+ $fs = $this->getFilestore();
+
+ return $fs->eof($this->handle);
+ }
+
+ public function exists() {
+ $fs = $this->getFilestore();
+
+ return $fs->exists($this);
+ }
+
+ /**
+ * Set a filestore.
+ *
+ * @param ElggFilestore $filestore The file store.
+ */
+ public function setFilestore(ElggFilestore $filestore) {
+ $this->filestore = $filestore;
+ }
+
+ /**
+ * Return a filestore suitable for saving this file.
+ * This filestore is either a pre-registered filestore, a filestore loaded from metatags saved
+ * along side this file, or the system default.
+ */
+ protected function getFilestore() {
+ // Short circuit if already set.
+ if ($this->filestore) {
+ return $this->filestore;
+ }
+
+ // If filestore meta set then retrieve filestore
+ // @todo Better way of doing this?
+ $metas = get_metadata_for_entity($this->guid);
+ $parameters = array();
+ if (is_array($metas)) {
+ foreach ($metas as $meta) {
+ if (strpos($meta->name, "filestore::")!==false) {
+ // Filestore parameter tag
+ $comp = explode("::", $meta->name);
+ $name = $comp[1];
+
+ $parameters[$name] = $meta->value;
+ }
+ }
+ }
+
+ if (isset($parameters['filestore'])) {
+ if (!class_exists($parameters['filestore'])) {
+ $msg = sprintf(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile'),
+ $parameters['filestore'],
+ $this->guid);
+ throw new ClassNotFoundException($msg);
+ }
+
+ // Create new filestore object
+ $this->filestore = new $parameters['filestore']();
+
+ $this->filestore->setParameters($parameters);
+ } else {
+ // @todo - should we log error if filestore not set
+ }
+
+
+ // if still nothing then set filestore to default
+ if (!$this->filestore) {
+ $this->filestore = get_default_filestore();
+ }
+
+ return $this->filestore;
+ }
+
+ public function save() {
+ if (!parent::save()) {
+ return false;
+ }
+
+ // Save datastore metadata
+ $params = $this->filestore->getParameters();
+ foreach ($params as $k => $v) {
+ $this->setMetaData("filestore::$k", $v);
+ }
+
+ // Now make a note of the filestore class
+ $this->setMetaData("filestore::filestore", get_class($this->filestore));
+
+ return true;
+ }
+}
diff --git a/engine/classes/ElggFileCache.php b/engine/classes/ElggFileCache.php
new file mode 100644
index 000000000..b8989a935
--- /dev/null
+++ b/engine/classes/ElggFileCache.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * 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
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggFilestore.php b/engine/classes/ElggFilestore.php
new file mode 100644
index 000000000..3311842a9
--- /dev/null
+++ b/engine/classes/ElggFilestore.php
@@ -0,0 +1,115 @@
+<?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);
+} \ No newline at end of file
diff --git a/engine/classes/ElggGroup.php b/engine/classes/ElggGroup.php
new file mode 100644
index 000000000..9713ca39e
--- /dev/null
+++ b/engine/classes/ElggGroup.php
@@ -0,0 +1,299 @@
+<?php
+
+/**
+ * @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',
+ ));
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggHMACCache.php b/engine/classes/ElggHMACCache.php
new file mode 100644
index 000000000..8c50d7dfb
--- /dev/null
+++ b/engine/classes/ElggHMACCache.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * 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");
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggMemcache.php b/engine/classes/ElggMemcache.php
new file mode 100644
index 000000000..5e898c26a
--- /dev/null
+++ b/engine/classes/ElggMemcache.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * 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
+ }
+}
diff --git a/engine/classes/ElggMetadata.php b/engine/classes/ElggMetadata.php
new file mode 100644
index 000000000..631b73c8f
--- /dev/null
+++ b/engine/classes/ElggMetadata.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * 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);
+ }
+
+ 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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggObject.php b/engine/classes/ElggObject.php
new file mode 100644
index 000000000..af67ef3f6
--- /dev/null
+++ b/engine/classes/ElggObject.php
@@ -0,0 +1,199 @@
+<?php
+
+/**
+ * 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',
+ ));
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php
new file mode 100644
index 000000000..921665f4d
--- /dev/null
+++ b/engine/classes/ElggPlugin.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @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;
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggRelationship.php b/engine/classes/ElggRelationship.php
new file mode 100644
index 000000000..4d14941a9
--- /dev/null
+++ b/engine/classes/ElggRelationship.php
@@ -0,0 +1,287 @@
+<?php
+
+/**
+ * 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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggSession.php b/engine/classes/ElggSession.php
new file mode 100644
index 000000000..874502579
--- /dev/null
+++ b/engine/classes/ElggSession.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * 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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggSharedMemoryCache.php b/engine/classes/ElggSharedMemoryCache.php
new file mode 100644
index 000000000..cae78943e
--- /dev/null
+++ b/engine/classes/ElggSharedMemoryCache.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * 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;
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggSite.php b/engine/classes/ElggSite.php
new file mode 100644
index 000000000..77e26372e
--- /dev/null
+++ b/engine/classes/ElggSite.php
@@ -0,0 +1,299 @@
+<?php
+/**
+ * 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;
+ }
+}
diff --git a/engine/classes/ElggStaticVariableCache.php b/engine/classes/ElggStaticVariableCache.php
new file mode 100644
index 000000000..0038862bd
--- /dev/null
+++ b/engine/classes/ElggStaticVariableCache.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * 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();
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggUser.php b/engine/classes/ElggUser.php
new file mode 100644
index 000000000..001da19ed
--- /dev/null
+++ b/engine/classes/ElggUser.php
@@ -0,0 +1,427 @@
+<?php
+/**
+ * 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);
+ }
+}
diff --git a/engine/classes/ElggWidget.php b/engine/classes/ElggWidget.php
new file mode 100644
index 000000000..dbca3c369
--- /dev/null
+++ b/engine/classes/ElggWidget.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * 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;
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ErrorResult.php b/engine/classes/ErrorResult.php
new file mode 100644
index 000000000..5fc6c88b6
--- /dev/null
+++ b/engine/classes/ErrorResult.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * 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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ExportException.php b/engine/classes/ExportException.php
new file mode 100644
index 000000000..dc5c686b7
--- /dev/null
+++ b/engine/classes/ExportException.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Export exception
+ *
+ * @package Elgg
+ * @subpackage Exceptions
+ *
+ */
+class ExportException extends DataFormatException {} \ No newline at end of file
diff --git a/engine/classes/Exportable.php b/engine/classes/Exportable.php
new file mode 100644
index 000000000..da5a7cc54
--- /dev/null
+++ b/engine/classes/Exportable.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * 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();
+} \ No newline at end of file
diff --git a/engine/classes/Friendable.php b/engine/classes/Friendable.php
new file mode 100644
index 000000000..d400bd092
--- /dev/null
+++ b/engine/classes/Friendable.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * An interface for objects that behave as elements within a social network that have a profile.
+ *
+ */
+interface Friendable {
+ /**
+ * Adds a user as a friend
+ *
+ * @param int $friend_guid The GUID of the user to add
+ */
+ public function addFriend($friend_guid);
+
+ /**
+ * Removes a user as a friend
+ *
+ * @param int $friend_guid The GUID of the user to remove
+ */
+ public function removeFriend($friend_guid);
+
+ /**
+ * Determines whether or not the current user is a friend of this entity
+ *
+ */
+ public function isFriend();
+
+ /**
+ * Determines whether or not this entity is friends with a particular entity
+ *
+ * @param int $user_guid The GUID of the entity this entity may or may not be friends with
+ */
+ public function isFriendsWith($user_guid);
+
+ /**
+ * Determines whether or not a foreign entity has made this one a friend
+ *
+ * @param int $user_guid The GUID of the foreign entity
+ */
+ public function isFriendOf($user_guid);
+
+ /**
+ * Returns this entity's friends
+ *
+ * @param string $subtype The subtype of entity to return
+ * @param int $limit The number of entities to return
+ * @param int $offset Indexing offset
+ */
+ public function getFriends($subtype = "", $limit = 10, $offset = 0);
+
+ /**
+ * Returns entities that have made this entity a friend
+ *
+ * @param string $subtype The subtype of entity to return
+ * @param int $limit The number of entities to return
+ * @param int $offset Indexing offset
+ */
+ public function getFriendsOf($subtype = "", $limit = 10, $offset = 0);
+
+ /**
+ * Returns objects in this entity's container
+ *
+ * @param string $subtype The subtype of entity to return
+ * @param int $limit The number of entities to return
+ * @param int $offset Indexing offset
+ */
+ public function getObjects($subtype="", $limit = 10, $offset = 0);
+
+ /**
+ * Returns objects in the containers of this entity's friends
+ *
+ * @param string $subtype The subtype of entity to return
+ * @param int $limit The number of entities to return
+ * @param int $offset Indexing offset
+ */
+ public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0);
+
+ /**
+ * Returns the number of object entities in this entity's container
+ *
+ * @param string $subtype The subtype of entity to count
+ */
+ public function countObjects($subtype = "");
+} \ No newline at end of file
diff --git a/engine/classes/GenericResult.php b/engine/classes/GenericResult.php
new file mode 100644
index 000000000..8bccd77f2
--- /dev/null
+++ b/engine/classes/GenericResult.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * 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;
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ImportException.php b/engine/classes/ImportException.php
new file mode 100644
index 000000000..fd86fc23c
--- /dev/null
+++ b/engine/classes/ImportException.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Import exception
+ *
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class ImportException extends DataFormatException {} \ No newline at end of file
diff --git a/engine/classes/Importable.php b/engine/classes/Importable.php
new file mode 100644
index 000000000..775319cb7
--- /dev/null
+++ b/engine/classes/Importable.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * 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);
+}
diff --git a/engine/classes/Locatable.php b/engine/classes/Locatable.php
new file mode 100644
index 000000000..5f52d8eab
--- /dev/null
+++ b/engine/classes/Locatable.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * 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();
+} \ No newline at end of file
diff --git a/engine/classes/Loggable.php b/engine/classes/Loggable.php
new file mode 100644
index 000000000..e12641410
--- /dev/null
+++ b/engine/classes/Loggable.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * 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();
+} \ No newline at end of file
diff --git a/engine/classes/Notable.php b/engine/classes/Notable.php
new file mode 100644
index 000000000..3c133d494
--- /dev/null
+++ b/engine/classes/Notable.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * 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();
+} \ No newline at end of file
diff --git a/engine/classes/ODD.php b/engine/classes/ODD.php
new file mode 100644
index 000000000..a4118ee15
--- /dev/null
+++ b/engine/classes/ODD.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * 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";
+ }
+}
diff --git a/engine/classes/ODDDocument.php b/engine/classes/ODDDocument.php
new file mode 100644
index 000000000..0c8731a75
--- /dev/null
+++ b/engine/classes/ODDDocument.php
@@ -0,0 +1,129 @@
+<?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;
+ }
+}
diff --git a/engine/classes/ODDEntity.php b/engine/classes/ODDEntity.php
new file mode 100644
index 000000000..30da5f37f
--- /dev/null
+++ b/engine/classes/ODDEntity.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * 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"; }
+} \ No newline at end of file
diff --git a/engine/classes/SuccessResult.php b/engine/classes/SuccessResult.php
new file mode 100644
index 000000000..db5769d58
--- /dev/null
+++ b/engine/classes/SuccessResult.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * 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);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCArrayParameter.php b/engine/classes/XMLRPCArrayParameter.php
new file mode 100644
index 000000000..600f5d9a7
--- /dev/null
+++ b/engine/classes/XMLRPCArrayParameter.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @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>";
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCBase64Parameter.php b/engine/classes/XMLRPCBase64Parameter.php
new file mode 100644
index 000000000..b32e7f3da
--- /dev/null
+++ b/engine/classes/XMLRPCBase64Parameter.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @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>";
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCBoolParameter.php b/engine/classes/XMLRPCBoolParameter.php
new file mode 100644
index 000000000..c2714ceff
--- /dev/null
+++ b/engine/classes/XMLRPCBoolParameter.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @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>";
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCCall.php b/engine/classes/XMLRPCCall.php
new file mode 100644
index 000000000..09e8e6d6d
--- /dev/null
+++ b/engine/classes/XMLRPCCall.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @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;
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCDateParameter.php b/engine/classes/XMLRPCDateParameter.php
new file mode 100644
index 000000000..47ba88c0f
--- /dev/null
+++ b/engine/classes/XMLRPCDateParameter.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @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>";
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCDoubleParameter.php b/engine/classes/XMLRPCDoubleParameter.php
new file mode 100644
index 000000000..64cbdff91
--- /dev/null
+++ b/engine/classes/XMLRPCDoubleParameter.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @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>";
+ }
+}
diff --git a/engine/classes/XMLRPCErrorResponse.php b/engine/classes/XMLRPCErrorResponse.php
new file mode 100644
index 000000000..4dfcfafea
--- /dev/null
+++ b/engine/classes/XMLRPCErrorResponse.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @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>";
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCIntParameter.php b/engine/classes/XMLRPCIntParameter.php
new file mode 100644
index 000000000..2305a66a7
--- /dev/null
+++ b/engine/classes/XMLRPCIntParameter.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @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>";
+ }
+}
diff --git a/engine/classes/XMLRPCParameter.php b/engine/classes/XMLRPCParameter.php
new file mode 100644
index 000000000..f9e04a073
--- /dev/null
+++ b/engine/classes/XMLRPCParameter.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * @class XMLRPCParameter Superclass for all RPC parameters.
+ * @author Curverider Ltd
+ */
+abstract class XMLRPCParameter
+{
+ protected $value;
+
+ function __construct() { }
+
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCResponse.php b/engine/classes/XMLRPCResponse.php
new file mode 100644
index 000000000..1dea8d682
--- /dev/null
+++ b/engine/classes/XMLRPCResponse.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @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)); }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCStringParameter.php b/engine/classes/XMLRPCStringParameter.php
new file mode 100644
index 000000000..bf9097747
--- /dev/null
+++ b/engine/classes/XMLRPCStringParameter.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @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>";
+ }
+}
diff --git a/engine/classes/XMLRPCStructParameter.php b/engine/classes/XMLRPCStructParameter.php
new file mode 100644
index 000000000..326a82804
--- /dev/null
+++ b/engine/classes/XMLRPCStructParameter.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @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>";
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XMLRPCSuccessResponse.php b/engine/classes/XMLRPCSuccessResponse.php
new file mode 100644
index 000000000..cffa64439
--- /dev/null
+++ b/engine/classes/XMLRPCSuccessResponse.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @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>";
+ }
+} \ No newline at end of file
diff --git a/engine/classes/XmlElement.php b/engine/classes/XmlElement.php
new file mode 100644
index 000000000..17e3151a8
--- /dev/null
+++ b/engine/classes/XmlElement.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @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;
+}; \ No newline at end of file
diff --git a/engine/lib/access.php b/engine/lib/access.php
index c7a87ced5..4155fc408 100644
--- a/engine/lib/access.php
+++ b/engine/lib/access.php
@@ -11,37 +11,7 @@
* @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';
/**
diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php
index 806e3699f..3c8bb2aad 100644
--- a/engine/lib/annotations.php
+++ b/engine/lib/annotations.php
@@ -9,118 +9,9 @@
* @link http://elgg.org/
*/
-/**
- * Include the ElggExtender superclass
- *
- */
-require_once('extender.php');
-
-/**
- * ElggAnnotation
- *
- * An annotation is similar to metadata.
- * Each entity can have more than one of each type of annotation.
- *
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd <info@elgg.com>
- */
-class ElggAnnotation extends ElggExtender {
-
- /**
- * Construct a new annotation, optionally from a given id value or db object.
- *
- * @param mixed $id
- */
- function __construct($id = null) {
- $this->attributes = array();
-
- if (!empty($id)) {
- if ($id instanceof stdClass) {
- $annotation = $id;
- } else {
- $annotation = get_annotation($id);
- }
-
- if ($annotation) {
- $objarray = (array) $annotation;
-
- foreach($objarray as $key => $value) {
- $this->attributes[$key] = $value;
- }
-
- $this->attributes['type'] = "annotation";
- }
- }
- }
-
- /**
- * Class member get overloading
- *
- * @param string $name
- * @return mixed
- */
- function __get($name) {
- return $this->get($name);
- }
-
- /**
- * Class member set overloading
- *
- * @param string $name
- * @param mixed $value
- * @return void
- */
- function __set($name, $value) {
- return $this->set($name, $value);
- }
-
- /**
- * Save this instance
- *
- * @return int an object id
- */
- function save() {
- if ($this->id > 0) {
- return update_annotation($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
- } else {
- $this->id = create_annotation($this->entity_guid, $this->name, $this->value,
- $this->value_type, $this->owner_guid, $this->access_id);
-
- if (!$this->id) {
- throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));
- }
- return $this->id;
- }
- }
-
- /**
- * Delete the annotation.
- */
- function delete() {
- return delete_annotation($this->id);
- }
-
- /**
- * Get a url for this annotation.
- *
- * @return string
- */
- public function getURL() {
- return get_annotation_url($this->id);
- }
-
- // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
+require_once 'extender.php';
- /**
- * For a given ID, return the object associated with it.
- * This is used by the river functionality primarily.
- * This is useful for checking access permissions etc on objects.
- */
- public function getObjectFromID($id) {
- return get_annotation($id);
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggAnnotation.php';
/**
* Convert a database row to a new ElggAnnotation
diff --git a/engine/lib/api.php b/engine/lib/api.php
index 823774108..7a6fd54af 100644
--- a/engine/lib/api.php
+++ b/engine/lib/api.php
@@ -11,274 +11,10 @@
// 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 /////////////////////////////////////////////////////////////////////
diff --git a/engine/lib/cache.php b/engine/lib/cache.php
index e227ba770..3e8a75d7b 100644
--- a/engine/lib/cache.php
+++ b/engine/lib/cache.php
@@ -9,429 +9,7 @@
* @link http://elgg.org/
*/
-/**
- * ElggCache The elgg cache superclass.
- * This defines the interface for a cache (wherever that cache is stored).
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage API
- */
-abstract class ElggCache implements
- // Override for array access
- ArrayAccess {
- /**
- * Variables for the cache object.
- *
- * @var array
- */
- private $variables;
-
- /**
- * Set the constructor.
- */
- function __construct() {
- $this->variables = array();
- }
-
- /**
- * Set a cache variable.
- *
- * @param string $variable
- * @param string $value
- */
- public function set_variable($variable, $value) {
- if (!is_array($this->variables)) {
- $this->variables = array();
- }
-
- $this->variables[$variable] = $value;
- }
-
- /**
- * Get variables for this cache.
- *
- * @param string $variable
- * @return mixed The variable or null;
- */
- public function get_variable($variable) {
- if (isset($this->variables[$variable])) {
- return $this->variables[$variable];
- }
-
- return null;
- }
-
- /**
- * Class member get overloading, returning key using $this->load defaults.
- *
- * @param string $key
- * @return mixed
- */
- function __get($key) {
- return $this->load($key);
- }
-
- /**
- * Class member set overloading, setting a key using $this->save defaults.
- *
- * @param string $key
- * @param mixed $value
- * @return mixed
- */
- function __set($key, $value) {
- return $this->save($key, $value);
- }
-
- /**
- * Supporting isset, using $this->load() with default values.
- *
- * @param string $key The name of the attribute or metadata.
- * @return bool
- */
- function __isset($key) {
- return (bool)$this->load($key);
- }
-
- /**
- * Supporting unsetting of magic attributes.
- *
- * @param string $key The name of the attribute or metadata.
- */
- function __unset($key) {
- return $this->delete($key);
- }
-
- /**
- * Save data in a cache.
- *
- * @param string $key
- * @param string $data
- * @return bool
- */
- abstract public function save($key, $data);
-
- /**
- * Load data from the cache using a given key.
- *
- * @param string $key
- * @param int $offset
- * @param int $limit
- * @return mixed The stored data or false.
- */
- abstract public function load($key, $offset = 0, $limit = null);
-
- /**
- * Invalidate a key
- *
- * @param string $key
- * @return bool
- */
- abstract public function delete($key);
-
- /**
- * Clear out all the contents of the cache.
- *
- */
- abstract public function clear();
-
- /**
- * Add a key only if it doesn't already exist.
- * Implemented simply here, if you extend this class and your caching engine provides a better way then
- * override this accordingly.
- *
- * @param string $key
- * @param string $data
- * @return bool
- */
- public function add($key, $data) {
- if (!isset($this[$key])) {
- return $this->save($key, $data);
- }
-
- return false;
- }
-
- // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
- function offsetSet($key, $value) {
- $this->save($key, $value);
- }
-
- function offsetGet($key) {
- return $this->load($key);
- }
-
- function offsetUnset($key) {
- if ( isset($this->key) ) {
- unset($this->key);
- }
- }
-
- function offsetExists($offset) {
- return isset($this->$offset);
- }
-}
-
-/**
- * Shared memory cache description.
- * Extends ElggCache with functions useful to shared memory style caches (static variables, memcache etc)
- */
-abstract class ElggSharedMemoryCache extends ElggCache {
- /**
- * Namespace variable used to keep various bits of the cache
- * separate.
- *
- * @var string
- */
- private $namespace;
-
- /**
- * Set the namespace of this cache.
- * This is useful for cache types (like memcache or static variables) where there is one large
- * flat area of memory shared across all instances of the cache.
- *
- * @param string $namespace
- */
- public function setNamespace($namespace = "default") {
- $this->namespace = $namespace;
- }
-
- /**
- * Get the namespace currently defined.
- *
- * @return string
- */
- public function getNamespace() {
- return $this->namespace;
- }
-}
-
-/**
- * ElggStaticVariableCache
- * Dummy cache which stores values in a static array. Using this makes future replacements to other caching back
- * ends (eg memcache) much easier.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage API
- */
-class ElggStaticVariableCache extends ElggSharedMemoryCache {
- /**
- * The cache.
- *
- * @var unknown_type
- */
- private static $__cache;
-
- /**
- * Create the variable cache.
- *
- * This function creates a variable cache in a static variable in memory, optionally with a given namespace (to avoid overlap).
- *
- * @param string $namespace The namespace for this cache to write to - note, namespaces of the same name are shared!
- */
- function __construct($namespace = 'default') {
- $this->setNamespace($namespace);
- $this->clear();
- }
-
- public function save($key, $data) {
- $namespace = $this->getNamespace();
-
- ElggStaticVariableCache::$__cache[$namespace][$key] = $data;
-
- return true;
- }
-
- public function load($key, $offset = 0, $limit = null) {
- $namespace = $this->getNamespace();
-
- if (isset(ElggStaticVariableCache::$__cache[$namespace][$key])) {
- return ElggStaticVariableCache::$__cache[$namespace][$key];
- }
-
- return false;
- }
-
- public function delete($key) {
- $namespace = $this->getNamespace();
-
- unset(ElggStaticVariableCache::$__cache[$namespace][$key]);
-
- return true;
- }
-
- public function clear() {
- $namespace = $this->getNamespace();
-
- if (!isset(ElggStaticVariableCache::$__cache)) {
- ElggStaticVariableCache::$__cache = array();
- }
-
- ElggStaticVariableCache::$__cache[$namespace] = array();
- }
-}
-
-/**
- * ElggFileCache
- * Store cached data in a file store.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage API
- */
-class ElggFileCache extends ElggCache {
- /**
- * Set the Elgg cache.
- *
- * @param string $cache_path The cache path.
- * @param int $max_age Maximum age in seconds, 0 if no limit.
- * @param int $max_size Maximum size of cache in seconds, 0 if no limit.
- */
- function __construct($cache_path, $max_age = 0, $max_size = 0) {
- $this->set_variable("cache_path", $cache_path);
- $this->set_variable("max_age", $max_age);
- $this->set_variable("max_size", $max_size);
-
- if ($cache_path=="") {
- throw new ConfigurationException(elgg_echo('ConfigurationException:NoCachePath'));
- }
- }
-
- /**
- * Create and return a handle to a file.
- *
- * @param string $filename
- * @param string $rw
- */
- protected function create_file($filename, $rw = "rb") {
- // Create a filename matrix
- $matrix = "";
- $depth = strlen($filename);
- if ($depth > 5) {
- $depth = 5;
- }
-
- // Create full path
- $path = $this->get_variable("cache_path") . $matrix;
- if (!is_dir($path)) {
- mkdir($path, 0700, true);
- }
-
- // Open the file
- if ((!file_exists($path . $filename)) && ($rw=="rb")) {
- return false;
- }
-
- return fopen($path . $filename, $rw);
- }
-
- /**
- * Create a sanitised filename for the file.
- *
- * @param string $filename
- */
- protected function sanitise_filename($filename) {
- // @todo : Writeme
-
- return $filename;
- }
-
- /**
- * Save a key
- *
- * @param string $key
- * @param string $data
- * @return boolean
- */
- public function save($key, $data) {
- $f = $this->create_file($this->sanitise_filename($key), "wb");
- if ($f) {
- $result = fwrite($f, $data);
- fclose($f);
-
- return $result;
- }
-
- return false;
- }
-
- /**
- * Load a key
- *
- * @param string $key
- * @param int $offset
- * @param int $limit
- * @return string
- */
- public function load($key, $offset = 0, $limit = null) {
- $f = $this->create_file($this->sanitise_filename($key));
- if ($f) {
- //fseek($f, $offset);
- if (!$limit) {
- $limit = -1;
- }
- $data = stream_get_contents($f, $limit, $offset);
-
- fclose($f);
-
- return $data;
- }
-
- return false;
- }
-
- /**
- * Invalidate a given key.
- *
- * @param string $key
- * @return bool
- */
- public function delete($key) {
- $dir = $this->get_variable("cache_path");
-
- if (file_exists($dir.$key)) {
- return unlink($dir.$key);
- }
- return TRUE;
- }
-
- public function clear() {
- // @todo writeme
- }
-
- public function __destruct() {
- // @todo Check size and age, clean up accordingly
- $size = 0;
- $dir = $this->get_variable("cache_path");
-
- // Short circuit if both size and age are unlimited
- if (($this->get_variable("max_age")==0) && ($this->get_variable("max_size")==0)) {
- return;
- }
-
- $exclude = array(".","..");
-
- $files = scandir($dir);
- if (!$files) {
- throw new IOException(sprintf(elgg_echo('IOException:NotDirectory'), $dir));
- }
-
- // Perform cleanup
- foreach ($files as $f) {
- if (!in_array($f, $exclude)) {
- $stat = stat($dir.$f);
-
- // Add size
- $size .= $stat['size'];
-
- // Is this older than my maximum date?
- if (($this->get_variable("max_age")>0) && (time() - $stat['mtime'] > $this->get_variable("max_age"))) {
- unlink($dir.$f);
- }
-
- // @todo Size
- }
- }
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggCache.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggSharedMemoryCache.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggStaticVariableCache.php';
+require_once dirname(dirname(__FILE__)).'/classes/ElggFileCache.php';
diff --git a/engine/lib/calendar.php b/engine/lib/calendar.php
index a9d6dfadf..5e4584515 100644
--- a/engine/lib/calendar.php
+++ b/engine/lib/calendar.php
@@ -8,35 +8,7 @@
* @link http://elgg.org/
*/
-/**
- * Calendar interface for events.
- *
- */
-interface Notable {
- /**
- * Calendar functionality.
- * This function sets the time of an object on a calendar listing.
- *
- * @param int $hour If ommitted, now is assumed.
- * @param int $minute If ommitted, now is assumed.
- * @param int $second If ommitted, now is assumed.
- * @param int $day If ommitted, now is assumed.
- * @param int $month If ommitted, now is assumed.
- * @param int $year If ommitted, now is assumed.
- * @param int $duration Duration of event, remainder of the day is assumed.
- */
- public function setCalendarTimeAndDuration($hour = NULL, $minute = NULL, $second = NULL, $day = NULL, $month = NULL, $year = NULL, $duration = NULL);
-
- /**
- * Return the start timestamp.
- */
- public function getCalendarStartTime();
-
- /**
- * Return the end timestamp.
- */
- public function getCalendarEndTime();
-}
+require_once dirname(dirname(__FILE__)).'/classes/Notable.php';
/**
* Return a timestamp for the start of a given day (defaults today).
diff --git a/engine/lib/cron.php b/engine/lib/cron.php
index 223b6774f..408a5c51f 100644
--- a/engine/lib/cron.php
+++ b/engine/lib/cron.php
@@ -8,8 +8,7 @@
* @link http://elgg.org/
*/
-/** The cron exception. */
-class CronException extends Exception {}
+require_once dirname(dirname(__FILE__)).'/classes/CronException.php';
/**
* Initialisation
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index 9a09d4f72..d4aa37a53 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -1750,88 +1750,7 @@ function is_ip_in_array(array $networks, $ip) {
return false;
}
-/**
- * An interface for objects that behave as elements within a social network that have a profile.
- *
- */
-interface Friendable {
- /**
- * Adds a user as a friend
- *
- * @param int $friend_guid The GUID of the user to add
- */
- public function addFriend($friend_guid);
-
- /**
- * Removes a user as a friend
- *
- * @param int $friend_guid The GUID of the user to remove
- */
- public function removeFriend($friend_guid);
-
- /**
- * Determines whether or not the current user is a friend of this entity
- *
- */
- public function isFriend();
-
- /**
- * Determines whether or not this entity is friends with a particular entity
- *
- * @param int $user_guid The GUID of the entity this entity may or may not be friends with
- */
- public function isFriendsWith($user_guid);
-
- /**
- * Determines whether or not a foreign entity has made this one a friend
- *
- * @param int $user_guid The GUID of the foreign entity
- */
- public function isFriendOf($user_guid);
-
- /**
- * Returns this entity's friends
- *
- * @param string $subtype The subtype of entity to return
- * @param int $limit The number of entities to return
- * @param int $offset Indexing offset
- */
- public function getFriends($subtype = "", $limit = 10, $offset = 0);
-
- /**
- * Returns entities that have made this entity a friend
- *
- * @param string $subtype The subtype of entity to return
- * @param int $limit The number of entities to return
- * @param int $offset Indexing offset
- */
- public function getFriendsOf($subtype = "", $limit = 10, $offset = 0);
-
- /**
- * Returns objects in this entity's container
- *
- * @param string $subtype The subtype of entity to return
- * @param int $limit The number of entities to return
- * @param int $offset Indexing offset
- */
- public function getObjects($subtype="", $limit = 10, $offset = 0);
-
- /**
- * Returns objects in the containers of this entity's friends
- *
- * @param string $subtype The subtype of entity to return
- * @param int $limit The number of entities to return
- * @param int $offset Indexing offset
- */
- public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0);
-
- /**
- * Returns the number of object entities in this entity's container
- *
- * @param string $subtype The subtype of entity to count
- */
- public function countObjects($subtype = "");
-}
+require_once dirname(dirname(__FILE__)).'/classes/Friendable.php';
/**
* Rebuilds a parsed (partial) URL
diff --git a/engine/lib/entities.php b/engine/lib/entities.php
index 813759c8b..2ba762c2c 100644
--- a/engine/lib/entities.php
+++ b/engine/lib/entities.php
@@ -19,1215 +19,7 @@ $SUBTYPE_CACHE = NULL;
// @todo Move this into start.php?
require_once('location.php');
-/**
- * ElggEntity The elgg entity superclass
- * This class holds methods for accessing the main entities table.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-abstract class ElggEntity implements
- Notable, // Calendar interface
- Locatable, // Geocoding interface
- Exportable, // Allow export of data
- Importable, // Allow import of data
- Loggable, // Can events related to this object class be logged
- Iterator, // Override foreach behaviour
- ArrayAccess // Override for array access
-{
- /**
- * The main attributes of an entity.
- * Blank entries for all database fields should be created by the constructor.
- * Subclasses should add to this in their constructors.
- * Any field not appearing in this will be viewed as a
- */
- protected $attributes;
-
- /**
- * If set, overrides the value of getURL()
- */
- protected $url_override;
-
- /**
- * Icon override, overrides the value of getIcon().
- */
- protected $icon_override;
-
- /**
- * Temporary cache for metadata, permitting meta data access before a guid has obtained.
- */
- protected $temp_metadata;
-
- /**
- * Temporary cache for annotations, permitting meta data access before a guid has obtained.
- */
- protected $temp_annotations;
-
-
- /**
- * Volatile data structure for this object, allows for storage of data
- * in-memory that isn't sync'd back to the metadata table.
- */
- protected $volatile;
-
- /**
- * Initialise the attributes array.
- * This is vital to distinguish between metadata and base parameters.
- *
- * Place your base parameters here.
- *
- * @return void
- */
- protected function initialise_attributes() {
- initialise_entity_cache();
-
- // Create attributes array if not already created
- if (!is_array($this->attributes)) {
- $this->attributes = array();
- }
- if (!is_array($this->temp_metadata)) {
- $this->temp_metadata = array();
- }
- if (!is_array($this->temp_annotations)) {
- $this->temp_annotations = array();
- }
- if (!is_array($this->volatile)) {
- $this->volatile = array();
- }
-
- $this->attributes['guid'] = "";
- $this->attributes['type'] = "";
- $this->attributes['subtype'] = "";
-
- $this->attributes['owner_guid'] = get_loggedin_userid();
- $this->attributes['container_guid'] = get_loggedin_userid();
-
- $this->attributes['site_guid'] = 0;
- $this->attributes['access_id'] = ACCESS_PRIVATE;
- $this->attributes['time_created'] = "";
- $this->attributes['time_updated'] = "";
- $this->attributes['last_action'] = '';
- $this->attributes['enabled'] = "yes";
-
- // There now follows a bit of a hack
- /* Problem: To speed things up, some objects are split over several tables, this means that it requires
- * n number of database reads to fully populate an entity. This causes problems for caching and create events
- * since it is not possible to tell whether a subclassed entity is complete.
- * Solution: We have two counters, one 'tables_split' which tells whatever is interested how many tables
- * are going to need to be searched in order to fully populate this object, and 'tables_loaded' which is how
- * many have been loaded thus far.
- * If the two are the same then this object is complete.
- *
- * Use: isFullyLoaded() to check
- */
- $this->attributes['tables_split'] = 1;
- $this->attributes['tables_loaded'] = 0;
- }
-
- /**
- * Clone an entity
- *
- * Resets the guid so that the entity can be saved as a distinct entity from
- * the original. Creation time will be set when this new entity is saved.
- * The owner and container guids come from the original entity. The clone
- * method copies metadata but does not copy over annotations, or private settings.
- *
- * Note: metadata will have its owner and access id set when the entity is saved
- * and it will be the same as that of the entity.
- */
- public function __clone() {
-
- $orig_entity = get_entity($this->guid);
- if (!$orig_entity) {
- elgg_log("Failed to clone entity with GUID $this->guid", "ERROR");
- return;
- }
-
- $metadata_array = get_metadata_for_entity($this->guid);
-
- $this->attributes['guid'] = "";
-
- $this->attributes['subtype'] = $orig_entity->getSubtype();
-
- // copy metadata over to new entity - slightly convoluted due to
- // handling of metadata arrays
- if (is_array($metadata_array)) {
- // create list of metadata names
- $metadata_names = array();
- foreach ($metadata_array as $metadata) {
- $metadata_names[] = $metadata['name'];
- }
- // arrays are stored with multiple enties per name
- $metadata_names = array_unique($metadata_names);
-
- // move the metadata over
- foreach ($metadata_names as $name) {
- $this->set($name, $orig_entity->$name);
- }
- }
- }
-
- /**
- * Return the value of a given key.
- * If $name is a key field (as defined in $this->attributes) that value is returned, otherwise it will
- * then look to see if the value is in this object's metadata.
- *
- * Q: Why are we not using __get overload here?
- * A: Because overload operators cause problems during subclassing, so we put the code here and
- * create overloads in subclasses.
- *
- * subtype is returned as an id rather than the subtype string. Use getSubtype()
- * to get the subtype string.
- *
- * @param string $name
- * @return mixed Returns the value of a given value, or null.
- */
- public function get($name) {
- // See if its in our base attribute
- if (isset($this->attributes[$name])) {
- return $this->attributes[$name];
- }
-
- // No, so see if its in the meta data for this entity
- $meta = $this->getMetaData($name);
-
- // getMetaData returns NULL if $name is not found
- return $meta;
- }
-
- /**
- * Set the value of a given key, replacing it if necessary.
- * If $name is a base attribute (as defined in $this->attributes) that value is set, otherwise it will
- * set the appropriate item of metadata.
- *
- * Note: It is important that your class populates $this->attributes with keys for all base attributes, anything
- * not in their gets set as METADATA.
- *
- * Q: Why are we not using __set overload here?
- * A: Because overload operators cause problems during subclassing, so we put the code here and
- * create overloads in subclasses.
- *
- * @param string $name
- * @param mixed $value
- */
- public function set($name, $value) {
- if (array_key_exists($name, $this->attributes)) {
- // Certain properties should not be manually changed!
- switch ($name) {
- case 'guid':
- case 'time_created':
- case 'time_updated':
- case 'last_action':
- return FALSE;
- break;
- default:
- $this->attributes[$name] = $value;
- break;
- }
- } else {
- return $this->setMetaData($name, $value);
- }
-
- return TRUE;
- }
-
- /**
- * Get a given piece of metadata.
- *
- * @param string $name
- */
- public function getMetaData($name) {
- if ((int) ($this->guid) > 0) {
- $md = get_metadata_byname($this->getGUID(), $name);
- } else {
- if (isset($this->temp_metadata[$name])) {
- return $this->temp_metadata[$name];
- }
- }
-
- if ($md && !is_array($md)) {
- return $md->value;
- } else if ($md && is_array($md)) {
- return metadata_array_to_values($md);
- }
-
- return null;
- }
-
- /**
- * Class member get overloading
- *
- * @param string $name
- * @return mixed
- */
- function __get($name) {
- return $this->get($name);
- }
-
- /**
- * Class member set overloading
- *
- * @param string $name
- * @param mixed $value
- * @return mixed
- */
- function __set($name, $value) {
- return $this->set($name, $value);
- }
-
- /**
- * Supporting isset.
- *
- * @param string $name The name of the attribute or metadata.
- * @return bool
- */
- function __isset($name) {
- return $this->$name !== NULL;
- }
-
- /**
- * Supporting unsetting of magic attributes.
- *
- * @param string $name The name of the attribute or metadata.
- */
- function __unset($name) {
- if (array_key_exists($name, $this->attributes)) {
- $this->attributes[$name] = "";
- }
- else {
- $this->clearMetaData($name);
- }
- }
-
- /**
- * Set a piece of metadata.
- *
- * @param string $name Name of the metadata
- * @param mixed $value Value of the metadata
- * @param string $value_type Types supported: integer and string. Will auto-identify if not set
- * @param bool $multiple (does not support associative arrays)
- * @return bool
- */
- public function setMetaData($name, $value, $value_type = "", $multiple = false) {
- if (is_array($value)) {
- unset($this->temp_metadata[$name]);
- remove_metadata($this->getGUID(), $name);
- foreach ($value as $v) {
- if ((int) $this->guid > 0) {
- $multiple = true;
- if (!create_metadata($this->getGUID(), $name, $v, $value_type,
- $this->getOwner(), $this->getAccessID(), $multiple)) {
- return false;
- }
- } else {
- if (($multiple) && (isset($this->temp_metadata[$name]))) {
- if (!is_array($this->temp_metadata[$name])) {
- $tmp = $this->temp_metadata[$name];
- $this->temp_metadata[$name] = array();
- $this->temp_metadata[$name][] = $tmp;
- }
-
- $this->temp_metadata[$name][] = $value;
- }
- else {
- $this->temp_metadata[$name] = $value;
- }
- }
- }
-
- return true;
- } else {
- unset($this->temp_metadata[$name]);
- if ((int) $this->guid > 0) {
- $result = create_metadata($this->getGUID(), $name, $value, $value_type, $this->getOwner(), $this->getAccessID(), $multiple);
- return (bool)$result;
- } else {
- if (($multiple) && (isset($this->temp_metadata[$name]))) {
- if (!is_array($this->temp_metadata[$name])) {
- $tmp = $this->temp_metadata[$name];
- $this->temp_metadata[$name] = array();
- $this->temp_metadata[$name][] = $tmp;
- }
-
- $this->temp_metadata[$name][] = $value;
- }
- else {
- $this->temp_metadata[$name] = $value;
- }
-
- return true;
- }
- }
- }
-
- /**
- * Clear metadata.
- */
- public function clearMetaData($name = "") {
- if (empty($name)) {
- return clear_metadata($this->getGUID());
- } else {
- return remove_metadata($this->getGUID(),$name);
- }
- }
-
-
- /**
- * Get a piece of volatile (non-persisted) data on this entity
- */
- public function getVolatileData($name) {
- if (!is_array($this->volatile)) {
- $this->volatile = array();
- }
-
- if (array_key_exists($name, $this->volatile)) {
- return $this->volatile[$name];
- } else {
- return NULL;
- }
- }
-
-
- /**
- * Set a piece of volatile (non-persisted) data on this entity
- */
- public function setVolatileData($name, $value) {
- if (!is_array($this->volatile)) {
- $this->volatile = array();
- }
-
- $this->volatile[$name] = $value;
- }
-
-
- /**
- * Remove all entities associated with this entity
- *
- * @return true
- */
- public function clearRelationships() {
- remove_entity_relationships($this->getGUID());
- remove_entity_relationships($this->getGUID(),"",true);
- return true;
- }
-
- /**
- * Add a relationship.
- *
- * @param int $guid Relationship to link to.
- * @param string $relationship The type of relationship.
- * @return bool
- */
- public function addRelationship($guid, $relationship) {
- return add_entity_relationship($this->getGUID(), $relationship, $guid);
- }
-
- /**
- * Remove a relationship
- *
- * @param int $guid
- * @param str $relationship
- * @return bool
- */
- public function removeRelationship($guid, $relationship) {
- return remove_entity_relationship($this->getGUID(), $relationship, $guid);
- }
-
- /**
- * Adds a private setting to this entity.
- *
- * @param $name
- * @param $value
- * @return unknown_type
- */
- function setPrivateSetting($name, $value) {
- return set_private_setting($this->getGUID(), $name, $value);
- }
-
- /**
- * Gets private setting for this entity
- *
- * @param $name
- * @return unknown_type
- */
- function getPrivateSetting($name) {
- return get_private_setting($this->getGUID(), $name);
- }
-
- /**
- * Removes private setting for this entity.
- *
- * @param $name
- * @return unknown_type
- */
- function removePrivateSetting($name) {
- return remove_private_setting($this->getGUID(), $name);
- }
-
- /**
- * Adds an annotation to an entity. By default, the type is detected automatically; however,
- * it can also be set. Note that by default, annotations are private.
- *
- * @param string $name
- * @param mixed $value
- * @param int $access_id
- * @param int $owner_id
- * @param string $vartype
- */
- function annotate($name, $value, $access_id = ACCESS_PRIVATE, $owner_id = 0, $vartype = "") {
- if ((int) $this->guid > 0) {
- return create_annotation($this->getGUID(), $name, $value, $vartype, $owner_id, $access_id);
- } else {
- $this->temp_annotations[$name] = $value;
- }
- return true;
- }
-
- /**
- * Get the annotations for an entity.
- *
- * @param string $name
- * @param int $limit
- * @param int $offset
- * @param string $order
- */
- function getAnnotations($name, $limit = 50, $offset = 0, $order="asc") {
- if ((int) ($this->guid) > 0) {
- return get_annotations($this->getGUID(), "", "", $name, "", 0, $limit, $offset, $order);
- } else {
- return $this->temp_annotations[$name];
- }
- }
-
- /**
- * Remove all annotations or all annotations for this entity.
- *
- * @param string $name
- */
- function clearAnnotations($name = "") {
- return clear_annotations($this->getGUID(), $name);
- }
-
- /**
- * Return the annotations for the entity.
- *
- * @param string $name The type of annotation.
- */
- function countAnnotations($name = "") {
- return count_annotations($this->getGUID(), "", "", $name);
- }
-
- /**
- * Get the average of an integer type annotation.
- *
- * @param string $name
- */
- function getAnnotationsAvg($name) {
- return get_annotations_avg($this->getGUID(), "", "", $name);
- }
-
- /**
- * Get the sum of integer type annotations of a given name.
- *
- * @param string $name
- */
- function getAnnotationsSum($name) {
- return get_annotations_sum($this->getGUID(), "", "", $name);
- }
-
- /**
- * Get the minimum of integer type annotations of given name.
- *
- * @param string $name
- */
- function getAnnotationsMin($name) {
- return get_annotations_min($this->getGUID(), "", "", $name);
- }
-
- /**
- * Get the maximum of integer type annotations of a given name.
- *
- * @param string $name
- */
- function getAnnotationsMax($name) {
- return get_annotations_max($this->getGUID(), "", "", $name);
- }
-
- /**
- * Gets an array of entities from a specific relationship type
- *
- * @param string $relationship Relationship type (eg "friends")
- * @param true|false $inverse Is this an inverse relationship?
- * @param int $limit Number of elements to return
- * @param int $offset Indexing offset
- * @return array|false An array of entities or false on failure
- */
- function getEntitiesFromRelationship($relationship, $inverse = false, $limit = 50, $offset = 0) {
- return elgg_get_entities_from_relationship(array(
- 'relationship' => $relationship,
- 'relationship_guid' => $this->getGUID(),
- 'inverse_relationship' => $inverse,
- 'limit' => $limit,
- 'offset' => $offset
- ));
- }
-
- /**
- * Gets the number of of entities from a specific relationship type
- *
- * @param string $relationship Relationship type (eg "friends")
- * @param bool $inverse_relationship
- * @return int|false The number of entities or false on failure
- */
- function countEntitiesFromRelationship($relationship, $inverse_relationship = FALSE) {
- return elgg_get_entities_from_relationship(array(
- 'relationship' => $relationship,
- 'relationship_guid' => $this->getGUID(),
- 'inverse_relationship' => $inverse_relationship,
- 'count' => TRUE
- ));
- }
-
- /**
- * Determines whether or not the specified user (by default the current one) can edit the entity
- *
- * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user)
- * @return true|false
- */
- function canEdit($user_guid = 0) {
- return can_edit_entity($this->getGUID(), $user_guid);
- }
-
- /**
- * Determines whether or not the specified user (by default the current one) can edit metadata on the entity
- *
- * @param ElggMetadata $metadata The piece of metadata to specifically check
- * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user)
- * @return true|false
- */
- function canEditMetadata($metadata = null, $user_guid = 0) {
- return can_edit_entity_metadata($this->getGUID(), $user_guid, $metadata);
- }
-
- /**
- * Returns whether the given user (or current user) has the ability to write to this container.
- *
- * @param int $user_guid The user.
- * @return bool
- */
- public function canWriteToContainer($user_guid = 0) {
- return can_write_to_container($user_guid, $this->getGUID());
- }
-
- /**
- * Obtain this entity's access ID
- *
- * @return int The access ID
- */
- public function getAccessID() {
- return $this->get('access_id');
- }
-
- /**
- * Obtain this entity's GUID
- *
- * @return int GUID
- */
- public function getGUID() {
- return $this->get('guid');
- }
-
- /**
- * Get the owner of this entity
- *
- * @return int The owner GUID
- */
- public function getOwner() {
- return $this->get('owner_guid');
- }
-
- /**
- * Returns the actual entity of the user who owns this entity, if any
- *
- * @return ElggEntity The owning user
- */
- public function getOwnerEntity() {
- return get_entity($this->get('owner_guid'));
- }
-
- /**
- * Gets the type of entity this is
- *
- * @return string Entity type
- */
- public function getType() {
- return $this->get('type');
- }
-
- /**
- * Returns the subtype of this entity
- *
- * @return string The entity subtype
- */
- public function getSubtype() {
- // If this object hasn't been saved, then return the subtype string.
- if (!((int) $this->guid > 0)) {
- return $this->get('subtype');
- }
-
- return get_subtype_from_id($this->get('subtype'));
- }
-
- /**
- * Gets the UNIX epoch time that this entity was created
- *
- * @return int UNIX epoch time
- */
- public function getTimeCreated() {
- return $this->get('time_created');
- }
-
- /**
- * Gets the UNIX epoch time that this entity was last updated
- *
- * @return int UNIX epoch time
- */
- public function getTimeUpdated() {
- return $this->get('time_updated');
- }
-
- /**
- * Gets the display URL for this entity
- *
- * @return string The URL
- */
- public function getURL() {
- if (!empty($this->url_override)) {
- return $this->url_override;
- }
- return get_entity_url($this->getGUID());
- }
-
- /**
- * Overrides the URL returned by getURL
- *
- * @param string $url The new item URL
- * @return string The URL
- */
- public function setURL($url) {
- $this->url_override = $url;
- return $url;
- }
-
- /**
- * Return a url for the entity's icon, trying multiple alternatives.
- *
- * @param string $size Either 'large','medium','small' or 'tiny'
- * @return string The url or false if no url could be worked out.
- */
- public function getIcon($size = 'medium') {
- if (isset($this->icon_override[$size])) {
- return $this->icon_override[$size];
- }
- return get_entity_icon_url($this, $size);
- }
-
- /**
- * Set an icon override for an icon and size.
- *
- * @param string $url The url of the icon.
- * @param string $size The size its for.
- * @return bool
- */
- public function setIcon($url, $size = 'medium') {
- $url = sanitise_string($url);
- $size = sanitise_string($size);
-
- if (!$this->icon_override) {
- $this->icon_override = array();
- }
- $this->icon_override[$size] = $url;
-
- return true;
- }
-
- /**
- * Tests to see whether the object has been fully loaded.
- *
- * @return bool
- */
- public function isFullyLoaded() {
- return ! ($this->attributes['tables_loaded'] < $this->attributes['tables_split']);
- }
-
- /**
- * Save generic attributes to the entities table.
- */
- public function save() {
- $guid = (int) $this->guid;
- if ($guid > 0) {
- cache_entity($this);
-
- return update_entity(
- $this->get('guid'),
- $this->get('owner_guid'),
- $this->get('access_id'),
- $this->get('container_guid')
- );
- } else {
- // Create a new entity (nb: using attribute array directly 'cos set function does something special!)
- $this->attributes['guid'] = create_entity($this->attributes['type'], $this->attributes['subtype'], $this->attributes['owner_guid'], $this->attributes['access_id'], $this->attributes['site_guid'], $this->attributes['container_guid']);
- if (!$this->attributes['guid']) {
- throw new IOException(elgg_echo('IOException:BaseEntitySaveFailed'));
- }
-
- // Save any unsaved metadata
- // @todo How to capture extra information (access id etc)
- if (sizeof($this->temp_metadata) > 0) {
- foreach($this->temp_metadata as $name => $value) {
- $this->$name = $value;
- unset($this->temp_metadata[$name]);
- }
- }
-
- // Save any unsaved annotations metadata.
- // @todo How to capture extra information (access id etc)
- if (sizeof($this->temp_annotations) > 0) {
- foreach($this->temp_annotations as $name => $value) {
- $this->annotate($name, $value);
- unset($this->temp_annotations[$name]);
- }
- }
-
- // set the subtype to id now rather than a string
- $this->attributes['subtype'] = get_subtype_id($this->attributes['type'], $this->attributes['subtype']);
-
- // Cache object handle
- if ($this->attributes['guid']) {
- cache_entity($this);
- }
-
- return $this->attributes['guid'];
- }
- }
-
- /**
- * Load the basic entity information and populate base attributes array.
- *
- * @param int $guid
- */
- protected function load($guid) {
- $row = get_entity_as_row($guid);
-
- if ($row) {
- // Create the array if necessary - all subclasses should test before creating
- if (!is_array($this->attributes)) {
- $this->attributes = array();
- }
-
- // Now put these into the attributes array as core values
- $objarray = (array) $row;
- foreach($objarray as $key => $value) {
- $this->attributes[$key] = $value;
- }
-
- // Increment the portion counter
- if (!$this->isFullyLoaded()) {
- $this->attributes['tables_loaded']++;
- }
-
- // Cache object handle
- if ($this->attributes['guid']) {
- cache_entity($this);
- }
-
- return true;
- }
-
- return false;
- }
-
- /**
- * Disable this entity.
- *
- * @param string $reason Optional reason
- * @param bool $recursive Recursively disable all contained entities?
- */
- public function disable($reason = "", $recursive = true) {
- return disable_entity($this->get('guid'), $reason, $recursive);
- }
-
- /**
- * Re-enable this entity.
- */
- public function enable() {
- return enable_entity($this->get('guid'));
- }
-
- /**
- * Is this entity enabled?
- *
- * @return boolean
- */
- public function isEnabled() {
- if ($this->enabled == 'yes') {
- return true;
- }
-
- return false;
- }
-
- /**
- * Delete this entity.
- */
- public function delete() {
- return delete_entity($this->get('guid'));
- }
-
- // LOCATABLE INTERFACE /////////////////////////////////////////////////////////////
-
- /** Interface to set the location */
- public function setLocation($location) {
- $location = sanitise_string($location);
-
- $this->location = $location;
-
- return true;
- }
-
- /**
- * Set latitude and longitude tags for a given entity.
- *
- * @param float $lat
- * @param float $long
- */
- public function setLatLong($lat, $long) {
- $lat = sanitise_string($lat);
- $long = sanitise_string($long);
-
- $this->set('geo:lat', $lat);
- $this->set('geo:long', $long);
-
- return true;
- }
-
- /**
- * Get the contents of the ->geo:lat field.
- *
- */
- public function getLatitude() {
- return $this->get('geo:lat');
- }
-
- /**
- * Get the contents of the ->geo:lat field.
- *
- */
- public function getLongitude() {
- return $this->get('geo:long');
- }
-
- /**
- * Get the ->location metadata.
- *
- */
- public function getLocation() {
- return $this->get('location');
- }
-
- // NOTABLE INTERFACE ///////////////////////////////////////////////////////////////
-
- /**
- * Calendar functionality.
- * This function sets the time of an object on a calendar listing.
- *
- * @param int $hour If ommitted, now is assumed.
- * @param int $minute If ommitted, now is assumed.
- * @param int $second If ommitted, now is assumed.
- * @param int $day If ommitted, now is assumed.
- * @param int $month If ommitted, now is assumed.
- * @param int $year If ommitted, now is assumed.
- * @param int $duration Duration of event, remainder of the day is assumed.
- */
- public function setCalendarTimeAndDuration($hour = NULL, $minute = NULL, $second = NULL, $day = NULL, $month = NULL, $year = NULL, $duration = NULL) {
- $start = mktime($hour, $minute, $second, $month, $day, $year);
- $end = $start + abs($duration);
- if (!$duration) {
- $end = get_day_end($day,$month,$year);
- }
-
- $this->calendar_start = $start;
- $this->calendar_end = $end;
-
- return true;
- }
-
- /**
- * Return the start timestamp.
- */
- public function getCalendarStartTime() {
- return (int)$this->calendar_start;
- }
-
- /**
- * Return the end timestamp.
- */
- public function getCalendarEndTime() {
- return (int)$this->calendar_end;
- }
-
- // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an array of fields which can be exported.
- */
- public function getExportableValues() {
- return array(
- 'guid',
- 'type',
- 'subtype',
- 'time_created',
- 'time_updated',
- 'container_guid',
- 'owner_guid',
- 'site_guid'
- );
- }
-
- /**
- * Export this class into an array of ODD Elements containing all necessary fields.
- * Override if you wish to return more information than can be found in $this->attributes (shouldn't happen)
- */
- public function export() {
- $tmp = array();
-
- // Generate uuid
- $uuid = guid_to_uuid($this->getGUID());
-
- // Create entity
- $odd = new ODDEntity(
- $uuid,
- $this->attributes['type'],
- get_subtype_from_id($this->attributes['subtype'])
- );
-
- $tmp[] = $odd;
-
- $exportable_values = $this->getExportableValues();
-
- // Now add its attributes
- foreach ($this->attributes as $k => $v) {
- $meta = NULL;
-
- if (in_array( $k, $exportable_values)) {
- switch ($k) {
- case 'guid' : // Dont use guid in OpenDD
- case 'type' : // Type and subtype already taken care of
- case 'subtype' :
- break;
-
- case 'time_created' : // Created = published
- $odd->setAttribute('published', date("r", $v));
- break;
-
- case 'site_guid' : // Container
- $k = 'site_uuid';
- $v = guid_to_uuid($v);
- $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
- break;
-
- case 'container_guid' : // Container
- $k = 'container_uuid';
- $v = guid_to_uuid($v);
- $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
- break;
-
- case 'owner_guid' : // Convert owner guid to uuid, this will be stored in metadata
- $k = 'owner_uuid';
- $v = guid_to_uuid($v);
- $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
- break;
-
- default :
- $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
- }
-
- // set the time of any metadata created
- if ($meta) {
- $meta->setAttribute('published', date("r",$this->time_created));
- $tmp[] = $meta;
- }
- }
- }
-
- // Now we do something a bit special.
- /*
- * This provides a rendered view of the entity to foreign sites.
- */
-
- elgg_set_viewtype('default');
- $view = elgg_view_entity($this, true);
- elgg_set_viewtype();
-
- $tmp[] = new ODDMetaData($uuid . "volatile/renderedentity/", $uuid, 'renderedentity', $view , 'volatile');
-
- return $tmp;
- }
-
- // IMPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Import data from an parsed xml data array.
- *
- * @param array $data
- * @param int $version
- */
- public function import(ODD $data) {
- if (!($data instanceof ODDEntity)) {
- throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass'));
- }
-
- // Set type and subtype
- $this->attributes['type'] = $data->getAttribute('class');
- $this->attributes['subtype'] = $data->getAttribute('subclass');
-
- // Set owner
- $this->attributes['owner_guid'] = get_loggedin_userid(); // Import as belonging to importer.
-
- // Set time
- $this->attributes['time_created'] = strtotime($data->getAttribute('published'));
- $this->attributes['time_updated'] = time();
-
- return true;
- }
-
- // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an identification for the object for storage in the system log.
- * This id must be an integer.
- *
- * @return int
- */
- public function getSystemLogID() {
- return $this->getGUID();
- }
-
- /**
- * Return the class name of the object.
- */
- public function getClassName() {
- return get_class($this);
- }
-
- /**
- * For a given ID, return the object associated with it.
- * This is used by the river functionality primarily.
- * This is useful for checking access permissions etc on objects.
- */
- public function getObjectFromID($id) {
- return get_entity($id);
- }
-
- /**
- * Return the GUID of the owner of this object.
- */
- public function getObjectOwnerGUID() {
- return $this->owner_guid;
- }
-
- /**
- * Returns tags for this entity.
- *
- * @param array $tag_names Optionally restrict by tag metadata names.
- * @return array
- */
- public function getTags($tag_names = NULL) {
- global $CONFIG;
-
- if ($tag_names && !is_array($tag_names)) {
- $tag_names = array($tag_names);
- }
-
- $valid_tags = elgg_get_registered_tag_metadata_names();
- $entity_tags = array();
-
- foreach ($valid_tags as $tag_name) {
- if (is_array($tag_names) && !in_array($tag_name, $tag_names)) {
- continue;
- }
-
- if ($tags = $this->$tag_name) {
- // if a single tag, metadata returns a string.
- // if multiple tags, metadata returns an array.
- if (is_array($tags)) {
- $entity_tags = array_merge($entity_tags, $tags);
- } else {
- $entity_tags[] = $tags;
- }
- }
- }
-
- return $entity_tags;
- }
-
- // ITERATOR INTERFACE //////////////////////////////////////////////////////////////
- /*
- * This lets an entity's attributes be displayed using foreach as a normal array.
- * Example: http://www.sitepoint.com/print/php5-standard-library
- */
-
- private $valid = FALSE;
-
- function rewind() {
- $this->valid = (FALSE !== reset($this->attributes));
- }
-
- function current() {
- return current($this->attributes);
- }
-
- function key() {
- return key($this->attributes);
- }
-
- function next() {
- $this->valid = (FALSE !== next($this->attributes));
- }
-
- function valid() {
- return $this->valid;
- }
-
- // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
- /*
- * This lets an entity's attributes be accessed like an associative array.
- * Example: http://www.sitepoint.com/print/php5-standard-library
- */
-
- function offsetSet($key, $value) {
- if ( array_key_exists($key, $this->attributes) ) {
- $this->attributes[$key] = $value;
- }
- }
-
- function offsetGet($key) {
- if ( array_key_exists($key, $this->attributes) ) {
- return $this->attributes[$key];
- }
- }
-
- function offsetUnset($key) {
- if ( array_key_exists($key, $this->attributes) ) {
- $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects
- }
- }
-
- function offsetExists($offset) {
- return array_key_exists($offset, $this->attributes);
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggEntity.php';
/**
* Initialise the entity cache.
diff --git a/engine/lib/export.php b/engine/lib/export.php
index 1b09016b0..9fbd62a4d 100644
--- a/engine/lib/export.php
+++ b/engine/lib/export.php
@@ -8,59 +8,10 @@
* @link http://elgg.org/
*/
-/**
- * Define an interface for all ODD exportable objects.
- *
- * @package Elgg
- * @subpackage Core
- * @author Curverider Ltd
- */
-interface Exportable {
- /**
- * This must take the contents of the object and convert it to exportable ODD
- * @return object or array of objects.
- */
- public function export();
-
- /**
- * Return a list of all fields that can be exported.
- * This should be used as the basis for the values returned by export()
- */
- public function getExportableValues();
-}
-
-/**
- * Define an interface for all ODD importable objects.
- * @author Curverider Ltd
- */
-interface Importable {
- /**
- * Accepts an array of data to import, this data is parsed from the XML produced by export.
- * The function should return the constructed object data, or NULL.
- *
- * @param ODD $data
- * @return bool
- * @throws ImportException if there was a critical error importing data.
- */
- public function import(ODD $data);
-}
-
-/**
- * Export exception
- *
- * @package Elgg
- * @subpackage Exceptions
- *
- */
-class ExportException extends DataFormatException {}
-
-/**
- * Import exception
- *
- * @package Elgg
- * @subpackage Exceptions
- */
-class ImportException extends DataFormatException {}
+require_once dirname(dirname(__FILE__)).'/classes/Exportable.php';
+require_once dirname(dirname(__FILE__)).'/classes/Importable.php';
+require_once dirname(dirname(__FILE__)).'/classes/ExportException.php';
+require_once dirname(dirname(__FILE__)).'/classes/ImportException.php';
/**
* Get a UUID from a given object.
diff --git a/engine/lib/extender.php b/engine/lib/extender.php
index 7b54a7842..e222c2926 100644
--- a/engine/lib/extender.php
+++ b/engine/lib/extender.php
@@ -9,256 +9,7 @@
* @link http://elgg.org/
*/
-/**
- * ElggExtender
- *
- * @author Curverider Ltd
- * @package Elgg
- * @subpackage Core
- */
-abstract class ElggExtender implements
- Exportable,
- Loggable, // Can events related to this object class be logged
- Iterator, // Override foreach behaviour
- ArrayAccess // Override for array access
-{
- /**
- * This contains the site's main properties (id, etc)
- * @var array
- */
- protected $attributes;
-
- /**
- * Get an attribute
- *
- * @param string $name
- * @return mixed
- */
- protected function get($name) {
- if (isset($this->attributes[$name])) {
- // Sanitise value if necessary
- if ($name=='value') {
- switch ($this->attributes['value_type']) {
- case 'integer' :
- return (int)$this->attributes['value'];
-
- //case 'tag' :
- //case 'file' :
- case 'text' :
- return ($this->attributes['value']);
-
- default :
- throw new InstallationException(sprintf(elgg_echo('InstallationException:TypeNotSupported'), $this->attributes['value_type']));
- }
- }
-
- return $this->attributes[$name];
- }
- return null;
- }
-
- /**
- * Set an attribute
- *
- * @param string $name
- * @param mixed $value
- * @param string $value_type
- * @return boolean
- */
- protected function set($name, $value, $value_type = "") {
- $this->attributes[$name] = $value;
- if ($name == 'value') {
- $this->attributes['value_type'] = detect_extender_valuetype($value, $value_type);
- }
-
- return true;
- }
-
- /**
- * Return the owner of this annotation.
- *
- * @return mixed
- */
- public function getOwner() {
- return $this->owner_guid;
- }
-
- /**
- * Return the owner entity
- *
- * @return mixed
- * @since 1.7.0
- */
- public function getOwnerEntity() {
- return get_user($this->owner_guid);
- }
-
- /**
- * Returns the entity this is attached to
- *
- * @return ElggEntity The enttiy
- */
- public function getEntity() {
- return get_entity($this->entity_guid);
- }
-
- /**
- * Save this data to the appropriate database table.
- */
- abstract public function save();
-
- /**
- * Delete this data.
- */
- abstract public function delete();
-
- /**
- * Determines whether or not the specified user can edit this
- *
- * @param int $user_guid The GUID of the user (defaults to currently logged in user)
- * @return true|false
- */
- public function canEdit($user_guid = 0) {
- return can_edit_extender($this->id,$this->type,$user_guid);
- }
-
- /**
- * Return a url for this extender.
- *
- * @return string
- */
- public abstract function getURL();
-
- // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an array of fields which can be exported.
- */
- public function getExportableValues() {
- return array(
- 'id',
- 'entity_guid',
- 'name',
- 'value',
- 'value_type',
- 'owner_guid',
- 'type',
- );
- }
-
- /**
- * Export this object
- *
- * @return array
- */
- public function export() {
- $uuid = get_uuid_from_object($this);
-
- $meta = new ODDMetadata($uuid, guid_to_uuid($this->entity_guid), $this->attributes['name'], $this->attributes['value'], $this->attributes['type'], guid_to_uuid($this->owner_guid));
- $meta->setAttribute('published', date("r", $this->time_created));
-
- return $meta;
- }
-
- // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an identification for the object for storage in the system log.
- * This id must be an integer.
- *
- * @return int
- */
- public function getSystemLogID() {
- return $this->id;
- }
-
- /**
- * Return the class name of the object.
- */
- public function getClassName() {
- return get_class($this);
- }
-
- /**
- * Return the GUID of the owner of this object.
- */
- public function getObjectOwnerGUID() {
- return $this->owner_guid;
- }
-
- /**
- * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc
- */
- public function getType() {
- return $this->type;
- }
-
- /**
- * Return a subtype. For metadata & annotations this is the 'name' and
- * for relationship this is the relationship type.
- */
- public function getSubtype() {
- return $this->name;
- }
-
-
- // ITERATOR INTERFACE //////////////////////////////////////////////////////////////
- /*
- * This lets an entity's attributes be displayed using foreach as a normal array.
- * Example: http://www.sitepoint.com/print/php5-standard-library
- */
-
- private $valid = FALSE;
-
- function rewind() {
- $this->valid = (FALSE !== reset($this->attributes));
- }
-
- function current() {
- return current($this->attributes);
- }
-
- function key() {
- return key($this->attributes);
- }
-
- function next() {
- $this->valid = (FALSE !== next($this->attributes));
- }
-
- function valid() {
- return $this->valid;
- }
-
- // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
- /*
- * This lets an entity's attributes be accessed like an associative array.
- * Example: http://www.sitepoint.com/print/php5-standard-library
- */
-
- function offsetSet($key, $value) {
- if ( array_key_exists($key, $this->attributes) ) {
- $this->attributes[$key] = $value;
- }
- }
-
- function offsetGet($key) {
- if ( array_key_exists($key, $this->attributes) ) {
- return $this->attributes[$key];
- }
- }
-
- function offsetUnset($key) {
- if ( array_key_exists($key, $this->attributes) ) {
- // Full unsetting is dangerious for our objects
- $this->attributes[$key] = "";
- }
- }
-
- function offsetExists($offset) {
- return array_key_exists($offset, $this->attributes);
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggExtender.php';
/**
* Detect the value_type for a given value.
diff --git a/engine/lib/filestore.php b/engine/lib/filestore.php
index 31fc9ab0d..74a8b0315 100644
--- a/engine/lib/filestore.php
+++ b/engine/lib/filestore.php
@@ -12,700 +12,9 @@
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.
diff --git a/engine/lib/group.php b/engine/lib/group.php
index ab6c9112d..22badc4b9 100644
--- a/engine/lib/group.php
+++ b/engine/lib/group.php
@@ -12,303 +12,7 @@
* @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.
diff --git a/engine/lib/location.php b/engine/lib/location.php
index 7b96f4a91..a424ece25 100644
--- a/engine/lib/location.php
+++ b/engine/lib/location.php
@@ -8,40 +8,7 @@
* @link http://elgg.org/
*/
-/**
- * Define an interface for geo-tagging entities.
- *
- */
-interface Locatable {
- /** Set a location text */
- public function setLocation($location);
-
- /**
- * Set latitude and longitude tags for a given entity.
- *
- * @param float $lat
- * @param float $long
- */
- public function setLatLong($lat, $long);
-
- /**
- * Get the contents of the ->geo:lat field.
- *
- */
- public function getLatitude();
-
- /**
- * Get the contents of the ->geo:lat field.
- *
- */
- public function getLongitude();
-
- /**
- * Get the ->location metadata.
- *
- */
- public function getLocation();
-}
+require_once dirname(dirname(__FILE__)).'/classes/Locatable.php';
/**
* Encode a location into a latitude and longitude, caching the result.
diff --git a/engine/lib/memcache.php b/engine/lib/memcache.php
index 1a428dac5..de1c001b5 100644
--- a/engine/lib/memcache.php
+++ b/engine/lib/memcache.php
@@ -10,156 +10,7 @@
* @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.
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php
index dd2e341d4..9ab32912a 100644
--- a/engine/lib/metadata.php
+++ b/engine/lib/metadata.php
@@ -9,118 +9,9 @@
* @link http://elgg.org/
*/
-/**
- * ElggMetadata
- * This class describes metadata that can be attached to ElggEntities.
- *
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-class ElggMetadata extends ElggExtender {
- /**
- * Construct a new site object, optionally from a given id value or row.
- *
- * @param mixed $id
- */
- function __construct($id = null) {
- $this->attributes = array();
-
- if (!empty($id)) {
- // Create from db row
- if ($id instanceof stdClass) {
- $metadata = $id;
- } else {
- $metadata = get_metadata($id);
- }
+require_once 'extender.php';
- if ($metadata) {
- $objarray = (array) $metadata;
- foreach($objarray as $key => $value) {
- $this->attributes[$key] = $value;
- }
- $this->attributes['type'] = "metadata";
- }
- }
- }
-
- /**
- * Class member get overloading
- *
- * @param string $name
- * @return mixed
- */
- function __get($name) {
- return $this->get($name);
- }
-
- /**
- * Class member set overloading
- *
- * @param string $name
- * @param mixed $value
- * @return mixed
- */
- function __set($name, $value) {
- return $this->set($name, $value);
- }
-
- /**
- * Determines whether or not the user can edit this piece of metadata
- *
- * @return true|false Depending on permissions
- */
- function canEdit() {
- if ($entity = get_entity($this->get('entity_guid'))) {
- return $entity->canEditMetadata($this);
- }
- return false;
- }
-
- /**
- * Save matadata object
- *
- * @return int the metadata object id
- */
- function save() {
- if ($this->id > 0) {
- return update_metadata($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
- } else {
- $this->id = create_metadata($this->entity_guid, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
- if (!$this->id) {
- throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));
- }
- return $this->id;
- }
- }
-
- /**
- * Delete a given metadata.
- */
- function delete() {
- return delete_metadata($this->id);
- }
-
- /**
- * Get a url for this item of metadata.
- *
- * @return string
- */
- public function getURL() {
- return get_metadata_url($this->id);
- }
-
- // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * For a given ID, return the object associated with it.
- * This is used by the river functionality primarily.
- * This is useful for checking access permissions etc on objects.
- */
- public function getObjectFromID($id) {
- return get_metadata($id);
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggMetadata.php';
/**
* Convert a database row to a new ElggMetadata
diff --git a/engine/lib/objects.php b/engine/lib/objects.php
index 63376c72d..1c7f1640c 100644
--- a/engine/lib/objects.php
+++ b/engine/lib/objects.php
@@ -10,203 +10,7 @@
* @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.
diff --git a/engine/lib/opendd.php b/engine/lib/opendd.php
index c582e6f77..dae6bc9d0 100644
--- a/engine/lib/opendd.php
+++ b/engine/lib/opendd.php
@@ -11,287 +11,9 @@
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.
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index c2427c655..e89e6007a 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -23,61 +23,7 @@ $ENABLED_PLUGINS_CACHE = NULL;
*/
class PluginException extends Exception {}
-/**
- * @class ElggPlugin Object representing a plugin's settings for a given site.
- * This class is currently a stub, allowing a plugin to saving settings in an object's metadata for each site.
- * @author Curverider Ltd
- */
-class ElggPlugin extends ElggObject {
- protected function initialise_attributes() {
- parent::initialise_attributes();
-
- $this->attributes['subtype'] = "plugin";
- }
-
- public function __construct($guid = null) {
- parent::__construct($guid);
- }
-
- /**
- * Override entity get and sets in order to save data to private data store.
- */
- public function get($name) {
- // See if its in our base attribute
- if (isset($this->attributes[$name])) {
- return $this->attributes[$name];
- }
-
- // No, so see if its in the private data store.
- // get_private_setting() returns false if it doesn't exist
- $meta = get_private_setting($this->guid, $name);
-
- if ($meta === false) {
- // Can't find it, so return null
- return NULL;
- }
-
- return $meta;
- }
-
- /**
- * Override entity get and sets in order to save data to private data store.
- */
- public function set($name, $value) {
- if (array_key_exists($name, $this->attributes)) {
- // Check that we're not trying to change the guid!
- if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) {
- return false;
- }
-
- $this->attributes[$name] = $value;
- } else {
- return set_private_setting($this->guid, $name, $value);
- }
-
- return true;
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggPlugin.php';
/**
* Returns a list of plugins to load, in the order that they should be loaded.
diff --git a/engine/lib/relationships.php b/engine/lib/relationships.php
index dd8a2b188..81d18d1ca 100644
--- a/engine/lib/relationships.php
+++ b/engine/lib/relationships.php
@@ -9,292 +9,7 @@
* @link http://elgg.org/
*/
-/**
- * Relationship class.
- *
- * @author Curverider Ltd
- * @package Elgg
- * @subpackage Core
- */
-class ElggRelationship implements
- Importable,
- Exportable,
- Loggable, // Can events related to this object class be logged
- Iterator, // Override foreach behaviour
- ArrayAccess // Override for array access
- {
- /**
- * This contains the site's main properties (id, etc)
- * @var array
- */
- protected $attributes;
-
- /**
- * Construct a new site object, optionally from a given id value or row.
- *
- * @param mixed $id
- */
- function __construct($id = null) {
- $this->attributes = array();
-
- if (!empty($id)) {
- if ($id instanceof stdClass) {
- $relationship = $id; // Create from db row
- } else {
- $relationship = get_relationship($id);
- }
-
- if ($relationship) {
- $objarray = (array) $relationship;
- foreach($objarray as $key => $value) {
- $this->attributes[$key] = $value;
- }
- }
- }
- }
-
- /**
- * Class member get overloading
- *
- * @param string $name
- * @return mixed
- */
- function __get($name) {
- if (isset($this->attributes[$name])) {
- return $this->attributes[$name];
- }
-
- return null;
- }
-
- /**
- * Class member set overloading
- *
- * @param string $name
- * @param mixed $value
- * @return mixed
- */
- function __set($name, $value) {
- $this->attributes[$name] = $value;
- return true;
- }
-
- /**
- * Save the relationship
- *
- * @return int the relationship id
- */
- public function save() {
- if ($this->id > 0) {
- delete_relationship($this->id);
- }
-
- $this->id = add_entity_relationship($this->guid_one, $this->relationship, $this->guid_two);
- if (!$this->id) {
- throw new IOException(sprintf(elgg_echo('IOException:UnableToSaveNew'), get_class()));
- }
-
- return $this->id;
- }
-
- /**
- * Delete a given relationship.
- */
- public function delete() {
- return delete_relationship($this->id);
- }
-
- /**
- * Get a URL for this relationship.
- *
- * @return string
- */
- public function getURL() {
- return get_relationship_url($this->id);
- }
-
- // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an array of fields which can be exported.
- */
- public function getExportableValues() {
- return array(
- 'id',
- 'guid_one',
- 'relationship',
- 'guid_two'
- );
- }
-
- /**
- * Export this relationship
- *
- * @return array
- */
- public function export() {
- $uuid = get_uuid_from_object($this);
- $relationship = new ODDRelationship(
- guid_to_uuid($this->guid_one),
- $this->relationship,
- guid_to_uuid($this->guid_two)
- );
-
- $relationship->setAttribute('uuid', $uuid);
-
- return $relationship;
- }
-
- // IMPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Import a relationship
- *
- * @param array $data
- * @param int $version
- * @return ElggRelationship
- * @throws ImportException
- */
- public function import(ODD $data) {
- if (!($element instanceof ODDRelationship)) {
- throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass'));
- }
-
- $uuid_one = $data->getAttribute('uuid1');
- $uuid_two = $data->getAttribute('uuid2');
-
- // See if this entity has already been imported, if so then we need to link to it
- $entity1 = get_entity_from_uuid($uuid_one);
- $entity2 = get_entity_from_uuid($uuid_two);
- if (($entity1) && ($entity2)) {
- // Set the item ID
- $this->attributes['guid_one'] = $entity1->getGUID();
- $this->attributes['guid_two'] = $entity2->getGUID();
-
- // Map verb to relationship
- //$verb = $data->getAttribute('verb');
- //$relationship = get_relationship_from_verb($verb);
- $relationship = $data->getAttribute('type');
-
- if ($relationship) {
- $this->attributes['relationship'] = $relationship;
- // save
- $result = $this->save();
- if (!$result) {
- throw new ImportException(sprintf(elgg_echo('ImportException:ProblemSaving'), get_class()));
- }
-
- return $this;
- }
- }
- }
-
- // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an identification for the object for storage in the system log.
- * This id must be an integer.
- *
- * @return int
- */
- public function getSystemLogID() {
- return $this->id;
- }
-
- /**
- * Return the class name of the object.
- */
- public function getClassName() {
- return get_class($this);
- }
-
- /**
- * For a given ID, return the object associated with it.
- * This is used by the river functionality primarily.
- * This is useful for checking access permissions etc on objects.
- */
- public function getObjectFromID($id) {
- return get_relationship($id);
- }
-
- /**
- * Return the GUID of the owner of this object.
- */
- public function getObjectOwnerGUID() {
- return $this->owner_guid;
- }
-
- /**
- * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc
- */
- public function getType() {
- return 'relationship';
- }
-
- /**
- * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.
- */
- public function getSubtype() {
- return $this->relationship;
- }
-
- // ITERATOR INTERFACE //////////////////////////////////////////////////////////////
- /*
- * This lets an entity's attributes be displayed using foreach as a normal array.
- * Example: http://www.sitepoint.com/print/php5-standard-library
- */
-
- private $valid = FALSE;
-
- function rewind() {
- $this->valid = (FALSE !== reset($this->attributes));
- }
-
- function current() {
- return current($this->attributes);
- }
-
- function key() {
- return key($this->attributes);
- }
-
- function next() {
- $this->valid = (FALSE !== next($this->attributes));
- }
-
- function valid() {
- return $this->valid;
- }
-
- // ARRAY ACCESS INTERFACE //////////////////////////////////////////////////////////
- /*
- * This lets an entity's attributes be accessed like an associative array.
- * Example: http://www.sitepoint.com/print/php5-standard-library
- */
-
- function offsetSet($key, $value) {
- if ( array_key_exists($key, $this->attributes) ) {
- $this->attributes[$key] = $value;
- }
- }
-
- function offsetGet($key) {
- if ( array_key_exists($key, $this->attributes) ) {
- return $this->attributes[$key];
- }
- }
-
- function offsetUnset($key) {
- if ( array_key_exists($key, $this->attributes) ) {
- $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects
- }
- }
-
- function offsetExists($offset) {
- return array_key_exists($offset, $this->attributes);
- }
-}
-
+require_once dirname(dirname(__FILE__)).'/classes/ElggRelationship.php';
/**
* Convert a database row to a new ElggRelationship
diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php
index 428a521a2..f2a534294 100644
--- a/engine/lib/sessions.php
+++ b/engine/lib/sessions.php
@@ -13,100 +13,7 @@
/** 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';
/**
diff --git a/engine/lib/sites.php b/engine/lib/sites.php
index 23a922757..ee556e86c 100644
--- a/engine/lib/sites.php
+++ b/engine/lib/sites.php
@@ -9,304 +9,7 @@
* @link http://elgg.org/
*/
-/**
- * ElggSite
- * Representation of a "site" in the system.
- * @author Curverider Ltd <info@elgg.com>
- * @package Elgg
- * @subpackage Core
- */
-class ElggSite extends ElggEntity {
- /**
- * Initialise the attributes array.
- * This is vital to distinguish between metadata and base parameters.
- *
- * Place your base parameters here.
- */
- protected function initialise_attributes() {
- parent::initialise_attributes();
-
- $this->attributes['type'] = "site";
- $this->attributes['name'] = "";
- $this->attributes['description'] = "";
- $this->attributes['url'] = "";
- $this->attributes['tables_split'] = 2;
- }
-
- /**
- * Construct a new site object, optionally from a given id value.
- *
- * @param mixed $guid If an int, load that GUID.
- * If a db row then will attempt to load the rest of the data.
- * @throws Exception if there was a problem creating the site.
- */
- function __construct($guid = null) {
- $this->initialise_attributes();
-
- if (!empty($guid)) {
- // Is $guid is a DB row - either a entity row, or a site table row.
- if ($guid instanceof stdClass) {
- // Load the rest
- if (!$this->load($guid->guid)) {
- throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));
- }
- }
-
- // Is $guid is an ElggSite? Use a copy constructor
- else if ($guid instanceof ElggSite) {
- elgg_deprecated_notice('This type of usage of the ElggSite constructor was deprecated. Please use the clone method.', 1.7);
-
- foreach ($guid->attributes as $key => $value) {
- $this->attributes[$key] = $value;
- }
- }
-
- // Is this is an ElggEntity but not an ElggSite = ERROR!
- else if ($guid instanceof ElggEntity) {
- throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggSite'));
- }
-
- // See if this is a URL
- else if (strpos($guid, "http") !== false) {
- $guid = get_site_by_url($guid);
- foreach ($guid->attributes as $key => $value) {
- $this->attributes[$key] = $value;
- }
- }
-
- // We assume if we have got this far, $guid is an int
- else if (is_numeric($guid)) {
- if (!$this->load($guid)) {
- throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
- }
- }
-
- else {
- throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
- }
- }
- }
-
- /**
- * Override the load function.
- * This function will ensure that all data is loaded (were possible), so
- * if only part of the ElggSite is loaded, it'll load the rest.
- *
- * @param int $guid
- */
- protected function load($guid) {
- // Test to see if we have the generic stuff
- if (!parent::load($guid)) {
- return false;
- }
-
- // Check the type
- if ($this->attributes['type']!='site') {
- throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
- }
-
- // Load missing data
- $row = get_site_entity_as_row($guid);
- if (($row) && (!$this->isFullyLoaded())) {
- // If $row isn't a cached copy then increment the counter
- $this->attributes['tables_loaded'] ++;
- }
-
- // Now put these into the attributes array as core values
- $objarray = (array) $row;
- foreach($objarray as $key => $value) {
- $this->attributes[$key] = $value;
- }
-
- return true;
- }
-
- /**
- * Override the save function.
- */
- public function save() {
- // Save generic stuff
- if (!parent::save()) {
- return false;
- }
-
- // Now save specific stuff
- return create_site_entity($this->get('guid'), $this->get('name'), $this->get('description'), $this->get('url'));
- }
-
- /**
- * Delete this site.
- */
- public function delete() {
- global $CONFIG;
- if ($CONFIG->site->getGUID() == $this->guid) {
- throw new SecurityException('SecurityException:deletedisablecurrentsite');
- }
-
- return parent::delete();
- }
-
- /**
- * Disable override to add safety rail.
- *
- * @param unknown_type $reason
- */
- public function disable($reason = "") {
- global $CONFIG;
-
- if ($CONFIG->site->getGUID() == $this->guid) {
- throw new SecurityException('SecurityException:deletedisablecurrentsite');
- }
-
- return parent::disable($reason);
- }
-
- /**
- * Return a list of users using this site.
- *
- * @param int $limit
- * @param int $offset
- * @return array of ElggUsers
- */
- public function getMembers($limit = 10, $offset = 0) {
- get_site_members($this->getGUID(), $limit, $offset);
- }
-
- /**
- * Add a user to the site.
- *
- * @param int $user_guid
- */
- public function addUser($user_guid) {
- return add_site_user($this->getGUID(), $user_guid);
- }
-
- /**
- * Remove a site user.
- *
- * @param int $user_guid
- */
- public function removeUser($user_guid) {
- return remove_site_user($this->getGUID(), $user_guid);
- }
-
- /**
- * Get an array of member ElggObjects.
- *
- * @param string $subtype
- * @param int $limit
- * @param int $offset
- */
- public function getObjects($subtype="", $limit = 10, $offset = 0) {
- get_site_objects($this->getGUID(), $subtype, $limit, $offset);
- }
-
- /**
- * Add an object to the site.
- *
- * @param int $user_id
- */
- public function addObject($object_guid) {
- return add_site_object($this->getGUID(), $object_guid);
- }
-
- /**
- * Remove a site user.
- *
- * @param int $user_id
- */
- public function removeObject($object_guid) {
- return remove_site_object($this->getGUID(), $object_guid);
- }
-
- /**
- * Get the collections associated with a site.
- *
- * @param string $type
- * @param int $limit
- * @param int $offset
- * @return unknown
- */
- public function getCollections($subtype="", $limit = 10, $offset = 0) {
- get_site_collections($this->getGUID(), $subtype, $limit, $offset);
- }
-
- // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an array of fields which can be exported.
- */
- public function getExportableValues() {
- return array_merge(parent::getExportableValues(), array(
- 'name',
- 'description',
- 'url',
- ));
- }
-
- public function check_walled_garden() {
- global $CONFIG;
-
- if ($CONFIG->walled_garden && !isloggedin()) {
- // hook into the index system call at the highest priority
- register_plugin_hook('index', 'system', 'elgg_walled_garden_index', 1);
-
- if (!$this->is_public_page()) {
- register_error(elgg_echo('loggedinrequired'));
- forward();
- }
- }
- }
-
- public function is_public_page($url='') {
- global $CONFIG;
-
- if (empty($url)) {
- $url = current_page_url();
-
- // do not check against URL queries
- if ($pos = strpos($url, '?')) {
- $url = substr($url, 0, $pos);
- }
- }
-
- // always allow index page
- if ($url == $CONFIG->url) {
- return TRUE;
- }
-
- // default public pages
- $defaults = array(
- 'action/login',
- 'pg/register',
- 'action/register',
- 'account/forgotten_password\.php',
- 'action/user/requestnewpassword',
- 'pg/resetpassword',
- 'upgrade\.php',
- 'xml-rpc\.php',
- 'mt/mt-xmlrpc\.cgi',
- '_css/css\.css',
- '_css/js\.php',
- );
-
- // include a hook for plugin authors to include public pages
- $plugins = trigger_plugin_hook('public_pages', 'walled_garden', NULL, array());
-
- // lookup admin-specific public pages
-
- // allow public pages
- foreach (array_merge($defaults, $plugins) as $public) {
- $pattern = "`^{$CONFIG->url}$public/*$`i";
- if (preg_match($pattern, $url)) {
- return TRUE;
- }
- }
-
- // non-public page
- return FALSE;
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggSite.php';
/**
* Return the site specific details of a site by a row.
diff --git a/engine/lib/system_log.php b/engine/lib/system_log.php
index 74597ed5d..9a94fb94e 100644
--- a/engine/lib/system_log.php
+++ b/engine/lib/system_log.php
@@ -9,54 +9,7 @@
* @link http://elgg.org/
*/
-/**
- * Interface that provides an interface which must be implemented by all objects wishing to be
- * recorded in the system log (and by extension the river).
- *
- * This interface defines a set of methods that permit the system log functions to hook in and retrieve
- * the necessary information and to identify what events can actually be logged.
- *
- * To have events involving your object to be logged simply implement this interface.
- *
- * @author Curverider Ltd
- */
-interface Loggable {
- /**
- * Return an identification for the object for storage in the system log.
- * This id must be an integer.
- *
- * @return int
- */
- public function getSystemLogID();
-
- /**
- * Return the class name of the object.
- * Added as a function because get_class causes errors for some reason.
- */
- public function getClassName();
-
- /**
- * Return the type of the object - eg. object, group, user, relationship, metadata, annotation etc
- */
- public function getType();
-
- /**
- * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.
- */
- public function getSubtype();
-
- /**
- * For a given ID, return the object associated with it.
- * This is used by the river functionality primarily.
- * This is useful for checking access permissions etc on objects.
- */
- public function getObjectFromID($id);
-
- /**
- * Return the GUID of the owner of this object.
- */
- public function getObjectOwnerGUID();
-}
+require_once dirname(dirname(__FILE__)).'/classes/Loggable.php';
/**
* Retrieve the system log based on a number of parameters.
diff --git a/engine/lib/users.php b/engine/lib/users.php
index 3722c8ed1..03d0d06c4 100644
--- a/engine/lib/users.php
+++ b/engine/lib/users.php
@@ -15,432 +15,7 @@ $USERNAME_TO_GUID_MAP_CACHE = array();
/// Map a user code to a cached GUID
$CODE_TO_GUID_MAP_CACHE = array();
-/**
- * ElggUser
- *
- * Representation of a "user" in the system.
- *
- * @package Elgg
- * @subpackage Core
- */
-class ElggUser extends ElggEntity
- implements Friendable {
- /**
- * Initialise the attributes array.
- * This is vital to distinguish between metadata and base parameters.
- *
- * Place your base parameters here.
- */
- protected function initialise_attributes() {
- parent::initialise_attributes();
-
- $this->attributes['type'] = "user";
- $this->attributes['name'] = "";
- $this->attributes['username'] = "";
- $this->attributes['password'] = "";
- $this->attributes['salt'] = "";
- $this->attributes['email'] = "";
- $this->attributes['language'] = "";
- $this->attributes['code'] = "";
- $this->attributes['banned'] = "no";
- $this->attributes['admin'] = 'no';
- $this->attributes['tables_split'] = 2;
- }
-
- /**
- * Construct a new user entity, optionally from a given id value.
- *
- * @param mixed $guid If an int, load that GUID.
- * If a db row then will attempt to load the rest of the data.
- * @throws Exception if there was a problem creating the user.
- */
- function __construct($guid = null) {
- $this->initialise_attributes();
-
- if (!empty($guid)) {
- // Is $guid is a DB row - either a entity row, or a user table row.
- if ($guid instanceof stdClass) {
- // Load the rest
- if (!$this->load($guid->guid)) {
- throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid));
- }
- }
-
- // See if this is a username
- else if (is_string($guid)) {
- $guid = get_user_by_username($guid);
- foreach ($guid->attributes as $key => $value) {
- $this->attributes[$key] = $value;
- }
- }
-
- // Is $guid is an ElggUser? Use a copy constructor
- else if ($guid instanceof ElggUser) {
- elgg_deprecated_notice('This type of usage of the ElggUser constructor was deprecated. Please use the clone method.', 1.7);
-
- foreach ($guid->attributes as $key => $value) {
- $this->attributes[$key] = $value;
- }
- }
-
- // Is this is an ElggEntity but not an ElggUser = ERROR!
- else if ($guid instanceof ElggEntity) {
- throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggUser'));
- }
-
- // We assume if we have got this far, $guid is an int
- else if (is_numeric($guid)) {
- if (!$this->load($guid)) {
- throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
- }
- }
-
- else {
- throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
- }
- }
- }
-
- /**
- * Override the load function.
- * This function will ensure that all data is loaded (were possible), so
- * if only part of the ElggUser is loaded, it'll load the rest.
- *
- * @param int $guid
- * @return true|false
- */
- protected function load($guid) {
- // Test to see if we have the generic stuff
- if (!parent::load($guid)) {
- return false;
- }
-
- // Check the type
- if ($this->attributes['type']!='user') {
- throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
- }
-
- // Load missing data
- $row = get_user_entity_as_row($guid);
- if (($row) && (!$this->isFullyLoaded())) {
- // If $row isn't a cached copy then increment the counter
- $this->attributes['tables_loaded'] ++;
- }
-
- // Now put these into the attributes array as core values
- $objarray = (array) $row;
- foreach($objarray as $key => $value) {
- $this->attributes[$key] = $value;
- }
-
- return true;
- }
-
- /**
- * Saves this user to the database.
- * @return true|false
- */
- public function save() {
- // Save generic stuff
- if (!parent::save()) {
- return false;
- }
-
- // Now save specific stuff
- return create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'), $this->get('password'), $this->get('salt'), $this->get('email'), $this->get('language'), $this->get('code'));
- }
-
- /**
- * User specific override of the entity delete method.
- *
- * @return bool
- */
- public function delete() {
- global $USERNAME_TO_GUID_MAP_CACHE, $CODE_TO_GUID_MAP_CACHE;
-
- // clear cache
- if (isset($USERNAME_TO_GUID_MAP_CACHE[$this->username])) {
- unset($USERNAME_TO_GUID_MAP_CACHE[$this->username]);
- }
- if (isset($CODE_TO_GUID_MAP_CACHE[$this->code])) {
- unset($CODE_TO_GUID_MAP_CACHE[$this->code]);
- }
-
- // Delete owned data
- clear_annotations_by_owner($this->guid);
- clear_metadata_by_owner($this->guid);
- clear_user_files($this);
-
- // Delete entity
- return parent::delete();
- }
-
- /**
- * Ban this user.
- *
- * @param string $reason Optional reason
- */
- public function ban($reason = "") {
- return ban_user($this->guid, $reason);
- }
-
- /**
- * Unban this user.
- */
- public function unban() {
- return unban_user($this->guid);
- }
-
- /**
- * Is this user banned or not?
- *
- * @return bool
- */
- public function isBanned() {
- return $this->banned == 'yes';
- }
-
- /**
- * Is this user admin?
- *
- * @return bool
- */
- public function isAdmin() {
-
- // for backward compatibility we need to pull this directly
- // from the attributes instead of using the magic methods.
- // this can be removed in 1.9
- // return $this->admin == 'yes';
- return $this->attributes['admin'] == 'yes';
- }
-
- /**
- * Make the user an admin
- *
- * @return bool
- */
- public function makeAdmin() {
- if (make_user_admin($this->guid)) {
- $this->attributes['admin'] = 'yes';
- return TRUE;
- }
- return FALSE;
- }
-
- /**
- * Remove the admin flag for user
- *
- * @return bool
- */
- public function removeAdmin() {
- if (remove_user_admin($this->guid)) {
- $this->attributes['admin'] = 'no';
- return TRUE;
- }
- return FALSE;
- }
-
- /**
- * Get sites that this user is a member of
- *
- * @param string $subtype Optionally, the subtype of result we want to limit to
- * @param int $limit The number of results to return
- * @param int $offset Any indexing offset
- */
- function getSites($subtype="", $limit = 10, $offset = 0) {
- // return get_site_users($this->getGUID(), $subtype, $limit, $offset);
- return get_user_sites($this->getGUID(), $subtype, $limit, $offset);
- }
-
- /**
- * Add this user to a particular site
- *
- * @param int $site_guid The guid of the site to add it to
- * @return true|false
- */
- function addToSite($site_guid) {
- // return add_site_user($this->getGUID(), $site_guid);
- return add_site_user($site_guid, $this->getGUID());
- }
-
- /**
- * Remove this user from a particular site
- *
- * @param int $site_guid The guid of the site to remove it from
- * @return true|false
- */
- function removeFromSite($site_guid) {
- //return remove_site_user($this->getGUID(), $site_guid);
- return remove_site_user($site_guid, $this->getGUID());
- }
-
- /**
- * Adds a user to this user's friends list
- *
- * @param int $friend_guid The GUID of the user to add
- * @return true|false Depending on success
- */
- function addFriend($friend_guid) {
- return user_add_friend($this->getGUID(), $friend_guid);
- }
-
- /**
- * Removes a user from this user's friends list
- *
- * @param int $friend_guid The GUID of the user to remove
- * @return true|false Depending on success
- */
- function removeFriend($friend_guid) {
- return user_remove_friend($this->getGUID(), $friend_guid);
- }
-
- /**
- * Determines whether or not this user is a friend of the currently logged in user
- *
- * @return true|false
- */
- function isFriend() {
- return user_is_friend(get_loggedin_userid(), $this->getGUID());
- }
-
- /**
- * Determines whether this user is friends with another user
- *
- * @param int $user_guid The GUID of the user to check is on this user's friends list
- * @return true|false
- */
- function isFriendsWith($user_guid) {
- return user_is_friend($this->getGUID(), $user_guid);
- }
-
- /**
- * Determines whether or not this user is on another user's friends list
- *
- * @param int $user_guid The GUID of the user to check against
- * @return true|false
- */
- function isFriendOf($user_guid) {
- return user_is_friend($user_guid, $this->getGUID());
- }
-
- /**
- * Retrieves a list of this user's friends
- *
- * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all)
- * @param int $limit The number of users to retrieve
- * @param int $offset Indexing offset, if any
- * @return array|false Array of ElggUsers, or false, depending on success
- */
- function getFriends($subtype = "", $limit = 10, $offset = 0) {
- return get_user_friends($this->getGUID(), $subtype, $limit, $offset);
- }
-
- /**
- * Retrieves a list of people who have made this user a friend
- *
- * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all)
- * @param int $limit The number of users to retrieve
- * @param int $offset Indexing offset, if any
- * @return array|false Array of ElggUsers, or false, depending on success
- */
- function getFriendsOf($subtype = "", $limit = 10, $offset = 0) {
- return get_user_friends_of($this->getGUID(), $subtype, $limit, $offset);
- }
-
- /**
- * Get an array of ElggObjects owned by this user.
- *
- * @param string $subtype The subtype of the objects, if any
- * @param int $limit Number of results to return
- * @param int $offset Any indexing offset
- */
- public function getObjects($subtype="", $limit = 10, $offset = 0) {
- return get_user_objects($this->getGUID(), $subtype, $limit, $offset);
- }
-
- /**
- * Get an array of ElggObjects owned by this user's friends.
- *
- * @param string $subtype The subtype of the objects, if any
- * @param int $limit Number of results to return
- * @param int $offset Any indexing offset
- */
- public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) {
- return get_user_friends_objects($this->getGUID(), $subtype, $limit, $offset);
- }
-
- /**
- * Counts the number of ElggObjects owned by this user
- *
- * @param string $subtype The subtypes of the objects, if any
- * @return int The number of ElggObjects
- */
- public function countObjects($subtype = "") {
- return count_user_objects($this->getGUID(), $subtype);
- }
-
- /**
- * Get the collections associated with a user.
- *
- * @param string $subtype Optionally, the subtype of result we want to limit to
- * @param int $limit The number of results to return
- * @param int $offset Any indexing offset
- * @return unknown
- */
- public function getCollections($subtype="", $limit = 10, $offset = 0) {
- return get_user_collections($this->getGUID(), $subtype, $limit, $offset);
- }
-
- /**
- * If a user's owner is blank, return its own GUID as the owner
- *
- * @return int User GUID
- */
- function getOwner() {
- if ($this->owner_guid == 0) {
- return $this->getGUID();
- }
-
- return $this->owner_guid;
- }
-
- // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
-
- /**
- * Return an array of fields which can be exported.
- */
- public function getExportableValues() {
- return array_merge(parent::getExportableValues(), array(
- 'name',
- 'username',
- 'language',
- ));
- }
-
- // backward compatibility with admin flag
- // remove for 1.9
- public function __set($name, $value) {
- if ($name == 'admin' || $name == 'siteadmin') {
- elgg_deprecated_notice('The admin/siteadmin metadata are not longer used. Use ElggUser->makeAdmin() and ElggUser->removeAdmin().', '1.7.1');
-
- if ($value == 'yes' || $value == '1') {
- $this->makeAdmin();
- } else {
- $this->removeAdmin();
- }
- }
- return parent::__set($name, $value);
- }
-
- public function __get($name) {
- if ($name == 'admin' || $name == 'siteadmin') {
- elgg_deprecated_notice('The admin/siteadmin metadata are not longer used. Use ElggUser->isAdmin().', '1.7.1');
- return $this->isAdmin();
- }
-
- return parent::__get($name);
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggUser.php';
/**
* Return the user specific details of a user by a row.
diff --git a/engine/lib/widgets.php b/engine/lib/widgets.php
index 03524da62..210aa198f 100644
--- a/engine/lib/widgets.php
+++ b/engine/lib/widgets.php
@@ -8,57 +8,7 @@
* @link http://elgg.org/
*/
-/**
- * Override ElggObject in order to store widget data in ultra-private stores.
- */
-class ElggWidget extends ElggObject {
- protected function initialise_attributes() {
- parent::initialise_attributes();
-
- $this->attributes['subtype'] = "widget";
- }
-
- public function __construct($guid = null) {
- parent::__construct($guid);
- }
-
- /**
- * Override entity get and sets in order to save data to private data store.
- */
- public function get($name) {
- // See if its in our base attribute
- if (isset($this->attributes[$name])) {
- return $this->attributes[$name];
- }
-
- // No, so see if its in the private data store.
- $meta = get_private_setting($this->guid, $name);
- if ($meta) {
- return $meta;
- }
-
- // Can't find it, so return null
- return null;
- }
-
- /**
- * Override entity get and sets in order to save data to private data store.
- */
- public function set($name, $value) {
- if (array_key_exists($name, $this->attributes)) {
- // Check that we're not trying to change the guid!
- if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) {
- return false;
- }
-
- $this->attributes[$name] = $value;
- } else {
- return set_private_setting($this->guid, $name, $value);
- }
-
- return true;
- }
-}
+require_once dirname(dirname(__FILE__)).'/classes/ElggWidget.php';
/**
* Register a particular context for use with widgets.
diff --git a/engine/lib/xml-rpc.php b/engine/lib/xml-rpc.php
index 110dd76dd..79c3eba07 100644
--- a/engine/lib/xml-rpc.php
+++ b/engine/lib/xml-rpc.php
@@ -10,385 +10,24 @@
*/
// 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 ///////////////////////////////////////////////////////////////////////
diff --git a/engine/lib/xml.php b/engine/lib/xml.php
index b21fdd92b..f9c5985c9 100644
--- a/engine/lib/xml.php
+++ b/engine/lib/xml.php
@@ -9,25 +9,8 @@
* @link http://elgg.org/
*/
- /**
- * @class XmlElement
- * A class representing an XML element for import.
- */
- class XmlElement
- {
- /** The name of the element */
- public $name;
-
- /** The attributes */
- public $attributes;
-
- /** CData */
- public $content;
-
- /** Child elements */
- public $children;
- };
-
+ require_once dirname(dirname(__FILE__)).'/classes/XmlElement.php';
+
/**
* This function serialises an object recursively into an XML representation.
* The function attempts to call $data->export() which expects a stdClass in return, otherwise it will attempt to