diff options
author | ewinslow <ewinslow@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-09-06 02:42:09 +0000 |
---|---|---|
committer | ewinslow <ewinslow@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-09-06 02:42:09 +0000 |
commit | 76dac45ebaf104b312a8527a05424601ca9d520a (patch) | |
tree | 7440558a893ebf1d3816829ecbb96c3b0df9b4f0 /engine | |
parent | 9e8baf614938dfd1687ddce39b409c3c0e5c5753 (diff) | |
download | elgg-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
Diffstat (limited to 'engine')
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 |