]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Standardized gobs of files.
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 15 Oct 2009 04:41:46 +0000 (04:41 +0000)
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 15 Oct 2009 04:41:46 +0000 (04:41 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@3548 36083f99-b078-4883-b0ff-0f9b5a30f544

37 files changed:
engine/lib/calendar.php
engine/lib/configuration.php
engine/lib/cron.php
engine/lib/exceptions.php
engine/lib/export.php
engine/lib/extender.php
engine/lib/filestore.php
engine/lib/group.php
engine/lib/input.php
engine/lib/install.php
engine/lib/languages.php
engine/lib/location.php
engine/lib/mb_wrapper.php
engine/lib/memcache.php
engine/lib/metadata.php
engine/lib/metastrings.php
engine/lib/notification.php
engine/lib/objects.php
engine/lib/opendd.php
engine/lib/pagehandler.php
engine/lib/pageowner.php
engine/lib/pam.php
engine/lib/ping.php
engine/lib/plugins.php
engine/lib/query.php
engine/lib/relationships.php
engine/lib/river2.php
engine/lib/search.php
engine/lib/sites.php
engine/lib/social.php
engine/lib/statistics.php
engine/lib/system_log.php
engine/lib/tags.php
engine/lib/users.php
engine/lib/usersettings.php
engine/lib/version.php
engine/lib/widgets.php

index 1f25eda447ae3d7f1cf654e5b97a09b398e9761d..a9d6dfadff4a01914171fc685f9d3e856af8789a 100644 (file)
@@ -1,93 +1,96 @@
 <?php
+/**
+ * Elgg calendar / entity / event functions.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
+/**
+ * Calendar interface for events.
+ *
+ */
+interface Notable {
        /**
-        * Elgg calendar / entity / event functions.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
-        * @link http://elgg.org/
-        */
-
-       /**
-        * Calendar interface for events.
+        * 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.
         */
-       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();
-       }
-       
-       /**
-        * Return a timestamp for the start of a given day (defaults today).
-        *
-        */
-       function get_day_start($day = null, $month = null, $year = null) { return mktime(0,0,0,$month,$day,$year); }
-       
+       public function setCalendarTimeAndDuration($hour = NULL, $minute = NULL, $second = NULL, $day = NULL, $month = NULL, $year = NULL, $duration = NULL);
+
        /**
-        * Return a timestamp for the end of a given day (defaults today).
-        *
+        * Return the start timestamp.
         */
-       function get_day_end($day = null, $month = null, $year = null) { return mktime(23,59,59,$month,$day,$year); }
-       
+       public function getCalendarStartTime();
+
        /**
-        * Return the notable entities for a given time period.
-        *
-        * @param int $start_time The start time as a unix timestamp.
-        * @param int $end_time The end time as a unix timestamp.
-        * @param string $type The type of entity (eg "user", "object" etc)
-        * @param string $subtype The arbitrary subtype of the entity
-        * @param int $owner_guid The GUID of the owning user
-        * @param string $order_by The field to order by; by default, time_created desc
-        * @param int $limit The number of entities to return; 10 by default
-        * @param int $offset The indexing offset, 0 by default
-        * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param int|array $container_guid The container or containers to get entities from (default: all containers).
+        * Return the end timestamp.
         */
-       function get_notable_entities($start_time, $end_time, $type = "", $subtype = "", $owner_guid = 0, $order_by = "asc", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = null)
-       {
-               global $CONFIG;
-               
-               if ($subtype === false || $subtype === null || $subtype === 0)
-                       return false;
-
-               $start_time = (int)$start_time;
-               $end_time = (int)$end_time;
-               $order_by = sanitise_string($order_by);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               $where = array();
-               
-               if (is_array($type)) {                  
-                       $tempwhere = "";
-                       if (sizeof($type))
+       public function getCalendarEndTime();
+}
+
+/**
+ * Return a timestamp for the start of a given day (defaults today).
+ *
+ */
+function get_day_start($day = null, $month = null, $year = null) {
+       return mktime(0, 0, 0, $month, $day, $year);
+}
+
+/**
+ * Return a timestamp for the end of a given day (defaults today).
+ *
+ */
+function get_day_end($day = null, $month = null, $year = null) {
+       return mktime(23, 59, 59, $month, $day, $year);
+}
+
+/**
+ * Return the notable entities for a given time period.
+ *
+ * @param int $start_time The start time as a unix timestamp.
+ * @param int $end_time The end time as a unix timestamp.
+ * @param string $type The type of entity (eg "user", "object" etc)
+ * @param string $subtype The arbitrary subtype of the entity
+ * @param int $owner_guid The GUID of the owning user
+ * @param string $order_by The field to order by; by default, time_created desc
+ * @param int $limit The number of entities to return; 10 by default
+ * @param int $offset The indexing offset, 0 by default
+ * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param int|array $container_guid The container or containers to get entities from (default: all containers).
+ */
+function get_notable_entities($start_time, $end_time, $type = "", $subtype = "", $owner_guid = 0, $order_by = "asc", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = null) {
+       global $CONFIG;
+
+       if ($subtype === false || $subtype === null || $subtype === 0) {
+               return false;
+       }
+
+       $start_time = (int)$start_time;
+       $end_time = (int)$end_time;
+       $order_by = sanitise_string($order_by);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $where = array();
+
+       if (is_array($type)) {
+               $tempwhere = "";
+               if (sizeof($type)) {
                        foreach($type as $typekey => $subtypearray) {
                                foreach($subtypearray as $subtypeval) {
                                        $typekey = sanitise_string($typekey);
                                        }
                                        if (!empty($tempwhere)) $tempwhere .= " or ";
                                        $tempwhere .= "(e.type = '{$typekey}' and e.subtype = {$subtypeval})";
-                               }                                                               
+                               }
                        }
-                       if (!empty($tempwhere)) $where[] = "({$tempwhere})";
-                       
-               } else {
-               
-                       $type = sanitise_string($type);
-                       $subtype = get_subtype_id($type, $subtype);
-                       
-                       if ($type != "")
-                               $where[] = "e.type='$type'";
-                       if ($subtype!=="")
-                               $where[] = "e.subtype=$subtype";
-                               
                }
-
-               if ($owner_guid != "") {
-                       if (!is_array($owner_guid)) {
-                               $owner_array = array($owner_guid);
-                               $owner_guid = (int) $owner_guid;
-                               $where[] = "e.owner_guid = '$owner_guid'";
-                       } else if (sizeof($owner_guid) > 0) {
-                               $owner_array = array_map('sanitise_int', $owner_guid);
-                               // Cast every element to the owner_guid array to int
-                               $owner_guid = implode(",",$owner_guid); //
-                               $where[] = "e.owner_guid in ({$owner_guid})" ; //
-                       }
-                       if (is_null($container_guid)) {
-                               $container_guid = $owner_array;
-                       }
+               if (!empty($tempwhere)) {
+                       $where[] = "({$tempwhere})";
                }
-               
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-                       
-               if (!is_null($container_guid)) {
-                       if (is_array($container_guid)) {
-                               foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val;
-                               $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")";
-                       } else {
-                               $container_guid = (int) $container_guid;
-                               $where[] = "e.container_guid = {$container_guid}";
-                       }
-               }       
-       
-               // Add the calendar stuff
-               $cal_join = "
-                       JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id
-                       
-                       JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id
-               ";      
-               $where[] = "cal_start_name.string='calendar_start'";
-               $where[] = "cal_start_value.string>=$start_time";
-               $where[] = "cal_end_name.string='calendar_end'";
-               $where[] = "cal_end_value.string <= $end_time";
-               
-               
-               if (!$count) {
-                       $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $cal_join where ";
-               } else {
-                       $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $cal_join where ";
+       } else {
+               $type = sanitise_string($type);
+               $subtype = get_subtype_id($type, $subtype);
+
+               if ($type != "") {
+                       $where[] = "e.type='$type'";
                }
-               foreach ($where as $w)
-                       $query .= " $w and ";
-                       
-               $query .= get_access_sql_suffix('e'); // Add access controls
-               
-               if (!$count) {
-                       $query .= " order by n.calendar_start $order_by";
-                       if ($limit) $query .= " limit $offset, $limit"; // Add order and limit
-                       $dt = get_data($query, "entity_row_to_elggstar");
-                       return $dt;
-               } else {
-                       $total = get_data_row($query);
-                       return $total->total;
+
+               if ($subtype!=="") {
+                       $where[] = "e.subtype=$subtype";
                }
-               
        }
-       
-       /**
-        * Return the notable entities for a given time period based on an item of metadata.
-        *
-        * @param int $start_time The start time as a unix timestamp.
-        * @param int $end_time The end time as a unix timestamp.
-        * @param mixed $meta_name 
-        * @param mixed $meta_value
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
-        * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
-        * 
-        * @return int|array A list of entities, or a count if $count is set to true
-        */
-       function get_notable_entities_from_metadata($start_time, $end_time, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false)
-       {
-               global $CONFIG;
-               
-               $meta_n = get_metastring_id($meta_name);
-               $meta_v = get_metastring_id($meta_value);
-                       
-               $start_time = (int)$start_time;
-               $end_time = (int)$end_time;
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if ($order_by == "") $order_by = "e.time_created desc";
-               $order_by = sanitise_string($order_by);
-               $site_guid = (int) $site_guid;
-               if ((is_array($owner_guid) && (count($owner_guid)))) {
-                       foreach($owner_guid as $key => $guid) {
-                               $owner_guid[$key] = (int) $guid;
-                       }
-               } else {
+
+       if ($owner_guid != "") {
+               if (!is_array($owner_guid)) {
+                       $owner_array = array($owner_guid);
                        $owner_guid = (int) $owner_guid;
+                       $where[] = "e.owner_guid = '$owner_guid'";
+               } else if (sizeof($owner_guid) > 0) {
+                       $owner_array = array_map('sanitise_int', $owner_guid);
+                       // Cast every element to the owner_guid array to int
+                       $owner_guid = implode(",",$owner_guid); //
+                       $where[] = "e.owner_guid in ({$owner_guid})" ; //
                }
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               //$access = get_access_list();
-                       
-               $where = array();
-               
-               if ($entity_type!="")
-                       $where[] = "e.type='$entity_type'";
-               if ($entity_subtype)
-                       $where[] = "e.subtype=$entity_subtype";
-               if ($meta_name!="")
-                       $where[] = "m.name_id='$meta_n'";
-               if ($meta_value!="")
-                       $where[] = "m.value_id='$meta_v'";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               if (is_array($owner_guid)) {
-                       $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
-               } else if ($owner_guid > 0)
-                       $where[] = "e.container_guid = {$owner_guid}";
-                       
-               // Add the calendar stuff
-               $cal_join = "
-                       JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id
-                       
-                       JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id
-               ";      
-               $where[] = "cal_start_name.string='calendar_start'";
-               $where[] = "cal_start_value.string>=$start_time";
-               $where[] = "cal_end_name.string='calendar_end'";
-               $where[] = "cal_end_value.string <= $end_time";
-               
-               if (!$count) {
-                       $query = "SELECT distinct e.* "; 
-               } else {
-                       $query = "SELECT count(distinct e.guid) as total ";
+               if (is_null($container_guid)) {
+                       $container_guid = $owner_array;
                }
-                       
-               $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid $cal_join where";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
+       }
+
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       if (!is_null($container_guid)) {
+               if (is_array($container_guid)) {
+                       foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val;
+                       $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")";
                } else {
-                       if ($row = get_data_row($query))
-                               return $row->total;
+                       $container_guid = (int) $container_guid;
+                       $where[] = "e.container_guid = {$container_guid}";
                }
-               return false;
-               
        }
-       
-       /**
-        * Return the notable entities for a given time period based on their relationship.
-        *
-        * @param int $start_time The start time as a unix timestamp.
-        * @param int $end_time The end time as a unix timestamp.
-        * @param string $relationship The relationship eg "friends_of"
-        * @param int $relationship_guid The guid of the entity to use query
-        * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
-        * @param string $type 
-        * @param string $subtype
-        * @param int $owner_guid
-        * @param string $order_by
-        * @param int $limit
-        * @param int $offset
-        * @param boolean $count Set to true if you want to count the number of entities instead (default false)
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @return array|int|false An array of entities, or the number of entities, or false on failure
-        */
-       function get_noteable_entities_from_relationship($start_time, $end_time, $relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0)
-       {
-               global $CONFIG;
-               
-               $start_time = (int)$start_time;
-               $end_time = (int)$end_time;
-               $relationship = sanitise_string($relationship);
-               $relationship_guid = (int)$relationship_guid;
-               $inverse_relationship = (bool)$inverse_relationship;
-               $type = sanitise_string($type);
-               $subtype = get_subtype_id($type, $subtype);
-               $owner_guid = (int)$owner_guid;
-               if ($order_by == "") $order_by = "time_created desc";
-               $order_by = sanitise_string($order_by);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-               
-               //$access = get_access_list();
-               
-               $where = array();
-               
-               if ($relationship!="")
-                       $where[] = "r.relationship='$relationship'";
-               if ($relationship_guid)
-                       $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'");
-               if ($type != "")
-                       $where[] = "e.type='$type'";
-               if ($subtype)
-                       $where[] = "e.subtype=$subtype";
-               if ($owner_guid != "")
-                       $where[] = "e.container_guid='$owner_guid'";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-                       
-               // Add the calendar stuff
-               $cal_join = "
-                       JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id
-                       
-                       JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id
-               ";      
-               $where[] = "cal_start_name.string='calendar_start'";
-               $where[] = "cal_start_value.string>=$start_time";
-               $where[] = "cal_end_name.string='calendar_end'";
-               $where[] = "cal_end_value.string <= $end_time";
-               
-               // Select what we're joining based on the options
-               $joinon = "e.guid = r.guid_one";
-               if (!$inverse_relationship)
-                       $joinon = "e.guid = r.guid_two";        
-                       
-               if ($count) {
-                       $query = "SELECT count(distinct e.guid) as total ";
-               } else {
-                       $query = "SELECT distinct e.* ";
+
+       // Add the calendar stuff
+       $cal_join = "
+               JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id
+               JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id
+
+               JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id
+               JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id
+       ";
+       $where[] = "cal_start_name.string='calendar_start'";
+       $where[] = "cal_start_value.string>=$start_time";
+       $where[] = "cal_end_name.string='calendar_end'";
+       $where[] = "cal_end_value.string <= $end_time";
+
+
+       if (!$count) {
+               $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $cal_join where ";
+       } else {
+               $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $cal_join where ";
+       }
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+
+       $query .= get_access_sql_suffix('e'); // Add access controls
+
+       if (!$count) {
+               $query .= " order by n.calendar_start $order_by";
+               // Add order and limit
+               if ($limit) {
+                       $query .= " limit $offset, $limit";
                }
-               $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon $cal_join where ";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
-                       }
+               $dt = get_data($query, "entity_row_to_elggstar");
+
+               return $dt;
+       } else {
+               $total = get_data_row($query);
+               return $total->total;
+       }
+}
+
+/**
+ * Return the notable entities for a given time period based on an item of metadata.
+ *
+ * @param int $start_time The start time as a unix timestamp.
+ * @param int $end_time The end time as a unix timestamp.
+ * @param mixed $meta_name
+ * @param mixed $meta_value
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+ *
+ * @return int|array A list of entities, or a count if $count is set to true
+ */
+function get_notable_entities_from_metadata($start_time, $end_time, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) {
+       global $CONFIG;
+
+       $meta_n = get_metastring_id($meta_name);
+       $meta_v = get_metastring_id($meta_value);
+
+       $start_time = (int)$start_time;
+       $end_time = (int)$end_time;
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+       $order_by = sanitise_string($order_by);
+       $site_guid = (int) $site_guid;
+       if ((is_array($owner_guid) && (count($owner_guid)))) {
+               foreach($owner_guid as $key => $guid) {
+                       $owner_guid[$key] = (int) $guid;
                }
-               return false;
+       } else {
+               $owner_guid = (int) $owner_guid;
        }
-       
-       /**
-        * Get all entities for today.
-        *
-        * @param string $type The type of entity (eg "user", "object" etc)
-        * @param string $subtype The arbitrary subtype of the entity
-        * @param int $owner_guid The GUID of the owning user
-        * @param string $order_by The field to order by; by default, time_created desc
-        * @param int $limit The number of entities to return; 10 by default
-        * @param int $offset The indexing offset, 0 by default
-        * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param int|array $container_guid The container or containers to get entities from (default: all containers).
-        */
-       function get_todays_entities($type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = null)
-       {
-               $day_start = get_day_start();
-               $day_end = get_day_end();
-               
-               return get_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid, $container_guid);
-       }
-       
-       /**
-        * Get entities for today from metadata.
-        *
-        * @param mixed $meta_name 
-        * @param mixed $meta_value
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
-        * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
-        * 
-        * @return int|array A list of entities, or a count if $count is set to true
-        */
-       function get_todays_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false)
-       {
-               $day_start = get_day_start();
-               $day_end = get_day_end();
-               
-               return get_notable_entities_from_metadata($day_start, $day_end, $meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, $order_by, $site_guid, $count);
-       }
-       
-       /**
-        * Get entities for today from a relationship
-        *
-        * @param string $relationship The relationship eg "friends_of"
-        * @param int $relationship_guid The guid of the entity to use query
-        * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
-        * @param string $type 
-        * @param string $subtype
-        * @param int $owner_guid
-        * @param string $order_by
-        * @param int $limit
-        * @param int $offset
-        * @param boolean $count Set to true if you want to count the number of entities instead (default false)
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @return array|int|false An array of entities, or the number of entities, or false on failure
-        */
-       function get_todays_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0)
-       {
-               $day_start = get_day_start();
-               $day_end = get_day_end();
-               
-               return get_notable_entities_from_relationship($day_start, $day_end, $relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid);
-       }
-       
-       /**
-        * Returns a viewable list of entities for a given time period.
-        *
-        * @see elgg_view_entity_list
-        * 
-        * @param int $start_time The start time as a unix timestamp.
-        * @param int $end_time The end time as a unix timestamp.
-        * @param string $type The type of entity (eg "user", "object" etc)
-        * @param string $subtype The arbitrary subtype of the entity
-        * @param int $owner_guid The GUID of the owning user
-        * @param int $limit The number of entities to display per page (default: 10)
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow gallery view 
-        * @param true|false $pagination Display pagination? Default: true
-        * @return string A viewable list of entities
-        */
-       function list_notable_entities($start_time, $end_time, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
-               
-               $offset = (int) get_input('offset');
-               $count =  get_notable_entities($start_time, $end_time, $type, $subtype, $owner_guid, "", $limit, $offset, true);
-               $entities = get_notable_entities($start_time, $end_time,$type, $subtype, $owner_guid, "", $limit, $offset);
 
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation);
-               
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
        }
-       
-       /**
-        * Return a list of today's entities.
-        * 
-        * @see list_notable_entities
-        *
-        * @param string $type The type of entity (eg "user", "object" etc)
-        * @param string $subtype The arbitrary subtype of the entity
-        * @param int $owner_guid The GUID of the owning user
-        * @param int $limit The number of entities to display per page (default: 10)
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow gallery view 
-        * @param true|false $pagination Display pagination? Default: true
-        * @return string A viewable list of entities
-        */
-       function list_todays_entities($type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
-               
-               $day_start = get_day_start();
-               $day_end = get_day_end();
-               
-               return list_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation);
-       }
-?>
\ No newline at end of file
+
+       //$access = get_access_list();
+
+       $where = array();
+
+       if ($entity_type!="") {
+               $where[] = "e.type='$entity_type'";
+       }
+
+       if ($entity_subtype) {
+               $where[] = "e.subtype=$entity_subtype";
+       }
+
+       if ($meta_name!="") {
+               $where[] = "m.name_id='$meta_n'";
+       }
+
+       if ($meta_value!="") {
+               $where[] = "m.value_id='$meta_v'";
+       }
+
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       if (is_array($owner_guid)) {
+               $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
+       } else if ($owner_guid > 0) {
+               $where[] = "e.container_guid = {$owner_guid}";
+       }
+
+       // Add the calendar stuff
+       $cal_join = "
+               JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id
+               JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id
+
+               JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id
+               JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id
+       ";
+
+       $where[] = "cal_start_name.string='calendar_start'";
+       $where[] = "cal_start_value.string>=$start_time";
+       $where[] = "cal_end_name.string='calendar_end'";
+       $where[] = "cal_end_value.string <= $end_time";
+
+       if (!$count) {
+               $query = "SELECT distinct e.* ";
+       } else {
+               $query = "SELECT count(distinct e.guid) as total ";
+       }
+
+       $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid $cal_join where";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+
+       // Add access controls
+       $query .= get_access_sql_suffix("e");
+       $query .= ' and ' . get_access_sql_suffix("m");
+
+       if (!$count) {
+               // Add order and limit
+               $query .= " order by $order_by limit $offset, $limit";
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($row = get_data_row($query)) {
+                       return $row->total;
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Return the notable entities for a given time period based on their relationship.
+ *
+ * @param int $start_time The start time as a unix timestamp.
+ * @param int $end_time The end time as a unix timestamp.
+ * @param string $relationship The relationship eg "friends_of"
+ * @param int $relationship_guid The guid of the entity to use query
+ * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
+ * @param string $type
+ * @param string $subtype
+ * @param int $owner_guid
+ * @param string $order_by
+ * @param int $limit
+ * @param int $offset
+ * @param boolean $count Set to true if you want to count the number of entities instead (default false)
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @return array|int|false An array of entities, or the number of entities, or false on failure
+ */
+function get_noteable_entities_from_relationship($start_time, $end_time, $relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) {
+       global $CONFIG;
+
+       $start_time = (int)$start_time;
+       $end_time = (int)$end_time;
+       $relationship = sanitise_string($relationship);
+       $relationship_guid = (int)$relationship_guid;
+       $inverse_relationship = (bool)$inverse_relationship;
+       $type = sanitise_string($type);
+       $subtype = get_subtype_id($type, $subtype);
+       $owner_guid = (int)$owner_guid;
+       if ($order_by == "") {
+               $order_by = "time_created desc";
+       }
+       $order_by = sanitise_string($order_by);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       //$access = get_access_list();
+
+       $where = array();
+
+       if ($relationship!="") {
+               $where[] = "r.relationship='$relationship'";
+       }
+       if ($relationship_guid) {
+               $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'");
+       }
+       if ($type != "") {
+               $where[] = "e.type='$type'";
+       }
+       if ($subtype) {
+               $where[] = "e.subtype=$subtype";
+       }
+       if ($owner_guid != "") {
+               $where[] = "e.container_guid='$owner_guid'";
+       }
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       // Add the calendar stuff
+       $cal_join = "
+               JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id
+               JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id
+
+               JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id
+               JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id
+       ";
+       $where[] = "cal_start_name.string='calendar_start'";
+       $where[] = "cal_start_value.string>=$start_time";
+       $where[] = "cal_end_name.string='calendar_end'";
+       $where[] = "cal_end_value.string <= $end_time";
+
+       // Select what we're joining based on the options
+       $joinon = "e.guid = r.guid_one";
+       if (!$inverse_relationship) {
+               $joinon = "e.guid = r.guid_two";
+       }
+
+       if ($count) {
+               $query = "SELECT count(distinct e.guid) as total ";
+       } else {
+               $query = "SELECT distinct e.* ";
+       }
+       $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon $cal_join where ";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+       // Add access controls
+       $query .= get_access_sql_suffix("e");
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+       return false;
+}
+
+/**
+ * Get all entities for today.
+ *
+ * @param string $type The type of entity (eg "user", "object" etc)
+ * @param string $subtype The arbitrary subtype of the entity
+ * @param int $owner_guid The GUID of the owning user
+ * @param string $order_by The field to order by; by default, time_created desc
+ * @param int $limit The number of entities to return; 10 by default
+ * @param int $offset The indexing offset, 0 by default
+ * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param int|array $container_guid The container or containers to get entities from (default: all containers).
+ */
+function get_todays_entities($type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = null) {
+       $day_start = get_day_start();
+       $day_end = get_day_end();
+
+       return get_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid, $container_guid);
+}
+
+/**
+ * Get entities for today from metadata.
+ *
+ * @param mixed $meta_name
+ * @param mixed $meta_value
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+ *
+ * @return int|array A list of entities, or a count if $count is set to true
+ */
+function get_todays_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) {
+       $day_start = get_day_start();
+       $day_end = get_day_end();
+
+       return get_notable_entities_from_metadata($day_start, $day_end, $meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, $order_by, $site_guid, $count);
+}
+
+/**
+ * Get entities for today from a relationship
+ *
+ * @param string $relationship The relationship eg "friends_of"
+ * @param int $relationship_guid The guid of the entity to use query
+ * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
+ * @param string $type
+ * @param string $subtype
+ * @param int $owner_guid
+ * @param string $order_by
+ * @param int $limit
+ * @param int $offset
+ * @param boolean $count Set to true if you want to count the number of entities instead (default false)
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @return array|int|false An array of entities, or the number of entities, or false on failure
+ */
+function get_todays_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) {
+       $day_start = get_day_start();
+       $day_end = get_day_end();
+
+       return get_notable_entities_from_relationship($day_start, $day_end, $relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid);
+}
+
+/**
+ * Returns a viewable list of entities for a given time period.
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param int $start_time The start time as a unix timestamp.
+ * @param int $end_time The end time as a unix timestamp.
+ * @param string $type The type of entity (eg "user", "object" etc)
+ * @param string $subtype The arbitrary subtype of the entity
+ * @param int $owner_guid The GUID of the owning user
+ * @param int $limit The number of entities to display per page (default: 10)
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow gallery view
+ * @param true|false $pagination Display pagination? Default: true
+ * @return string A viewable list of entities
+ */
+function list_notable_entities($start_time, $end_time, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
+       $offset = (int) get_input('offset');
+       $count =  get_notable_entities($start_time, $end_time, $type, $subtype, $owner_guid, "", $limit, $offset, true);
+       $entities = get_notable_entities($start_time, $end_time,$type, $subtype, $owner_guid, "", $limit, $offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation);
+}
+
+/**
+ * Return a list of today's entities.
+ *
+ * @see list_notable_entities
+ *
+ * @param string $type The type of entity (eg "user", "object" etc)
+ * @param string $subtype The arbitrary subtype of the entity
+ * @param int $owner_guid The GUID of the owning user
+ * @param int $limit The number of entities to display per page (default: 10)
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow gallery view
+ * @param true|false $pagination Display pagination? Default: true
+ * @return string A viewable list of entities
+ */
+function list_todays_entities($type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
+       $day_start = get_day_start();
+       $day_end = get_day_end();
+
+       return list_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation);
+}
\ No newline at end of file
index 9aa5d21747735b9c1c2869614c38fae758593798..17b3cd04a182e7ab959c11201f5ca34b466a7768 100644 (file)
 <?php
+/**
+ * Elgg configuration library
+ * Contains functions for managing system configuration
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Elgg configuration library
-        * Contains functions for managing system configuration
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd
-
-        * @link http://elgg.org/
-        */
-
-       
-       /**
-        * Unset a config option.
-        *
-        * @param string $name The name of the field.
-        * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default).
-        * @return mixed
-        */
-               function unset_config($name, $site_guid = 0) 
-               {
-                       global $CONFIG;
-                       
-                       $name = mysql_real_escape_string($name);
-                       $site_guid = (int) $site_guid;
-                       if ($site_guid == 0)
-                               $site_guid = (int) $CONFIG->site_id;
-                               
-                       return delete_data("delete from {$CONFIG->dbprefix}config where name='$name' and site_guid=$site_guid");
-               }
+/**
+ * Unset a config option.
+ *
+ * @param string $name The name of the field.
+ * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default).
+ * @return mixed
+ */
+function unset_config($name, $site_guid = 0) {
+       global $CONFIG;
+
+       $name = mysql_real_escape_string($name);
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = (int) $CONFIG->site_id;
+       }
+
+       return delete_data("delete from {$CONFIG->dbprefix}config where name='$name' and site_guid=$site_guid");
+}
+
+/**
+ * Sets a configuration value
+ *
+ * @param string $name The name of the configuration value
+ * @param string $value Its value
+ * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default)
+ * @return false|int 1 or false depending on success or failure
+ */
+function set_config($name, $value, $site_guid = 0) {
+       global $CONFIG;
+
+       // Unset existing
+       unset_config($name,$site_guid);
+
+       $name = mysql_real_escape_string($name);
+       $value = mysql_real_escape_string($value);
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = (int) $CONFIG->site_id;
+       }
+       $CONFIG->$name = $value;
+       $value = sanitise_string(serialize($value));
+
+       return insert_data("insert into {$CONFIG->dbprefix}config set name = '{$name}', value = '{$value}', site_guid = {$site_guid}");
+}
+
+/**
+ * Gets a configuration value
+ *
+ * @param string $name The name of the config value
+ * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default)
+ * @return mixed|false Depending on success
+ */
+function get_config($name, $site_guid = 0) {
+       global $CONFIG;
 
-       /**
-        * Sets a configuration value
-        *
-        * @param string $name The name of the configuration value
-        * @param string $value Its value
-        * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default)
-        * @return false|int 1 or false depending on success or failure 
-        */
-               function set_config($name, $value, $site_guid = 0) {
-                       
-                       global $CONFIG;
-                       
-                       // Unset existing
-                       unset_config($name,$site_guid);
-                       
-                       $name = mysql_real_escape_string($name);
-                       $value = mysql_real_escape_string($value);
-                       $site_guid = (int) $site_guid;
-                       if ($site_guid == 0)
-                               $site_guid = (int) $CONFIG->site_id;
-                       $CONFIG->$name = $value;
-                       $value = sanitise_string(serialize($value));
-                       
-                       return insert_data("insert into {$CONFIG->dbprefix}config set name = '{$name}', value = '{$value}', site_guid = {$site_guid}");
-                       
+       if (isset($CONFIG->$name)) {
+               return $CONFIG->$name;
+       }
+       $name = mysql_real_escape_string($name);
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = (int) $CONFIG->site_id;
+       }
+       if ($result = get_data_row("SELECT value FROM {$CONFIG->dbprefix}config
+               WHERE name = '{$name}' and site_guid = {$site_guid}")) {
+               $result = $result->value;
+               $result = unserialize($result->value);
+               $CONFIG->$name = $result;
+               return $result;
+       }
+
+       return false;
+}
+
+/**
+ * Gets all the configuration details in the config database for a given site.
+ *
+ * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default)
+ */
+function get_all_config($site_guid = 0) {
+       global $CONFIG;
+
+       $site_guid = (int) $site_guid;
+
+       if ($site_guid == 0) {
+               $site_guid = (int) $CONFIG->site_id;
+       }
+
+       if ($result = get_data("SELECT * from {$CONFIG->dbprefix}config where site_guid = {$site_guid}")) {
+               foreach ($result as $r) {
+                       $name = $r->name;
+                       $value = $r->value;
+                       $CONFIG->$name = unserialize($value);
                }
 
-       /**
-        * Gets a configuration value
-        *
-        * @param string $name The name of the config value
-        * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default)
-        * @return mixed|false Depending on success
-        */
-               function get_config($name, $site_guid = 0) {
-                       
-                       global $CONFIG;
-                       if (isset($CONFIG->$name))
-                               return $CONFIG->$name;
-                       $name = mysql_real_escape_string($name);
-                       $site_guid = (int) $site_guid;
-                       if ($site_guid == 0)
-                               $site_guid = (int) $CONFIG->site_id;
-                       if ($result = get_data_row("SELECT value from {$CONFIG->dbprefix}config where name = '{$name}' and site_guid = {$site_guid}")) {
-                               $result = $result->value;
-                               $result = unserialize($result->value);
-                               $CONFIG->$name = $result;
-                               return $result;
-                       }
-                       return false;
-                       
+               return true;
+       }
+       return false;
+}
+
+/**
+ * If certain configuration elements don't exist, autodetect sensible defaults
+ *
+ * @uses $CONFIG The main configuration global
+ *
+ */
+function set_default_config() {
+       global $CONFIG;
+
+       if (empty($CONFIG->path)) {
+               $CONFIG->path = str_replace("\\","/",dirname(dirname(dirname(__FILE__)))) . "/";
+       }
+
+       if (empty($CONFIG->viewpath)) {
+               $CONFIG->viewpath = $CONFIG->path . "views/";
+       }
+
+       if (empty($CONFIG->pluginspath)) {
+               $CONFIG->pluginspath = $CONFIG->path . "mod/";
+       }
+
+       if (empty($CONFIG->wwwroot)) {
+               /*
+               $CONFIG->wwwroot = "http://" . $_SERVER['SERVER_NAME'];
+
+               $request = $_SERVER['REQUEST_URI'];
+
+               if (strripos($request,"/") < (strlen($request) - 1)) {
+                       // addressing a file directly, not a dir
+                       $request = substr($request, 0, strripos($request,"/")+1);
                }
-               
-               /**
-                * Gets all the configuration details in the config database for a given site.
-                *
-                * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default)
-                */
-               function get_all_config($site_guid = 0)
-               {
-                       global $CONFIG;
-                       
-                       $site_guid = (int) $site_guid;
-                       
-                       if ($site_guid == 0)
-                               $site_guid = (int) $CONFIG->site_id;
-                               
-                       if ($result = get_data("SELECT * from {$CONFIG->dbprefix}config where site_guid = {$site_guid}")) {
-                               foreach ($result as $r)
-                               {       
-                                       $name = $r->name;
-                                       $value = $r->value;
-                                       $CONFIG->$name = unserialize($value);
-                               }
-                               
-                               return true;
-                       }
-                       return false;
+
+               $CONFIG->wwwroot .= $request;
+               */
+               $pathpart = str_replace("//","/",str_replace($_SERVER['DOCUMENT_ROOT'],"",$CONFIG->path));
+               if (substr($pathpart,0,1) != "/") {
+                       $pathpart = "/" . $pathpart;
                }
+               $CONFIG->wwwroot = "http://" . $_SERVER['HTTP_HOST'] . $pathpart;
+       }
+
+       if (empty($CONFIG->url)) {
+               $CONFIG->url = $CONFIG->wwwroot;
+       }
+
+       if (empty($CONFIG->sitename)) {
+               $CONFIG->sitename = "New Elgg site";
+       }
+
+       if (empty($CONFIG->language)) {
+               $CONFIG->language = "en";
+       }
+}
 
-       /**
-        * If certain configuration elements don't exist, autodetect sensible defaults 
-        * 
-        * @uses $CONFIG The main configuration global
-        *
-        */
-               function set_default_config() {
-                       
-                       global $CONFIG;
-                       if (empty($CONFIG->path))
-                               $CONFIG->path = str_replace("\\","/",dirname(dirname(dirname(__FILE__)))) . "/";
-                               
-                       if (empty($CONFIG->viewpath))
-                               $CONFIG->viewpath = $CONFIG->path . "views/";   
-
-                       if (empty($CONFIG->pluginspath))
-                               $CONFIG->pluginspath = $CONFIG->path . "mod/";
-                               
-                       if (empty($CONFIG->wwwroot)) {
-                               /*
-                               $CONFIG->wwwroot = "http://" . $_SERVER['SERVER_NAME'];
-                               
-                               $request = $_SERVER['REQUEST_URI'];
-                               
-                               if (strripos($request,"/") < (strlen($request) - 1)) {
-                                       // addressing a file directly, not a dir
-                                       $request = substr($request, 0, strripos($request,"/")+1);
-                               }
-                               
-                               $CONFIG->wwwroot .= $request;
-                               */
-                               $pathpart = str_replace("//","/",str_replace($_SERVER['DOCUMENT_ROOT'],"",$CONFIG->path));
-                               if (substr($pathpart,0,1) != "/") $pathpart = "/" . $pathpart; 
-                               $CONFIG->wwwroot = "http://" . $_SERVER['HTTP_HOST'] . $pathpart;
-               
-                       }
-               
-                       if (empty($CONFIG->url))
-                               $CONFIG->url = $CONFIG->wwwroot;
-                       
-                       if (empty($CONFIG->sitename))
-                               $CONFIG->sitename = "New Elgg site";
-                               
-                       if (empty($CONFIG->language))
-                               $CONFIG->language = "en";
+/**
+ * Function that provides some config initialisation on system init
+ *
+ */
+function configuration_init() {
+       global $CONFIG;
 
+       if (is_installed() || is_db_installed()) {
+               $path = datalist_get('path');
+               if (!empty($path)) {
+                       $CONFIG->path = $path;
                }
-               
-       /**
-        * Function that provides some config initialisation on system init
-        *
-        */
-               
-               function configuration_init() {
-                       
-                       global $CONFIG;
-                       
-                       if (is_installed() || is_db_installed()) {
-                               
-                               $path = datalist_get('path');
-                               if (!empty($path))
-                                       $CONFIG->path = $path;
-                               $dataroot = datalist_get('dataroot');
-                               if (!empty($dataroot))
-                                       $CONFIG->dataroot = $dataroot;
-                               $simplecache_enabled = datalist_get('simplecache_enabled');
-                               if ($simplecache_enabled !== false) {
-                                       $CONFIG->simplecache_enabled = $simplecache_enabled;
-                               } else {
-                                       $CONFIG->simplecache_enabled = 1;
-                               }
-                               $viewpath_cache_enabled = datalist_get('viewpath_cache_enabled');
-                               if ($viewpath_cache_enabled !== false) {
-                                       $CONFIG->viewpath_cache_enabled = $viewpath_cache_enabled;
-                               } else {
-                                       $CONFIG->viewpath_cache_enabled = 1;
-                               }
-                               if (isset($CONFIG->site) && ($CONFIG->site instanceof ElggSite)) {
-                                       $CONFIG->wwwroot = $CONFIG->site->url;
-                                       $CONFIG->sitename = $CONFIG->site->name;
-                                       $CONFIG->sitedescription = $CONFIG->site->description;
-                                       $CONFIG->siteemail = $CONFIG->site->email;
-                               }
-                               $CONFIG->url = $CONFIG->wwwroot;
-                               
-                               // Load default settings from database
-                               get_all_config();
-                               
-                               return true;
-                       }
+               $dataroot = datalist_get('dataroot');
+               if (!empty($dataroot)) {
+                       $CONFIG->dataroot = $dataroot;
                }
-               
-       /**
-        * Register config_init
-        */
-
-               register_elgg_event_handler('boot','system','configuration_init',10);
-               
-?>
\ No newline at end of file
+               $simplecache_enabled = datalist_get('simplecache_enabled');
+               if ($simplecache_enabled !== false) {
+                       $CONFIG->simplecache_enabled = $simplecache_enabled;
+               } else {
+                       $CONFIG->simplecache_enabled = 1;
+               }
+               $viewpath_cache_enabled = datalist_get('viewpath_cache_enabled');
+               if ($viewpath_cache_enabled !== false) {
+                       $CONFIG->viewpath_cache_enabled = $viewpath_cache_enabled;
+               } else {
+                       $CONFIG->viewpath_cache_enabled = 1;
+               }
+               if (isset($CONFIG->site) && ($CONFIG->site instanceof ElggSite)) {
+                       $CONFIG->wwwroot = $CONFIG->site->url;
+                       $CONFIG->sitename = $CONFIG->site->name;
+                       $CONFIG->sitedescription = $CONFIG->site->description;
+                       $CONFIG->siteemail = $CONFIG->site->email;
+               }
+               $CONFIG->url = $CONFIG->wwwroot;
+
+               // Load default settings from database
+               get_all_config();
+
+               return true;
+       }
+}
+
+/**
+ * Register config_init
+ */
+
+register_elgg_event_handler('boot', 'system', 'configuration_init', 10);
\ No newline at end of file
index e991e49a2b6c6a5f6a463f05edd5ba90b36983d3..b4952e2ee2b9848668da29172f67f2d3c7a3445e 100644 (file)
@@ -1,61 +1,57 @@
 <?php
-       /**
       * Elgg cron library.
-        * 
       * @package Elgg
       * @subpackage Core
       * @author Curverider Ltd
       * @link http://elgg.org/
       */
+/**
+ * Elgg cron library.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /** The cron exception. */
-       class CronException extends Exception {}
+/** The cron exception. */
+class CronException extends Exception {}
 
-       /**
-        * Initialisation 
-        *
-        */
-       function cron_init()
-       {
-               // Register a pagehandler for cron
-               register_page_handler('cron','cron_page_handler');
-       }
-               
-       /**
-        * Cron handler for redirecting pages.
-        *
-        * @param unknown_type $page
-        */
-       function cron_page_handler($page) 
-       {
-               global $CONFIG;
-               
-               if ($page[0])
-               {
-                       switch (strtolower($page[0]))
-                       {
-                               case 'minute' :
-                               case 'fiveminute' :
-                               case 'fifteenmin' :
-                               case 'halfhour' :
-                               case 'hourly' : 
-                               case 'daily'  :
-                               case 'weekly' :
-                               case 'monthly':
-                               case 'yearly' : 
-                               case 'reboot' : set_input('period', $page[0]); break; 
-                               default : throw new CronException(sprintf(elgg_echo('CronException:unknownperiod'), $page[0]));
-                       }
-                       
-                       // Include cron handler
-                       include($CONFIG->path . "engine/handlers/cron_handler.php");
-               }
-               else
-                       forward(); 
-       }
+/**
+ * Initialisation
+ *
+ */
+function cron_init() {
+       // Register a pagehandler for cron
+       register_page_handler('cron','cron_page_handler');
+}
 
+/**
+ * Cron handler for redirecting pages.
+ *
+ * @param unknown_type $page
+ */
+function cron_page_handler($page) {
+       global $CONFIG;
 
-       // Register a startup event
-       register_elgg_event_handler('init','system','cron_init');       
+       if ($page[0]) {
+               switch (strtolower($page[0])) {
+                       case 'minute' :
+                       case 'fiveminute' :
+                       case 'fifteenmin' :
+                       case 'halfhour' :
+                       case 'hourly' :
+                       case 'daily'  :
+                       case 'weekly' :
+                       case 'monthly':
+                       case 'yearly' :
+                       case 'reboot' :
+                               set_input('period', $page[0]);
+                               break;
+                       default :
+                               throw new CronException(sprintf(elgg_echo('CronException:unknownperiod'), $page[0]));
+               }
+
+               // Include cron handler
+               include($CONFIG->path . "engine/handlers/cron_handler.php");
+       } else {
+               forward();
+       }
+}
 
-?>
\ No newline at end of file
+// Register a startup event
+register_elgg_event_handler('init','system','cron_init');
\ No newline at end of file
index 95f2bfc82990349bda3af65c7e6394a6b7803e47..ccf0170620072eae204f2562bea4b45e0ca283a6 100644 (file)
 <?php
-       /**
-        * Exceptions.
-        * Define some globally useful exception classes.
-        * 
-        * @package Elgg
-        * @subpackage Exceptions
-        * @author Curverider Ltd <info@elgg.com>
-        * @link http://elgg.org/
-        */
-
-       // Top level //////////////////////////////////////////////////////////////////////////////
-
-       /**
-        * IOException 
-        * An IO Exception, throw when an IO Exception occurs. Subclass for specific IO Exceptions.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class IOException extends Exception {}
-
-       /**
-        * ClassException 
-        * A class Exception, throw when there is a class error.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class ClassException extends Exception {}
-
-       /**
-        * ConfigurationException 
-        * There is a configuration error
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class ConfigurationException extends Exception {}
-
-       /**
-        * SecurityException 
-        * An Security Exception, throw when a Security Exception occurs. Subclass for specific Security Execeptions (access problems etc)
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class SecurityException extends Exception {}
-
-       /**
-        * ClassNotFoundException 
-        * An database exception, throw when a database exception happens, subclass if more detail is needed.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class DatabaseException extends Exception {}
-
-       /**
-        * APIException
-        * The API Exception class, thrown by the API layer when an API call has an issue.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class APIException extends Exception {}
-       
-       /**
-        * CallException
-        * An exception thrown when there is a problem calling something.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class CallException extends Exception {}
-       
-       /**
-        * Data format exception
-        * An exception thrown when there is a problem in the format of some data.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class DataFormatException extends Exception {}
-       
-       // Class exceptions ///////////////////////////////////////////////////////////////////////
-
-       /**
-        * InvalidClassException 
-        * An invalid class Exception, throw when a class is invalid.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class InvalidClassException extends ClassException {}
-
-       /**
-        * ClassNotFoundException 
-        * An Class not found Exception, throw when an class can not be found occurs.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class ClassNotFoundException extends ClassException {}
-       
-       // Configuration exceptions ///////////////////////////////////////////////////////////////
-
-       /**
-        * InstallationException
-        * Thrown when there is a major problem with the installation.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class InstallationException extends ConfigurationException {}
-       
-       // Call exceptions ////////////////////////////////////////////////////////////////////////
-
-       /**
-        * NotImplementedException
-        * Thrown when a method or function has not been implemented, primarily used in development... you should
-        * not see these!
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class NotImplementedException extends CallException {}
-       
-       /**
-        * InvalidParameterException
-        * A parameter is invalid.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class InvalidParameterException extends CallException {}
-       
-       // Installation exception /////////////////////////////////////////////////////////////////
-       
-       /**
-        * RegistrationException
-        * Could not register a new user for whatever reason.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class RegistrationException extends InstallationException {}
-?>
\ No newline at end of file
+/**
+ * Exceptions.
+ * Define some globally useful exception classes.
+ *
+ * @package Elgg
+ * @subpackage Exceptions
+ * @author Curverider Ltd <info@elgg.com>
+ * @link http://elgg.org/
+ */
+
+// Top level //////////////////////////////////////////////////////////////////////////////
+
+/**
+ * IOException
+ * An IO Exception, throw when an IO Exception occurs. Subclass for specific IO Exceptions.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class IOException extends Exception {}
+
+/**
+ * ClassException
+ * A class Exception, throw when there is a class error.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class ClassException extends Exception {}
+
+/**
+ * ConfigurationException
+ * There is a configuration error
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class ConfigurationException extends Exception {}
+
+/**
+ * SecurityException
+ * An Security Exception, throw when a Security Exception occurs. Subclass for specific Security Execeptions (access problems etc)
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class SecurityException extends Exception {}
+
+/**
+ * ClassNotFoundException
+ * An database exception, throw when a database exception happens, subclass if more detail is needed.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class DatabaseException extends Exception {}
+
+/**
+ * APIException
+ * The API Exception class, thrown by the API layer when an API call has an issue.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class APIException extends Exception {}
+
+/**
+ * CallException
+ * An exception thrown when there is a problem calling something.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class CallException extends Exception {}
+
+/**
+ * Data format exception
+ * An exception thrown when there is a problem in the format of some data.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class DataFormatException extends Exception {}
+
+// Class exceptions ///////////////////////////////////////////////////////////////////////
+
+/**
+ * InvalidClassException
+ * An invalid class Exception, throw when a class is invalid.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class InvalidClassException extends ClassException {}
+
+/**
+ * ClassNotFoundException
+ * An Class not found Exception, throw when an class can not be found occurs.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class ClassNotFoundException extends ClassException {}
+
+// Configuration exceptions ///////////////////////////////////////////////////////////////
+
+/**
+ * InstallationException
+ * Thrown when there is a major problem with the installation.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class InstallationException extends ConfigurationException {}
+
+// Call exceptions ////////////////////////////////////////////////////////////////////////
+
+/**
+ * NotImplementedException
+ * Thrown when a method or function has not been implemented, primarily used in development... you should
+ * not see these!
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class NotImplementedException extends CallException {}
+
+/**
+ * InvalidParameterException
+ * A parameter is invalid.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class InvalidParameterException extends CallException {}
+
+// Installation exception /////////////////////////////////////////////////////////////////
+
+/**
+ * RegistrationException
+ * Could not register a new user for whatever reason.
+ *
+ * @author Curverider Ltd <info@elgg.com>
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+class RegistrationException extends InstallationException {}
\ No newline at end of file
index 0e487faabeab3529926aef6105c3c63dbe23f226..e3acace5fed2da3ba37a723bbfe587096f17d62e 100644 (file)
 <?php
-       /**
       * Elgg Data import export functionality.
-        * 
       * @package Elgg
       * @subpackage Core
       * @author Curverider Ltd
       * @link http://elgg.org/
       */
+/**
+ * Elgg Data import export functionality.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
+/**
+ * Define an interface for all ODD exportable objects.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ */
+interface Exportable {
        /**
-        * Define an interface for all ODD exportable objects.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
+        * This must take the contents of the object and convert it to exportable ODD
+        * @return object or array of objects.
         */
-       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();
-           
-       }
+       public function export();
 
        /**
-        * Define an interface for all ODD importable objects.
-        * @author Curverider Ltd
+        * Return a list of all fields that can be exported.
+        * This should be used as the basis for the values returned by export()
         */
-       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);
-       }
+       public function getExportableValues();
+}
 
+/**
+ * Define an interface for all ODD importable objects.
+ * @author Curverider Ltd
+ */
+interface Importable {
        /**
-        * Export exception
-        * 
-        * @package Elgg
-        * @subpackage Exceptions
-        *
-        */
-       class ExportException extends DataFormatException {}
-       
-       /**
-        * Import exception
+        * 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.
         *
-        * @package Elgg
-        * @subpackage Exceptions
-        */
-       class ImportException extends DataFormatException {}
-               
-       /**
-        * Get a UUID from a given object.
-        * 
-        * @param $object The object either an ElggEntity, ElggRelationship or ElggExtender
-        * @return the UUID or false
+        * @param ODD $data
+        * @return bool
+        * @throws ImportException if there was a critical error importing data.
         */
-       function get_uuid_from_object($object)
-       {
-               if ($object instanceof ElggEntity)
-                       return guid_to_uuid($object->guid);
-               else if ($object instanceof ElggExtender) {
-                       $type = $object->type;
-                       if ($type == 'volatile')
-                               $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->name}/";
-                       else
-                               $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->id}/";
-                               
-                       return $uuid;
-               } else if ($object instanceof ElggRelationship) {
-                       return guid_to_uuid($object->guid_one) . "relationship/{$object->id}/"; 
+       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 {}
+
+/**
+ * Get a UUID from a given object.
+ *
+ * @param $object The object either an ElggEntity, ElggRelationship or ElggExtender
+ * @return the UUID or false
+ */
+function get_uuid_from_object($object) {
+       if ($object instanceof ElggEntity) {
+               return guid_to_uuid($object->guid);
+       } else if ($object instanceof ElggExtender) {
+               $type = $object->type;
+               if ($type == 'volatile') {
+                       $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->name}/";
+               } else {
+                       $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->id}/";
                }
-                       
-               
-               return false;
+
+               return $uuid;
+       } else if ($object instanceof ElggRelationship) {
+               return guid_to_uuid($object->guid_one) . "relationship/{$object->id}/";
        }
-       
-       /**
-        * Generate a UUID from a given GUID.
-        * 
-        * @param int $guid The GUID of an object.
-        */
-       function guid_to_uuid($guid)
-       {
-               global $CONFIG;
-               
-               return $CONFIG->wwwroot  . "export/opendd/$guid/";
+
+       return false;
+}
+
+/**
+ * Generate a UUID from a given GUID.
+ *
+ * @param int $guid The GUID of an object.
+ */
+function guid_to_uuid($guid) {
+       global $CONFIG;
+
+       return $CONFIG->wwwroot  . "export/opendd/$guid/";
+}
+
+/**
+ * Test to see if a given uuid is for this domain, returning true if so.
+ * @param $uuid
+ * @return bool
+ */
+function is_uuid_this_domain($uuid) {
+       global $CONFIG;
+
+       if (strpos($uuid, $CONFIG->wwwroot) === 0) {
+               return true;
        }
-       
-       /**
-        * Test to see if a given uuid is for this domain, returning true if so.
-        * @param $uuid
-        * @return bool
-        */
-       function is_uuid_this_domain($uuid)
-       {
-               global $CONFIG;
-               
-               if (strpos($uuid, $CONFIG->wwwroot) === 0)
-                       return true;
-                       
-               return false;
+
+       return false;
+}
+
+/**
+ * This function attempts to retrieve a previously imported entity via its UUID.
+ *
+ * @param $uuid
+ */
+function get_entity_from_uuid($uuid) {
+       $uuid = sanitise_string($uuid);
+
+       $entities = get_entities_from_metadata("import_uuid", $uuid);
+
+       if ($entities) {
+               return $entities[0];
        }
-       
-       /**
-        * This function attempts to retrieve a previously imported entity via its UUID.
-        * 
-        * @param $uuid 
-        */
-       function get_entity_from_uuid($uuid)
-       {
-               $uuid = sanitise_string($uuid);
-               
-               $entities = get_entities_from_metadata("import_uuid", $uuid);
-               
-               if ($entities)
-                       return $entities[0];
-               
-               return false;
+
+       return false;
+}
+
+/**
+ * Tag a previously created guid with the uuid it was imported on.
+ *
+ * @param int $guid
+ * @param string $uuid
+ */
+function add_uuid_to_guid($guid, $uuid) {
+       $guid = (int)$guid;
+       $uuid = sanitise_string($uuid);
+
+       return create_metadata($guid, "import_uuid", $uuid);
+}
+
+
+$IMPORTED_DATA = array();
+$IMPORTED_OBJECT_COUNTER = 0;
+
+/**
+ * This function processes an element, passing elements to the plugin stack to see if someone will
+ * process it.
+ *
+ * If nobody processes the top level element, the sub level elements are processed.
+ *
+ * @param ODD $odd The odd element to process
+ */
+function __process_element(ODD $odd) {
+       global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER;
+
+       // See if anyone handles this element, return true if it is.
+       if ($odd) {
+               $handled = trigger_plugin_hook("import", "all", array("element" => $odd), $to_be_serialised);
        }
-       
-       /**
-        * Tag a previously created guid with the uuid it was imported on.
-        *
-        * @param int $guid
-        * @param string $uuid
-        */
-       function add_uuid_to_guid($guid, $uuid)
-       {
-               $guid = (int)$guid;
-               $uuid = sanitise_string($uuid);
-               
-               return create_metadata($guid, "import_uuid", $uuid);
+
+       // If not, then see if any of its sub elements are handled
+       if ($handled) {
+               // Increment validation counter
+               $IMPORTED_OBJECT_COUNTER ++;
+               // Return the constructed object
+               $IMPORTED_DATA[] = $handled;
+
+               return true;
        }
-       
-       
+
+       return false;
+}
+
+function exportAsArray($guid) {
+       $guid = (int)$guid;
+
+       // Initialise the array
+       $to_be_serialised = array();
+
+       // Trigger a hook to
+       $to_be_serialised = trigger_plugin_hook("export", "all", array("guid" => $guid), $to_be_serialised);
+
+       // Sanity check
+       if ((!is_array($to_be_serialised)) || (count($to_be_serialised)==0)) {
+               throw new ExportException(sprintf(elgg_echo('ExportException:NoSuchEntity'), $guid));
+       }
+
+       return $to_be_serialised;
+}
+
+/**
+ * Export a GUID.
+ *
+ * This function exports a GUID and all information related to it in an XML format.
+ *
+ * This function makes use of the "serialise" plugin hook, which is passed an array to which plugins
+ * should add data to be serialised to.
+ *
+ * @see ElggEntity for an example of its usage.
+ * @param int $guid The GUID.
+ * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats.
+ * @return xml
+ */
+function export($guid) {
+       $odd = new ODDDocument(exportAsArray($guid));
+
+       return ODD_Export($odd);
+}
+
+/**
+ * Import an XML serialisation of an object.
+ * This will make a best attempt at importing a given xml doc.
+ *
+ * @param string $xml
+ * @return bool
+ * @throws Exception if there was a problem importing the data.
+ */
+function import($xml) {
+       global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER;
+
        $IMPORTED_DATA = array();
        $IMPORTED_OBJECT_COUNTER = 0;
-       
-       /**
-        * This function processes an element, passing elements to the plugin stack to see if someone will
-        * process it.
-        * 
-        * If nobody processes the top level element, the sub level elements are processed.
-        * 
-        * @param ODD $odd The odd element to process
-        */
-       function __process_element(ODD $odd)
-       {
-               global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER;
-               
-               // See if anyone handles this element, return true if it is.
-               if ($odd)
-                       $handled = trigger_plugin_hook("import", "all", array("element" => $odd), $to_be_serialised);
-
-               // If not, then see if any of its sub elements are handled
-               if ($handled) 
-               {
-                       $IMPORTED_OBJECT_COUNTER ++; // Increment validation counter
-                       $IMPORTED_DATA[] = $handled; // Return the constructed object
-
-                       return true;
-               }
-               
-               return false;
-       }
-       
-       function exportAsArray($guid)
-       {
-               
-               $guid = (int)$guid;  
-               
-               // Initialise the array
-               $to_be_serialised = array();
-               
-               // Trigger a hook to 
-               $to_be_serialised = trigger_plugin_hook("export", "all", array("guid" => $guid), $to_be_serialised);
-               
-               // Sanity check
-               if ((!is_array($to_be_serialised)) || (count($to_be_serialised)==0)) throw new ExportException(sprintf(elgg_echo('ExportException:NoSuchEntity'), $guid));
-
-               return $to_be_serialised;
-       }
-       
-       /**
-        * Export a GUID.
-        * 
-        * This function exports a GUID and all information related to it in an XML format.
-        * 
-        * This function makes use of the "serialise" plugin hook, which is passed an array to which plugins
-        * should add data to be serialised to.
-        * 
-        * @see ElggEntity for an example of its usage.
-        * @param int $guid The GUID.
-        * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats.
-        * @return xml 
-        */
-       function export($guid)
-       {
-               $odd = new ODDDocument(exportAsArray($guid));
-               
-               return ODD_Export($odd);
+
+       $document = ODD_Import($xml);
+       if (!$document) {
+               throw new ImportException(elgg_echo('ImportException:NoODDElements'));
        }
-       
-       /**
-        * Import an XML serialisation of an object.
-        * This will make a best attempt at importing a given xml doc.
-        *
-        * @param string $xml
-        * @return bool
-        * @throws Exception if there was a problem importing the data.
-        */
-       function import($xml)
-       {
-               global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER;
-       
-               $IMPORTED_DATA = array();
-               $IMPORTED_OBJECT_COUNTER = 0;
-               
-               $document = ODD_Import($xml);
-               if (!$document)
-                       throw new ImportException(elgg_echo('ImportException:NoODDElements'));
-               
-               foreach ($document as $element)
-                       __process_element($element);
-               
-               if ($IMPORTED_OBJECT_COUNTER!= count($IMPORTED_DATA))
-                       throw new ImportException(elgg_echo('ImportException:NotAllImported'));
-               
-               return true;
+
+       foreach ($document as $element) {
+               __process_element($element);
        }
 
-       
-       /**
-        * Register the OpenDD import action
-        */
-       function export_init()
-       {
-               global $CONFIG;
-               
-               register_action("import/opendd", false);
+       if ($IMPORTED_OBJECT_COUNTER!= count($IMPORTED_DATA)) {
+               throw new ImportException(elgg_echo('ImportException:NotAllImported'));
        }
-       
-       // Register a startup event
-       register_elgg_event_handler('init','system','export_init',100); 
-?>
\ No newline at end of file
+
+       return true;
+}
+
+
+/**
+ * Register the OpenDD import action
+ */
+function export_init() {
+       global $CONFIG;
+
+       register_action("import/opendd", false);
+}
+
+// Register a startup event
+register_elgg_event_handler('init', 'system', 'export_init', 100);
\ No newline at end of file
index 456a1f778a59430eda0014d8b23e906f59544bea..cbcdd6eb7766bf250d8a54dd3c08378a2bada5a1 100644 (file)
 <?php
+/**
+ * Elgg Entity Extender.
+ * This file contains ways of extending an Elgg entity in custom ways.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @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
+{
        /**
-        * Elgg Entity Extender.
-        * This file contains ways of extending an Elgg entity in custom ways.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
-        * @link http://elgg.org/
+        * This contains the site's main properties (id, etc)
+        * @var array
         */
+       protected $attributes;
 
        /**
-        * ElggExtender 
-        * 
-        * @author Curverider Ltd
-        * @package Elgg
-        * @subpackage Core
+        * Get an attribute
+        *
+        * @param string $name
+        * @return mixed
         */
-       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']));
-                                       }
+       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
-                */
-               public function getOwnerEntity()
-               {
-                       return get_user($this->owner_guid);
+                       return $this->attributes[$name];
                }
-               
-               /**
-                * 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) ) {
-                       $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects
-                       }
-               } 
-               
-               function offsetExists($offset) 
-               {
-                       return array_key_exists($offset, $this->attributes);
-               } 
-       }
-       
+               return null;
+       }
+
        /**
-        * Detect the value_type for a given value.
-        * Currently this is very crude.
-        * 
-        * TODO: Make better!
+        * Set an attribute
         *
+        * @param string $name
         * @param mixed $value
-        * @param string $value_type If specified, overrides the detection.
-        * @return string
+        * @param string $value_type
+        * @return boolean
         */
-       function detect_extender_valuetype($value, $value_type = "")
-       {
-               if ($value_type!="")
-                       return $value_type;
-                       
-               // This is crude
-               if (is_int($value)) return 'integer';
-               if (is_numeric($value)) return 'text'; // Catch floating point values which are not integer
-               
-               return 'text';
+       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;
        }
-       
+
        /**
-        * Utility function used by import_extender_plugin_hook() to process an ODDMetaData and add it to an entity.
-        * This function does not hit ->save() on the entity (this lets you construct in memory)
+        * Return the owner of this annotation.
         *
-        * @param ElggEntity The entity to add the data to.
-        * @param ODDMetaData $element The OpenDD element
-        * @return bool
+        * @return mixed
         */
-       function oddmetadata_to_elggextender(ElggEntity $entity, ODDMetaData $element)
-       {
-               // Get the type of extender (metadata, type, attribute etc)
-               $type = $element->getAttribute('type');
-               $attr_name = $element->getAttribute('name');
-               $attr_val = $element->getBody();
-
-               switch ($type)
-               {
-                       case 'volatile' : break; // Ignore volatile items
-                       case 'annotation' : 
-                               $entity->annotate($attr_name, $attr_val);
-                       break;
-                       case 'metadata' :
-                               $entity->setMetaData($attr_name, $attr_val, "", true);
-                       break;
-                       default : // Anything else assume attribute
-                               $entity->set($attr_name, $attr_val);                    
-               }
-               
-               // Set time if appropriate
-               $attr_time = $element->getAttribute('published');
-               if ($attr_time)
-                       $entity->set('time_updated', $attr_time);
-                       
-               return true;
+       public function getOwner() {
+               return $this->owner_guid;
        }
-       
+
        /**
-        *  Handler called by trigger_plugin_hook on the "import" event.
+        * Return the owner entity
+        *
+        * @return mixed
         */
-       function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params)
-       {
-               $element = $params['element'];
-               
-               $tmp = NULL;
-               
-               if ($element instanceof ODDMetaData)
-               {
-                       // Recall entity
-                       $entity_uuid = $element->getAttribute('entity_uuid');
-                       $entity = get_entity_from_uuid($entity_uuid);
-                       if (!$entity)
-                               throw new ImportException(sprintf(elgg_echo('ImportException:GUIDNotFound'), $entity_uuid));
-                       
-                       oddmetadata_to_elggextender($entity, $element);
-       
-                       // Save
-                       if (!$entity->save())
-                               throw new ImportException(sprintf(elgg_echo('ImportException:ProblemUpdatingMeta'), $attr_name, $entity_uuid));
-                       
-                       return true;
-               }
+       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);
        }
-       
+
        /**
-        * Determines whether or not the specified user can edit the specified piece of extender
+        * 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 $extender_id The ID of the piece of extender
-        * @param string $type 'metadata' or 'annotation'
-        * @param int $user_guid The GUID of the user
+        * @param int $user_guid The GUID of the user (defaults to currently logged in user)
         * @return true|false
         */
-       function can_edit_extender($extender_id, $type, $user_guid = 0) {
-               
-               if (!isloggedin())
-                       return false;
-               
-               $user_guid = (int)$user_guid;
-               $user = get_entity($user_guid);
-               if (!$user) $user = get_loggedin_user(); 
-
-               $functionname = "get_{$type}";
-               if (is_callable($functionname)) {
-                       $extender = $functionname($extender_id);
-               } else return false;
-               
-               if (!is_a($extender,"ElggExtender")) return false;
-               
-               // If the owner is the specified user, great! They can edit.
-               if ($extender->getOwner() == $user->getGUID()) return true;
-               
-               // If the user can edit the entity this is attached to, great! They can edit.
-               if (can_edit_entity($extender->entity_guid,$user->getGUID())) return true;
-               
-               // Trigger plugin hooks
-               return trigger_plugin_hook('permissions_check',$type,array('entity' => $entity, 'user' => $user),false);
-               
-       }
-       
+       public function canEdit($user_guid = 0) {
+               return can_edit_extender($this->id,$this->type,$user_guid);
+       }
+
        /**
-        * Sets the URL handler for a particular extender type and name.
-        * It is recommended that you do not call this directly, instead use one of the wrapper functions in the
-        * subtype files.
+        * Return a url for this extender.
         *
-        * @param string $function_name The function to register
-        * @param string $extender_type Extender type
-        * @param string $extender_name The name of the extender
-        * @return true|false Depending on success
+        * @return string
         */
-       function register_extender_url_handler($function_name, $extender_type = "all", $extender_name = "all") {
-               global $CONFIG;
-               
-               if (!is_callable($function_name)) return false;
-               
-               if (!isset($CONFIG->extender_url_handler)) {
-                       $CONFIG->extender_url_handler = array();
-               }
-               if (!isset($CONFIG->extender_url_handler[$extender_type])) {
-                       $CONFIG->extender_url_handler[$extender_type] = array();
-               }
-               $CONFIG->extender_url_handler[$extender_type][$extender_name] = $function_name;
-               
-               return true;
-               
+       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',
+               );
        }
-       
+
        /**
-        * Get the URL of a given elgg extender. 
-        * Used by get_annotation_url and get_metadata_url.
+        * Export this object
         *
-        * @param ElggExtender $extender
+        * @return array
         */
-       function get_extender_url(ElggExtender $extender)
-       {
-               global $CONFIG;
-               
-               $view = elgg_get_viewtype(); 
-                       
-               $guid = $extender->entity_guid;
-               $type = $extender->type;
-               
-               $url = "";
-               
-               $function = "";
-               if (isset($CONFIG->extender_url_handler[$type][$extender->name]))
-                       $function = $CONFIG->extender_url_handler[$type][$extender->name];
-               if (isset($CONFIG->extender_url_handler[$type]['all']))
-                       $function = $CONFIG->extender_url_handler[$type]['all'];
-               if (isset($CONFIG->extender_url_handler['all']['all']))
-                       $function = $CONFIG->extender_url_handler['all']['all'];
-                       
-               if (is_callable($function)) {
-                       $url = $function($extender);
+       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];
                }
-               
-               if ($url == "") {
-                       $nameid = $extender->id;
-                       if ($type == 'volatile')
-                               $nameid== $extender->name;
-                       $url = $CONFIG->wwwroot  . "export/$view/$guid/$type/$nameid/";
-               } 
-               return $url;
-       }
-       
-       /** Register the hook */
-       register_plugin_hook("import", "all", "import_extender_plugin_hook", 2);
-       
-?>
+       }
+
+       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);
+       }
+}
+
+/**
+ * Detect the value_type for a given value.
+ * Currently this is very crude.
+ *
+ * TODO: Make better!
+ *
+ * @param mixed $value
+ * @param string $value_type If specified, overrides the detection.
+ * @return string
+ */
+function detect_extender_valuetype($value, $value_type = "") {
+       if ($value_type!="") {
+               return $value_type;
+       }
+
+       // This is crude
+       if (is_int($value)) {
+               return 'integer';
+       }
+       // Catch floating point values which are not integer
+       if (is_numeric($value)) {
+               return 'text';
+       }
+
+       return 'text';
+}
+
+/**
+ * Utility function used by import_extender_plugin_hook() to process an ODDMetaData and add it to an entity.
+ * This function does not hit ->save() on the entity (this lets you construct in memory)
+ *
+ * @param ElggEntity The entity to add the data to.
+ * @param ODDMetaData $element The OpenDD element
+ * @return bool
+ */
+function oddmetadata_to_elggextender(ElggEntity $entity, ODDMetaData $element) {
+       // Get the type of extender (metadata, type, attribute etc)
+       $type = $element->getAttribute('type');
+       $attr_name = $element->getAttribute('name');
+       $attr_val = $element->getBody();
+
+       switch ($type) {
+               // Ignore volatile items
+               case 'volatile' :
+                       break;
+               case 'annotation' :
+                       $entity->annotate($attr_name, $attr_val);
+                       break;
+               case 'metadata' :
+                       $entity->setMetaData($attr_name, $attr_val, "", true);
+                       break;
+               default : // Anything else assume attribute
+                       $entity->set($attr_name, $attr_val);
+       }
+
+       // Set time if appropriate
+       $attr_time = $element->getAttribute('published');
+       if ($attr_time) {
+               $entity->set('time_updated', $attr_time);
+       }
+
+       return true;
+}
+
+/**
+ *  Handler called by trigger_plugin_hook on the "import" event.
+ */
+function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params) {
+       $element = $params['element'];
+
+       $tmp = NULL;
+
+       if ($element instanceof ODDMetaData) {
+               // Recall entity
+               $entity_uuid = $element->getAttribute('entity_uuid');
+               $entity = get_entity_from_uuid($entity_uuid);
+               if (!$entity) {
+                       throw new ImportException(sprintf(elgg_echo('ImportException:GUIDNotFound'), $entity_uuid));
+               }
+
+               oddmetadata_to_elggextender($entity, $element);
+
+               // Save
+               if (!$entity->save()) {
+                       throw new ImportException(sprintf(elgg_echo('ImportException:ProblemUpdatingMeta'), $attr_name, $entity_uuid));
+               }
+
+               return true;
+       }
+}
+
+/**
+ * Determines whether or not the specified user can edit the specified piece of extender
+ *
+ * @param int $extender_id The ID of the piece of extender
+ * @param string $type 'metadata' or 'annotation'
+ * @param int $user_guid The GUID of the user
+ * @return true|false
+ */
+function can_edit_extender($extender_id, $type, $user_guid = 0) {
+       if (!isloggedin()) {
+               return false;
+       }
+
+       $user_guid = (int)$user_guid;
+       $user = get_entity($user_guid);
+       if (!$user) {
+               $user = get_loggedin_user();
+       }
+
+       $functionname = "get_{$type}";
+       if (is_callable($functionname)) {
+               $extender = $functionname($extender_id);
+       } else {
+               return false;
+       }
+
+       if (!is_a($extender,"ElggExtender")) {
+               return false;
+       }
+
+       // If the owner is the specified user, great! They can edit.
+       if ($extender->getOwner() == $user->getGUID()) {
+               return true;
+       }
+
+       // If the user can edit the entity this is attached to, great! They can edit.
+       if (can_edit_entity($extender->entity_guid,$user->getGUID())) {
+               return true;
+       }
+
+       // Trigger plugin hooks
+       return trigger_plugin_hook('permissions_check',$type,array('entity' => $entity, 'user' => $user),false);
+}
+
+/**
+ * Sets the URL handler for a particular extender type and name.
+ * It is recommended that you do not call this directly, instead use one of the wrapper functions in the
+ * subtype files.
+ *
+ * @param string $function_name The function to register
+ * @param string $extender_type Extender type
+ * @param string $extender_name The name of the extender
+ * @return true|false Depending on success
+ */
+function register_extender_url_handler($function_name, $extender_type = "all", $extender_name = "all") {
+       global $CONFIG;
+
+       if (!is_callable($function_name)) {
+               return false;
+       }
+
+       if (!isset($CONFIG->extender_url_handler)) {
+               $CONFIG->extender_url_handler = array();
+       }
+       if (!isset($CONFIG->extender_url_handler[$extender_type])) {
+               $CONFIG->extender_url_handler[$extender_type] = array();
+       }
+       $CONFIG->extender_url_handler[$extender_type][$extender_name] = $function_name;
+
+       return true;
+}
+
+/**
+ * Get the URL of a given elgg extender.
+ * Used by get_annotation_url and get_metadata_url.
+ *
+ * @param ElggExtender $extender
+ */
+function get_extender_url(ElggExtender $extender) {
+       global $CONFIG;
+
+       $view = elgg_get_viewtype();
+
+       $guid = $extender->entity_guid;
+       $type = $extender->type;
+
+       $url = "";
+
+       $function = "";
+       if (isset($CONFIG->extender_url_handler[$type][$extender->name])) {
+               $function = $CONFIG->extender_url_handler[$type][$extender->name];
+       }
+
+       if (isset($CONFIG->extender_url_handler[$type]['all'])) {
+               $function = $CONFIG->extender_url_handler[$type]['all'];
+       }
+
+       if (isset($CONFIG->extender_url_handler['all']['all'])) {
+               $function = $CONFIG->extender_url_handler['all']['all'];
+       }
+
+       if (is_callable($function)) {
+               $url = $function($extender);
+       }
+
+       if ($url == "") {
+               $nameid = $extender->id;
+               if ($type == 'volatile') {
+                       $nameid== $extender->name;
+               }
+               $url = $CONFIG->wwwroot  . "export/$view/$guid/$type/$nameid/";
+       }
+       return $url;
+}
+
+/** Register the hook */
+register_plugin_hook("import", "all", "import_extender_plugin_hook", 2);
\ No newline at end of file
index a7df5a8f02383105a07c034a5dc548b4c4f07b7a..852fbae8f0e418ddae13f66f901e4f51a9f1c6e4 100644 (file)
 <?php
+/**
+ * Elgg filestore.
+ * This file contains classes, interfaces and functions for saving and retrieving data to various file
+ * stores.
+ *
+ * @package Elgg
+ * @subpackage API
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
+
+include_once("objects.php");
+
+/**
+ * @class ElggFilestore
+ * This class defines the interface for all elgg data repositories.
+ * @author Curverider Ltd
+ */
+abstract class ElggFilestore {
        /**
-        * Elgg filestore.
-        * This file contains classes, interfaces and functions for saving and retrieving data to various file 
-        * stores.
-        * 
-        * @package Elgg
-        * @subpackage API
-        * @author Curverider Ltd
-        * @link http://elgg.org/
+        * 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);
 
-       include_once("objects.php");
-       
        /**
-        * @class ElggFilestore
-        * This class defines the interface for all elgg data repositories.
-        * @author Curverider Ltd
+        * 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 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);
-               
-       }
-       
+       abstract public function write($f, $data);
+
        /**
-        * @class ElggDiskFilestore
-        * This class uses disk storage to save data.
-        * @author Curverider Ltd
+        * 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.
         */
-       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 = "r+b"; 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);
+       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 delete(ElggFile $file)
-               {
-                       $filename = $this->getFilenameOnFilestore($file);
-                       if (file_exists($filename)) {
-                               return unlink($filename);
-                       } else {
-                               return true;
-                       }
+       }
+
+       public function open(ElggFile $file, $mode) {
+               $fullname = $this->getFilenameOnFilestore($file);
+
+               // Split into path and name
+               $ls = strrpos($fullname,"/");
+               if ($ls===false) {
+                       $ls = 0;
                }
-               
-               public function seek($f, $position)
-               {
-                       return fseek($f, $position);
+
+               $path = substr($fullname, 0, $ls);
+               $name = substr($fullname, $ls);
+
+               // Try and create the directory
+               try {
+                       $this->make_directory_root($path);
+               } catch (Exception $e) {
+
                }
-               
-               public function tell($f)
-               {
-                       return ftell($f);
+
+               if (($mode!='write') && (!file_exists($fullname))) {
+                       return false;
                }
-               
-               public function eof($f)
-               {
-                       return feof($f);
+
+               switch ($mode) {
+                       case "read" :
+                               $mode = "r+b";
+                               break;
+                       case "write" :
+                               $mode = "w+b";
+                               break;
+                       case "append" :
+                               $mode = "a+b";
+                               break;
+                       default:
+                               throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode));
                }
-               
-               public function getFileSize(ElggFile $file)
-               {                       
-                       return filesize($this->getFilenameOnFilestore($file));
+
+               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);
                }
-       
-               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->username) . $file->getFilename();
+
+               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 grabFile(ElggFile $file) {
-                       
-                       return file_get_contents($file->getFilenameOnFilestore());
-                       
+       }
+
+       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();
                }
-               
-               public function exists(ElggFile $file)
-               {
-                       return file_exists($this->getFilenameOnFilestore($file));
+
+               if ((!$owner) || (!$owner->username)) {
+                       throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:MissingOwner'), $file->getFilename(), $file->guid));
                }
-               
-               public function getSize($prefix,$container_guid) {
-                       if ($container_guid && ($container=get_entity($container_guid)) && ($username = $container->username)) {
-                               return get_dir_size($this->dir_root.$this->make_file_matrix($username).$prefix);
-                       } else {
-                               return false;
-                       }
+
+               return $this->dir_root . $this->make_file_matrix($owner->username) . $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 && ($container=get_entity($container_guid)) && ($username = $container->username)) {
+                       return get_dir_size($this->dir_root.$this->make_file_matrix($username).$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)) 
+       }
+
+       /**
+        * 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 string $filename
-                */
-               protected function make_file_matrix($filename)
-               {
-                       $invalid_fs_chars = '*\'\\/"!$%^&*.%(){}[]#~?<>;|¬`@-+=';
-                       
-                       $matrix = "";
-                       
-                       $name = $filename;
-                       $filename = $this->mb_str_split($filename);
-                       if (!$filename) return false;
-                       
-                       $len = count($filename);
-                       if ($len>$this->matrix_depth)
-                               $len = $this->matrix_depth;
-                       
-                       for ($n = 0; $n < $len; $n++) {
-                               
-                               // Prevent a matrix being formed with unsafe characters
-                               $char = $filename[$n];
-                               if (strpos($invalid_fs_chars, $char)!==false)
-                                       $char = '_';
-                               
-                               $matrix .= $char . "/";
-                       }       
-       
-                       return $matrix.$name."/";
                }
-               
-               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 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 false;
+
+                       return $array;
+               } else {
+                       return str_split($string);
                }
+
+               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
+        * Construct the filename matrix.
+        *
+        * @param string $filename
         */
-       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";
+       protected function make_file_matrix($filename) {
+               $invalid_fs_chars = '*\'\\/"!$%^&*.%(){}[]#~?<>;|¬`@-+=';
+
+               $matrix = "";
+
+               $name = $filename;
+               $filename = $this->mb_str_split($filename);
+               if (!$filename) {
+                       return false;
                }
-               
-               public function __construct($guid = null) 
-               {                       
-                       parent::__construct($guid);
-                       
-                       // Set default filestore
-                       $this->filestore = $this->getFilestore();
+
+               $len = count($filename);
+               if ($len>$this->matrix_depth) {
+                       $len = $this->matrix_depth;
                }
-               
-               /**
-                * 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;
+
+               for ($n = 0; $n < $len; $n++) {
+                       // Prevent a matrix being formed with unsafe characters
+                       $char = $filename[$n];
+                       if (strpos($invalid_fs_chars, $char)!==false) {
+                               $char = '_';
                        }
-                       $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);
-                       
+
+                       $matrix .= $char . "/";
                }
-               
-               /**
-                * Close the file and commit changes
-                */
-               public function close()
-               {
-                       $fs = $this->getFilestore();
-                       
-                       if ($fs->close($this->handle))
-                       {
-                               $this->handle = NULL;
-                               
-                               return true;
-                       }
-                       
-                       return false;
+
+               return $matrix.$name."/";
+       }
+
+       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;
                }
-               
-               /**
-                * Delete this file.
-                */
-               public function delete()
-               {
-                       $fs = $this->getFilestore();
-                       if ($fs->delete($this)) {
-                               return parent::delete();
-                       }
+
+               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;
                }
-               
-               /**
-                * Seek a position in the file.
-                * 
-                * @param int $position
-                */
-               public function seek($position)
-               {
-                       $fs = $this->getFilestore();
-                       
-                       return $fs->seek($this->handle, $position);
+               $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;
                }
-               
-               /**
-                * Return the current position of the file.
-                * 
-                * @return int The file position
-                */
-               public function tell()
-               {
-                       $fs = $this->getFilestore();
-                       
-                       return $fs->tell($this->handle);
+
+               // 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'));
                }
-       
-               /**
-                * Return the size of the file in bytes.
-                */
-               public function size()
-               {
-                       return $this->filestore->getFileSize($this);
+
+               // 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));
                }
-               
-               /**
-                * 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);
+
+               // 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;
                }
-               
-               public function exists()
-               {
-                       $fs = $this->getFilestore();
-                       
-                       return $fs->exists($this);
+
+               return false;
+       }
+
+       /**
+        * Delete this file.
+        */
+       public function delete() {
+               $fs = $this->getFilestore();
+               if ($fs->delete($this)) {
+                       return parent::delete();
                }
-               
-               /**
-                * Set a filestore.
-                * 
-                * @param ElggFilestore $filestore The file store.
-                */
-               public function setFilestore(ElggFilestore $filestore)
-               {
-                       $this->filestore = $filestore;  
+       }
+
+       /**
+        * 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;
                }
-               
-               /**
-                * 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)
-                               {
+
+               // 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]; 
-                       
+                                       $name = $comp[1];
+
                                        $parameters[$name] = $meta->value;
                                }
                        }
-               
-                       // If parameters loaded then create new filestore
-                       if (count($parameters)!=0)
-                       {
-                               // Create new filestore object
-                               if ((!isset($parameters['filestore'])) || (!class_exists($parameters['filestore'])))
-                                       throw new ClassNotFoundException(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile'));
-                                       
-                               $this->filestore = new $parameters['filestore']();
-
-                               // Set parameters
-                               $this->filestore->setParameters($parameters);
+               }
+
+               // If parameters loaded then create new filestore
+               if (count($parameters)!=0) {
+                       // Create new filestore object
+                       if ((!isset($parameters['filestore'])) || (!class_exists($parameters['filestore']))) {
+                               throw new ClassNotFoundException(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile'));
                        }
-                       
 
-                       // if still nothing then set filestore to default
-                       if (!$this->filestore)
-                               $this->filestore = get_default_filestore();
+                       $this->filestore = new $parameters['filestore']();
 
-                       return $this->filestore;
+                       // Set parameters
+                       $this->filestore->setParameters($parameters);
                }
-               
-               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;
+
+
+               // if still nothing then set filestore to default
+               if (!$this->filestore) {
+                       $this->filestore = get_default_filestore();
                }
-               
+
+               return $this->filestore;
        }
-       
-       /**
-        * Get the size of the specified directory.
-        *
-        * @param string $dir The full path of the directory
-        * @return int The size of the directory.
-        */
-       function get_dir_size($dir,$totalsize = 0){
-           $handle = @opendir($dir);
-           while ($file = @readdir ($handle)){
-               if (eregi("^\.{1,2}$",$file))
-                   continue;
-               if(is_dir($dir.$file)){
-                       $totalsize = get_dir_size($dir.$file."/",$totalsize);
-                   } else{
-                       $totalsize += filesize($dir.$file);
-                   }
-           }
-           @closedir($handle);
-       
-           return($totalsize);
-       }
-       
-       /**
-        * Get the contents of an uploaded file.
-        * (Returns false if there was an issue.)
-        *
-        * @param string $input_name The name of the file input field on the submission form
-        * @return mixed|false The contents of the file, or false on failure.
-        */
-       function get_uploaded_file($input_name) {
-               
-               // If the file exists ...
-               if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) {
-                       return file_get_contents($_FILES[$input_name]['tmp_name']);
+
+       public function save() {
+               if (!parent::save()) {
+                       return false;
                }
-               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;
        }
-       
-       /**
-        * Gets the jpeg contents of the resized version of an uploaded image 
-        * (Returns false if the uploaded file was not an image)
-        *
-        * @param string $input_name The name of the file input field on the submission form
-        * @param int $maxwidth The maximum width of the resized image
-        * @param int $maxheight The maximum height of the resized image
-        * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped.
-        * @return false|mixed The contents of the resized image, or false on failure
-        */
-       function get_resized_image_from_uploaded_file($input_name, $maxwidth, $maxheight, $square = false) {
-               // If our file exists ...
-               if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) {
-                       
-                       return get_resized_image_from_existing_file($_FILES[$input_name]['tmp_name'], $maxwidth, $maxheight, $square);
-                       
+}
+
+/**
+ * Get the size of the specified directory.
+ *
+ * @param string $dir The full path of the directory
+ * @return int The size of the directory.
+ */
+function get_dir_size($dir, $totalsize = 0){
+       $handle = @opendir($dir);
+       while ($file = @readdir ($handle)){
+               if (eregi("^\.{1,2}$", $file)) {
+                       continue;
+               }
+               if(is_dir($dir . $file)) {
+                       $totalsize = get_dir_size($dir . $file . "/", $totalsize);
+               } else{
+                       $totalsize += filesize($dir . $file);
                }
-               
-               return false;
        }
-       
-       /**
-        * Gets the jpeg contents of the resized version of an already uploaded image 
-        * (Returns false if the uploaded file was not an image)
-        *
-        * @param string $input_name The name of the file input field on the submission form
-        * @param int $maxwidth The maximum width of the resized image
-        * @param int $maxheight The maximum height of the resized image
-        * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped.
-        * @return false|mixed The contents of the resized image, or false on failure
-        */
-       function get_resized_image_from_existing_file($input_name, $maxwidth, $maxheight, $square = false, $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0) {
-               
-               // Get the size information from the image
-               if ($imgsizearray = getimagesize($input_name)) {
-               
-                       // Get width and height
-                       $width = $imgsizearray[0];
-                       $height = $imgsizearray[1];
+       @closedir($handle);
+
+       return($totalsize);
+}
+
+/**
+ * Get the contents of an uploaded file.
+ * (Returns false if there was an issue.)
+ *
+ * @param string $input_name The name of the file input field on the submission form
+ * @return mixed|false The contents of the file, or false on failure.
+ */
+function get_uploaded_file($input_name) {
+       // If the file exists ...
+       if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) {
+               return file_get_contents($_FILES[$input_name]['tmp_name']);
+       }
+       return false;
+}
+
+/**
+ * Gets the jpeg contents of the resized version of an uploaded image
+ * (Returns false if the uploaded file was not an image)
+ *
+ * @param string $input_name The name of the file input field on the submission form
+ * @param int $maxwidth The maximum width of the resized image
+ * @param int $maxheight The maximum height of the resized image
+ * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped.
+ * @return false|mixed The contents of the resized image, or false on failure
+ */
+function get_resized_image_from_uploaded_file($input_name, $maxwidth, $maxheight, $square = false) {
+       // If our file exists ...
+       if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) {
+               return get_resized_image_from_existing_file($_FILES[$input_name]['tmp_name'], $maxwidth, $maxheight, $square);
+       }
+
+       return false;
+}
+
+/**
+ * Gets the jpeg contents of the resized version of an already uploaded image
+ * (Returns false if the uploaded file was not an image)
+ *
+ * @param string $input_name The name of the file input field on the submission form
+ * @param int $maxwidth The maximum width of the resized image
+ * @param int $maxheight The maximum height of the resized image
+ * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped.
+ * @return false|mixed The contents of the resized image, or false on failure
+ */
+function get_resized_image_from_existing_file($input_name, $maxwidth, $maxheight, $square = false, $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0) {
+       // Get the size information from the image
+       if ($imgsizearray = getimagesize($input_name)) {
+               // Get width and height
+               $width = $imgsizearray[0];
+               $height = $imgsizearray[1];
+               $newwidth = $width;
+               $newheight = $height;
+
+               // Square the image dimensions if we're wanting a square image
+               if ($square) {
+                       if ($width < $height) {
+                               $height = $width;
+                       } else {
+                               $width = $height;
+                       }
+
                        $newwidth = $width;
                        $newheight = $height;
-                       
-                       // Square the image dimensions if we're wanting a square image
-                       if ($square) {
-                               if ($width < $height) {
-                                       $height = $width;
+               }
+
+               if ($width > $maxwidth) {
+                       $newheight = floor($height * ($maxwidth / $width));
+                       $newwidth = $maxwidth;
+               }
+
+               if ($newheight > $maxheight) {
+                       $newwidth = floor($newwidth * ($maxheight / $newheight));
+                       $newheight = $maxheight;
+               }
+
+               $accepted_formats = array(
+                       'image/jpeg' => 'jpeg',
+                       'image/png' => 'png',
+                       'image/gif' => 'gif'
+               );
+
+               // If it's a file we can manipulate ...
+               if (array_key_exists($imgsizearray['mime'],$accepted_formats)) {
+                       $function = "imagecreatefrom" . $accepted_formats[$imgsizearray['mime']];
+                       $newimage = imagecreatetruecolor($newwidth,$newheight);
+
+                       if (is_callable($function) && $oldimage = $function($input_name)) {
+                               // Crop the image if we need a square
+                               if ($square) {
+                                       if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) {
+                                               $widthoffset = floor(($imgsizearray[0] - $width) / 2);
+                                               $heightoffset = floor(($imgsizearray[1] - $height) / 2);
+                                       } else {
+                                               $widthoffset = $x1;
+                                               $heightoffset = $y1;
+                                               $width = ($x2 - $x1);
+                                               $height = $width;
+                                       }
                                } else {
-                                       $width = $height;
-                               }
-                               
-                               $newwidth = $width;
-                               $newheight = $height;
-                               
-                       }
-                       
-                       if ($width > $maxwidth) {
-                               $newheight = floor($height * ($maxwidth / $width));
-                               $newwidth = $maxwidth;
-                       }
-                       if ($newheight > $maxheight) {
-                               $newwidth = floor($newwidth * ($maxheight / $newheight));
-                               $newheight = $maxheight; 
-                       }
-                       
-                       $accepted_formats = array(
-                                                                                       'image/jpeg' => 'jpeg',
-                                                                                       'image/png' => 'png',
-                                                                                       'image/gif' => 'gif'
-                                                                       );
-                       
-                       // If it's a file we can manipulate ...
-                       if (array_key_exists($imgsizearray['mime'],$accepted_formats)) {
-
-                               $function = "imagecreatefrom" . $accepted_formats[$imgsizearray['mime']];
-                               $newimage = imagecreatetruecolor($newwidth,$newheight);
-                               
-                               if (is_callable($function) && $oldimage = $function($input_name)) {
-                               
-                                       // Crop the image if we need a square
-                                       if ($square) {
-                                               if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) {
-                                                       $widthoffset = floor(($imgsizearray[0] - $width) / 2);
-                                                       $heightoffset = floor(($imgsizearray[1] - $height) / 2);
-                                               } else {
-                                                       $widthoffset = $x1;
-                                                       $heightoffset = $y1;
-                                                       $width = ($x2 - $x1);
-                                                       $height = $width;
-                                               }
+                                       if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) {
+                                               $widthoffset = 0;
+                                               $heightoffset = 0;
                                        } else {
-                                               if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) {
-                                                       $widthoffset = 0;
-                                                       $heightoffset = 0;
-                                               } else {
-                                                       $widthoffset = $x1;
-                                                       $heightoffset = $y1;
-                                                       $width = ($x2 - $x1);
-                                                       $height = ($y2 - $y1);
-                                               }
-                                       }//else {
-                                               // Resize and return the image contents!
-                                               if ($square) {
-                                                       $newheight = $maxheight;
-                                                       $newwidth = $maxwidth;
-                                               }
-                                               imagecopyresampled($newimage, $oldimage, 0,0,$widthoffset,$heightoffset,$newwidth,$newheight,$width,$height);
-                                       //}
-                                       
-                                       // imagecopyresized($newimage, $oldimage, 0,0,0,0,$newwidth,$newheight,$width,$height);
-                                       ob_start();
-                                       imagejpeg($newimage, null, 90);
-                                       $jpeg = ob_get_clean();
-                                       return $jpeg;
-                                       
-                               }
-                               
+                                               $widthoffset = $x1;
+                                               $heightoffset = $y1;
+                                               $width = ($x2 - $x1);
+                                               $height = ($y2 - $y1);
+                                       }
+                               }//else {
+                                       // Resize and return the image contents!
+                                       if ($square) {
+                                               $newheight = $maxheight;
+                                               $newwidth = $maxwidth;
+                                       }
+                                       imagecopyresampled($newimage, $oldimage, 0,0,$widthoffset,$heightoffset,$newwidth,$newheight,$width,$height);
+                               //}
+
+                               // imagecopyresized($newimage, $oldimage, 0,0,0,0,$newwidth,$newheight,$width,$height);
+                               ob_start();
+                               imagejpeg($newimage, null, 90);
+                               $jpeg = ob_get_clean();
+                               return $jpeg;
                        }
-                       
                }
-                       
-               return false;
        }
-       
-
-       // putting these here for now
-
-       function file_delete($guid) {
-               if ($file = get_entity($guid)) {
-       
-                       if ($file->canEdit()) {
-       
-                               $container = get_entity($file->container_guid);
-                               
-                               $thumbnail = $file->thumbnail;
-                               $smallthumb = $file->smallthumb;
-                               $largethumb = $file->largethumb;
-                               if ($thumbnail) {
-       
-                                       $delfile = new ElggFile();
-                                       $delfile->owner_guid = $file->owner_guid;
-                                       $delfile->setFilename($thumbnail);
-                                       $delfile->delete();
-       
-                               }
-                               if ($smallthumb) {
-       
-                                       $delfile = new ElggFile();
-                                       $delfile->owner_guid = $file->owner_guid;
-                                       $delfile->setFilename($smallthumb);
-                                       $delfile->delete();
-       
-                               }
-                               if ($largethumb) {
-       
-                                       $delfile = new ElggFile();
-                                       $delfile->owner_guid = $file->owner_guid;
-                                       $delfile->setFilename($largethumb);
-                                       $delfile->delete();
-       
-                               }
-                               
-                               return $file->delete();
+
+       return false;
+}
+
+
+// putting these here for now
+
+function file_delete($guid) {
+       if ($file = get_entity($guid)) {
+               if ($file->canEdit()) {
+                       $container = get_entity($file->container_guid);
+
+                       $thumbnail = $file->thumbnail;
+                       $smallthumb = $file->smallthumb;
+                       $largethumb = $file->largethumb;
+                       if ($thumbnail) {
+                               $delfile = new ElggFile();
+                               $delfile->owner_guid = $file->owner_guid;
+                               $delfile->setFilename($thumbnail);
+                               $delfile->delete();
+                       }
+                       if ($smallthumb) {
+                               $delfile = new ElggFile();
+                               $delfile->owner_guid = $file->owner_guid;
+                               $delfile->setFilename($smallthumb);
+                               $delfile->delete();
                        }
+                       if ($largethumb) {
+                               $delfile = new ElggFile();
+                               $delfile->owner_guid = $file->owner_guid;
+                               $delfile->setFilename($largethumb);
+                               $delfile->delete();
+                       }
+
+                       return $file->delete();
                }
-               
-               return false;
        }
-       
-       /**
-        * Returns an overall file type from the mimetype
-        *
-        * @param string $mimetype The MIME type
-        * @return string The overall type
-        */
-       function file_get_general_file_type($mimetype) {
-               
-               switch($mimetype) {
-                       
-                       case "application/msword":
-                                                                               return "document";
-                                                                               break;
-                       case "application/pdf":
-                                                                               return "document";
-                                                                               break;
-                       
-               }
-               
-               if (substr_count($mimetype,'text/'))
+
+       return false;
+}
+
+/**
+ * Returns an overall file type from the mimetype
+ *
+ * @param string $mimetype The MIME type
+ * @return string The overall type
+ */
+function file_get_general_file_type($mimetype) {
+       switch($mimetype) {
+
+               case "application/msword":
                        return "document";
-                       
-               if (substr_count($mimetype,'audio/'))
-                       return "audio";
-                       
-               if (substr_count($mimetype,'image/'))
-                       return "image";
-                       
-               if (substr_count($mimetype,'video/'))
-                       return "video";
-
-               if (substr_count($mimetype,'opendocument'))
-                       return "document";      
-                       
-               return "general";
-               
-       }
-       
-       function file_handle_upload($prefix,$subtype,$plugin) {         
-               $desc = get_input("description");
-               $tags = get_input("tags");
-               $tags = explode(",", $tags);
-               $folder = get_input("folder_text");
-               if (!$folder) {
-                       $folder = get_input("folder_select");
+                       break;
+               case "application/pdf":
+                       return "document";
+                       break;
+       }
+
+       if (substr_count($mimetype,'text/')) {
+               return "document";
+       }
+
+       if (substr_count($mimetype,'audio/')) {
+               return "audio";
+       }
+
+       if (substr_count($mimetype,'image/')) {
+               return "image";
+       }
+
+       if (substr_count($mimetype,'video/')) {
+               return "video";
+       }
+
+       if (substr_count($mimetype,'opendocument')) {
+               return "document";
+       }
+
+       return "general";
+}
+
+function file_handle_upload($prefix,$subtype,$plugin) {
+       $desc = get_input("description");
+       $tags = get_input("tags");
+       $tags = explode(",", $tags);
+       $folder = get_input("folder_text");
+       if (!$folder) {
+               $folder = get_input("folder_select");
+       }
+       $access_id = (int) get_input("access_id");
+       $container_guid = (int) get_input('container_guid', 0);
+       if (!$container_guid) {
+               $container_guid == get_loggedin_userid();
+       }
+
+       // Extract file from, save to default filestore (for now)
+
+       // see if a plugin has set a quota for this user
+       $file_quota = trigger_plugin_hook("$plugin:quotacheck",'user',array('container_guid'=>$container_guid));
+       if (!$file_quota) {
+               // no, see if there is a generic quota set
+               $file_quota = get_plugin_setting('quota', $plugin);
+       }
+       if ($file_quota) {
+               // convert to megabytes
+               $file_quota = $file_quota*1000*1024;
+       }
+
+       // handle uploaded files
+       $number_of_files = get_input('number_of_files',0);
+       $quota_exceeded = false;
+       $bad_mime_type = false;
+
+       for ($i = 0; $i < $number_of_files; $i++) {
+               $title = get_input("title_".$i);
+               $uploaded = $_FILES["upload_".$i];
+               if (!$uploaded || !$uploaded['name']) {
+                       // no such file, so skip it
+                       continue;
                }
-               $access_id = (int) get_input("access_id");
-               $container_guid = (int) get_input('container_guid', 0);
-               if (!$container_guid)
-                       $container_guid == get_loggedin_userid();
-               
-               // Extract file from, save to default filestore (for now)
-               
-               // see if a plugin has set a quota for this user
-               $file_quota = trigger_plugin_hook("$plugin:quotacheck",'user',array('container_guid'=>$container_guid));
-               if (!$file_quota) {
-                       // no, see if there is a generic quota set
-                       $file_quota = get_plugin_setting('quota', $plugin);
+               if ($plugin == "photo") {
+                       // do a mime type test
+                       if (in_array($uploaded['type'],array('image/jpeg','image/gif','image/png','image/jpg','image/jpe','image/pjpeg','image/x-png'))) {
+                               $file = new PhotoPluginFile();
+                       } else {
+                               $bad_mime_type = true;
+                               break;
+                       }
+               } else {
+                       $file = new FilePluginFile();
                }
+               $dir_size = $file->getFilestoreSize($prefix,$container_guid);
+               $filestorename = strtolower(time().$uploaded['name']);
+               $file->setFilename($prefix.$filestorename);
+               $file->setMimeType($uploaded['type']);
+
+               $file->originalfilename = $uploaded['name'];
+
+               $file->subtype = $subtype;
+
+               $file->access_id = $access_id;
+
+               $uf = get_uploaded_file('upload_'.$i);
+
                if ($file_quota) {
-                       // convert to megabytes
-                       $file_quota = $file_quota*1000*1024;
-               }
-               
-               // handle uploaded files
-               $number_of_files = get_input('number_of_files',0);
-               $quota_exceeded = false;
-               $bad_mime_type = false;
-               
-               for ($i = 0; $i < $number_of_files; $i++) {
-                       
-                       $title = get_input("title_".$i);
-                       $uploaded = $_FILES["upload_".$i];
-                       if (!$uploaded || !$uploaded['name']) {
-                               // no such file, so skip it
-                               continue;
+                       $file_size = strlen($uf);
+                       if (($dir_size + $file_size) > $file_quota) {
+                               $quota_exceeded = true;
                        }
-                       if ($plugin == "photo") {
-                               // do a mime type test
-                               if (in_array($uploaded['type'],array('image/jpeg','image/gif','image/png','image/jpg','image/jpe','image/pjpeg','image/x-png'))) {
-                                       $file = new PhotoPluginFile();
-                               } else {
-                                       $bad_mime_type = true;
-                                       break;
-                               }
-                               
-                       } else {
-                               $file = new FilePluginFile();
-                       }
-                       $dir_size = $file->getFilestoreSize($prefix,$container_guid);
-                       $filestorename = strtolower(time().$uploaded['name']);
-                       $file->setFilename($prefix.$filestorename);
-                       $file->setMimeType($uploaded['type']);
-               
-                       $file->originalfilename = $uploaded['name'];
-               
-                       $file->subtype = $subtype;
-               
-                       $file->access_id = $access_id;
-               
-                       $uf = get_uploaded_file('upload_'.$i);
-               
-                       if ($file_quota) {
-                               $file_size = strlen($uf);
-                               if (($dir_size + $file_size) > $file_quota) {
-                                       $quota_exceeded = true;         
-                               }               
+               }
+
+               if (!$quota_exceeded) {
+                       // all clear, so try to save the data
+
+                       $file->open("write");
+                       $file->write($uf);
+                       $file->close();
+
+                       $file->title = $title;
+                       $file->description = $desc;
+                       if ($container_guid) {
+                               $file->container_guid = $container_guid;
                        }
-                       
-                       if (!$quota_exceeded) {
-                               // all clear, so try to save the data
-               
-                               $file->open("write");
-                               $file->write($uf);
-                               $file->close();
-                               
-                               $file->title = $title;
-                               $file->description = $desc;
-                               if ($container_guid)
-                                       $file->container_guid = $container_guid;
-                               
-                               // Save tags
-                               $file->tags = $tags;
-                               
-                               $file->simpletype = file_get_general_file_type($uploaded['type']);
-                               $file->folder = $folder;
-                               
-                               $result = $file->save();
-                               
-                               if ($result)
-                               {
-                                       
-                                       // Generate thumbnail (if image)
-                                       if (substr_count($file->getMimeType(),'image/'))
-                                       {
-                                               $thumbnail = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),60,60, true);
-                                               $thumbsmall = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),153,153, true);
-                                               $thumblarge = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),600,600, false);
-                                               if ($thumbnail) {
-                                                       $thumb = new ElggFile();
-                                                       $thumb->setMimeType($uploaded['type']);
-                                                       
-                                                       $thumb->setFilename($prefix."thumb".$filestorename);
-                                                       $thumb->open("write");
-                                                       $thumb->write($thumbnail);
-                                                       $thumb->close();
-                                                       
-                                                       $file->thumbnail = $prefix."thumb".$filestorename;
-                                                       
-                                                       $thumb->setFilename($prefix."smallthumb".$filestorename);
-                                                       $thumb->open("write");
-                                                       $thumb->write($thumbsmall);
-                                                       $thumb->close();
-                                                       $file->smallthumb = $prefix."smallthumb".$filestorename;
-                                                       
-                                                       $thumb->setFilename($prefix."largethumb".$filestorename);
-                                                       $thumb->open("write");
-                                                       $thumb->write($thumblarge);
-                                                       $thumb->close();
-                                                       $file->largethumb = $prefix."largethumb".$filestorename;
-                                                               
-                                               }
+
+                       // Save tags
+                       $file->tags = $tags;
+
+                       $file->simpletype = file_get_general_file_type($uploaded['type']);
+                       $file->folder = $folder;
+
+                       $result = $file->save();
+
+                       if ($result) {
+
+                               // Generate thumbnail (if image)
+                               if (substr_count($file->getMimeType(),'image/')) {
+                                       $thumbnail = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),60,60, true);
+                                       $thumbsmall = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),153,153, true);
+                                       $thumblarge = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),600,600, false);
+                                       if ($thumbnail) {
+                                               $thumb = new ElggFile();
+                                               $thumb->setMimeType($uploaded['type']);
+
+                                               $thumb->setFilename($prefix."thumb".$filestorename);
+                                               $thumb->open("write");
+                                               $thumb->write($thumbnail);
+                                               $thumb->close();
+
+                                               $file->thumbnail = $prefix."thumb".$filestorename;
+
+                                               $thumb->setFilename($prefix."smallthumb".$filestorename);
+                                               $thumb->open("write");
+                                               $thumb->write($thumbsmall);
+                                               $thumb->close();
+                                               $file->smallthumb = $prefix."smallthumb".$filestorename;
+
+                                               $thumb->setFilename($prefix."largethumb".$filestorename);
+                                               $thumb->open("write");
+                                               $thumb->write($thumblarge);
+                                               $thumb->close();
+                                               $file->largethumb = $prefix."largethumb".$filestorename;
                                        }
-                               
-                                       // add to this user's file folders
-                                       file_add_to_folders($folder,$container_guid,$plugin);
-                                       
-                                       add_to_river("river/object/$plugin/create",'create',$_SESSION['user']->guid,$file->guid);
-                               } else {
-                                       break;
                                }
+
+                               // add to this user's file folders
+                               file_add_to_folders($folder,$container_guid,$plugin);
+
+                               add_to_river("river/object/$plugin/create",'create',$_SESSION['user']->guid,$file->guid);
                        } else {
                                break;
                        }
+               } else {
+                       break;
                }
-               
-               if ($quota_exceeded) {
-                       echo elgg_echo("$plugin:quotaexceeded");
-               } else if ($bad_mime_type)      {
-                       echo elgg_echo("$plugin:badmimetype");
-               } else if ($result) {
-                       if ($number_of_files > 1) {
-                               echo elgg_echo("$plugin:saved_multi");
-                       } else {
-                               echo elgg_echo("$plugin:saved");
-                       }
-           } else {
-               if ($number_of_files > 1) {
-                               echo elgg_echo("$plugin:uploadfailed_multi");
-               } else {
-                       echo elgg_echo("$plugin:uploadfailed");
-               }
+       }
+
+       if ($quota_exceeded) {
+               echo elgg_echo("$plugin:quotaexceeded");
+       } else if ($bad_mime_type)      {
+               echo elgg_echo("$plugin:badmimetype");
+       } else if ($result) {
+               if ($number_of_files > 1) {
+                       echo elgg_echo("$plugin:saved_multi");
+               } else {
+                       echo elgg_echo("$plugin:saved");
+               }
+       } else {
+               if ($number_of_files > 1) {
+                       echo elgg_echo("$plugin:uploadfailed_multi");
+               } else {
+                       echo elgg_echo("$plugin:uploadfailed");
                }
        }
-       
-       function file_add_to_folders($folder,$container_guid,$plugin) {
-               if ($container_guid && ($container = get_entity($container_guid))) {
-                       $folder_field_name = 'elgg_'.$plugin.'_folders';
-                       $folders = $container->$folder_field_name;
-                       if ($folders) {
-                               if (is_array($folders)) {
-                                       if (!in_array($folder,$folders)) {
-                                               $folders[] = $folder;
-                                               $container->$folder_field_name = $folders;
-                                       }
-                               } else {
-                                       if ($folders != $folder) {
-                                               $container->$folder_field_name = array($folders,$folder);
-                                       }
+}
+
+function file_add_to_folders($folder,$container_guid,$plugin) {
+       if ($container_guid && ($container = get_entity($container_guid))) {
+               $folder_field_name = 'elgg_'.$plugin.'_folders';
+               $folders = $container->$folder_field_name;
+               if ($folders) {
+                       if (is_array($folders)) {
+                               if (!in_array($folder,$folders)) {
+                                       $folders[] = $folder;
+                                       $container->$folder_field_name = $folders;
+                               }
+                       } else {
+                               if ($folders != $folder) {
+                                       $container->$folder_field_name = array($folders,$folder);
                                }
-                       } else {                                
-                               $container->$folder_field_name = $folder;
                        }
+               } else {
+                       $container->$folder_field_name = $folder;
                }
        }
-       
-       function file_handle_save($forward,$plugin) {
-               // Get variables
-               $title = get_input("title");
-               $desc = get_input("description");
-               $tags = get_input("tags");
-               $folder = get_input("folder_text");
-               if (!$folder) {
-                       $folder = get_input("folder_select");
+}
+
+function file_handle_save($forward,$plugin) {
+       // Get variables
+       $title = get_input("title");
+       $desc = get_input("description");
+       $tags = get_input("tags");
+       $folder = get_input("folder_text");
+       if (!$folder) {
+               $folder = get_input("folder_select");
+       }
+       $access_id = (int) get_input("access_id");
+
+       $guid = (int) get_input('file_guid');
+
+       if (!$file = get_entity($guid)) {
+               register_error(elgg_echo("$plugin:uploadfailed"));
+               forward($forward . $_SESSION['user']->username);
+               exit;
+       }
+
+       $result = false;
+
+       $container_guid = $file->container_guid;
+       $container = get_entity($container_guid);
+
+       if ($file->canEdit()) {
+               $file->access_id = $access_id;
+               $file->title = $title;
+               $file->description = $desc;
+               $file->folder = $folder;
+               // add to this user's file folders
+               file_add_to_folders($folder,$container_guid,$plugin);
+
+               // Save tags
+               $tags = explode(",", $tags);
+               $file->tags = $tags;
+
+               $result = $file->save();
+       }
+
+       if ($result) {
+               system_message(elgg_echo("$plugin:saved"));
+       } else {
+               register_error(elgg_echo("$plugin:uploadfailed"));
+       }
+       forward($forward . $container->username);
+}
+
+/**
+ * Manage a file download.
+ *
+ * @param unknown_type $plugin
+ * @param unknown_type $file_guid If not specified then file_guid will be found in input.
+ */
+function file_manage_download($plugin, $file_guid = "") {
+       // Get the guid
+       $file_guid = (int)$file_guid;
+
+       if (!$file_guid) {
+               $file_guid = (int)get_input("file_guid");
+       }
+
+       // Get the file
+       $file = get_entity($file_guid);
+
+       if ($file) {
+               $mime = $file->getMimeType();
+               if (!$mime) {
+                       $mime = "application/octet-stream";
                }
-               $access_id = (int) get_input("access_id");
-               
-               $guid = (int) get_input('file_guid');
-               
-               if (!$file = get_entity($guid)) {
-                       register_error(elgg_echo("$plugin:uploadfailed"));
-                       forward($forward . $_SESSION['user']->username);
-                       exit;
+
+               $filename = $file->originalfilename;
+
+               header("Content-type: $mime");
+               if (strpos($mime, "image/")!==false) {
+                       header("Content-Disposition: inline; filename=\"$filename\"");
+               } else {
+                       header("Content-Disposition: attachment; filename=\"$filename\"");
                }
-               
-               $result = false;
-               
-               $container_guid = $file->container_guid;
-               $container = get_entity($container_guid);
-               
-               if ($file->canEdit()) {
-               
-                       $file->access_id = $access_id;
-                       $file->title = $title;
-                       $file->description = $desc;
-                       $file->folder = $folder;
-                       // add to this user's file folders
-                       file_add_to_folders($folder,$container_guid,$plugin);
-               
-                       // Save tags
-                               $tags = explode(",", $tags);
-                               $file->tags = $tags;
-       
-                               $result = $file->save();
+
+               echo $file->grabFile();
+               exit;
+       } else {
+               register_error(elgg_echo("$plugin:downloadfailed"));
+       }
+}
+
+/**
+ * Manage the download of a file icon.
+ *
+ * @param unknown_type $plugin
+ * @param unknown_type $file_guid The guid, if not specified this is obtained from the input.
+ */
+function file_manage_icon_download($plugin, $file_guid = "") {
+       // Get the guid
+       $file_guid = (int)$file_guid;
+
+       if (!$file_guid) {
+               $file_guid = (int)get_input("file_guid");
+       }
+
+       // Get the file
+       $file = get_entity($file_guid);
+
+       if ($file) {
+               $mime = $file->getMimeType();
+               if (!$mime) {
+                       $mime = "application/octet-stream";
                }
-               
-               if ($result)
-                       system_message(elgg_echo("$plugin:saved"));
-               else
-                       register_error(elgg_echo("$plugin:uploadfailed"));
-               
-               forward($forward . $container->username);
-       }
-       
-       /**
-        * Manage a file download.
-        *
-        * @param unknown_type $plugin
-        * @param unknown_type $file_guid If not specified then file_guid will be found in input.
-        */
-       function file_manage_download($plugin, $file_guid = "") {
-               // Get the guid
-               $file_guid = (int)$file_guid;
-               
-               if (!$file_guid)
-                       $file_guid = (int)get_input("file_guid");
-               
-               // Get the file
-               $file = get_entity($file_guid);
-               
-               if ($file)
-               {
-                       $mime = $file->getMimeType();
-                       if (!$mime) $mime = "application/octet-stream";
-                       
-                       $filename = $file->originalfilename;
-                       
-                       header("Content-type: $mime");
-                       if (strpos($mime, "image/")!==false)
-                               header("Content-Disposition: inline; filename=\"$filename\"");
-                       else
-                               header("Content-Disposition: attachment; filename=\"$filename\"");
-       
-                       echo $file->grabFile();
-                       exit;
+
+               $filename = $file->thumbnail;
+
+               header("Content-type: $mime");
+               if (strpos($mime, "image/")!==false) {
+                       header("Content-Disposition: inline; filename=\"$filename\"");
+               } else {
+                       header("Content-Disposition: attachment; filename=\"$filename\"");
                }
-               else
-                       register_error(elgg_echo("$plugin:downloadfailed"));
-       }
-       
-       /**
-        * Manage the download of a file icon.
-        *
-        * @param unknown_type $plugin
-        * @param unknown_type $file_guid The guid, if not specified this is obtained from the input.
-        */
-       function file_manage_icon_download($plugin, $file_guid = "") {
-               // Get the guid
-               $file_guid = (int)$file_guid;
-               
-               if (!$file_guid)
-                       $file_guid = (int)get_input("file_guid");
-               
-               // Get the file
-               $file = get_entity($file_guid);
-               
-               if ($file)
+
+               $readfile = new ElggFile();
+               $readfile->owner_guid = $file->owner_guid;
+               $readfile->setFilename($filename);
+
+               /*
+               if ($file->open("read"));
                {
-                       $mime = $file->getMimeType();
-                       if (!$mime) $mime = "application/octet-stream";
-                       
-                       $filename = $file->thumbnail;
-                       
-                       header("Content-type: $mime");
-                       if (strpos($mime, "image/")!==false)
-                               header("Content-Disposition: inline; filename=\"$filename\"");
-                       else
-                               header("Content-Disposition: attachment; filename=\"$filename\"");
-       
-                               
-                       $readfile = new ElggFile();
-                       $readfile->owner_guid = $file->owner_guid;
-                       $readfile->setFilename($filename);
-                               
-                       /*
-                       if ($file->open("read"));
+                       while (!$file->eof())
                        {
-                               while (!$file->eof())
-                               {
-                                       echo $file->read(10240, $file->tell()); 
-                               }
+                               echo $file->read(10240, $file->tell());
                        }
-                       */
-       
-                       $contents = $readfile->grabFile();
-                       if (empty($contents)) {
-                               echo file_get_contents(dirname(dirname(__FILE__)) . "/graphics/icons/general.jpg" );
+               }
+               */
+
+               $contents = $readfile->grabFile();
+               if (empty($contents)) {
+                       echo file_get_contents(dirname(dirname(__FILE__)) . "/graphics/icons/general.jpg" );
+               } else {
+                       echo $contents;
+               }
+               exit;
+       } else {
+               register_error(elgg_echo("$plugin:downloadfailed"));
+       }
+}
+
+function file_display_thumbnail($file_guid,$size) {
+       // Get file entity
+       if ($file = get_entity($file_guid)) {
+               $simpletype = $file->simpletype;
+               if ($simpletype == "image") {
+                       // Get file thumbnail
+                       if ($size == "small") {
+                               $thumbfile = $file->smallthumb;
                        } else {
+                               $thumbfile = $file->largethumb;
+                       }
+
+                       // Grab the file
+                       if ($thumbfile && !empty($thumbfile)) {
+                               $readfile = new ElggFile();
+                               $readfile->owner_guid = $file->owner_guid;
+                               $readfile->setFilename($thumbfile);
+                               $mime = $file->getMimeType();
+                               $contents = $readfile->grabFile();
+
+                               header("Content-type: $mime");
                                echo $contents;
+                               exit;
                        }
-                       exit;
-               }
-               else
-                       register_error(elgg_echo("$plugin:downloadfailed"));
-       }
-       
-       function file_display_thumbnail($file_guid,$size) {
-               // Get file entity
-               if ($file = get_entity($file_guid)) {                           
-                       $simpletype = $file->simpletype;
-                       if ($simpletype == "image") {                           
-                               // Get file thumbnail
-                               if ($size == "small") {
-                                       $thumbfile = $file->smallthumb;
-                               } else {
-                                       $thumbfile = $file->largethumb;
-                               }
-                               
-                               // Grab the file
-                               if ($thumbfile && !empty($thumbfile)) {
-                                       $readfile = new ElggFile();
-                                       $readfile->owner_guid = $file->owner_guid;
-                                       $readfile->setFilename($thumbfile);
-                                       $mime = $file->getMimeType();
-                                       $contents = $readfile->grabFile();
-                                       
-                                       header("Content-type: $mime");
-                                       echo $contents;
-                                       exit;
-                                       
-                               }                               
-                       }                       
                }
        }
-       
-       function file_set_page_owner($file) {
-               $page_owner = page_owner_entity();
-               if ($page_owner === false || is_null($page_owner)) {
-                       $container_guid = $file->container_guid;
-                       if (!empty($container_guid))
-                               if ($page_owner = get_entity($container_guid)) {
-                                       set_page_owner($page_owner->guid);
-                               }
-                       if (empty($page_owner)) {
-                               $page_owner = $_SESSION['user'];
-                               set_page_owner($_SESSION['guid']);
+}
+
+function file_set_page_owner($file) {
+       $page_owner = page_owner_entity();
+       if ($page_owner === false || is_null($page_owner)) {
+               $container_guid = $file->container_guid;
+               if (!empty($container_guid)) {
+                       if ($page_owner = get_entity($container_guid)) {
+                               set_page_owner($page_owner->guid);
                        }
                }
-       }
 
-       /// Variable holding the default datastore
-       $DEFAULT_FILE_STORE = NULL;
-       
-       /**
-        * Return the default filestore.
-        *
-        * @return ElggFilestore
-        */
-       function get_default_filestore()
-       {
-               global $DEFAULT_FILE_STORE;
-               
-               return $DEFAULT_FILE_STORE;
-       }
-       
-       /**
-        * Set the default filestore for the system.
-        */
-       function set_default_filestore(ElggFilestore $filestore)
-       {
-               global $DEFAULT_FILE_STORE;
-               
-               $DEFAULT_FILE_STORE = $filestore;
-               
-               return true;
+               if (empty($page_owner)) {
+                       $page_owner = $_SESSION['user'];
+                       set_page_owner($_SESSION['guid']);
+               }
        }
+}
 
-       /**
-        * Run once and only once.
-        */
-       function filestore_run_once()
-       {
-               // Register a class
-               add_subtype("object", "file", "ElggFile");      
-       }
-       
-       /** 
-        * Initialise the file modules. 
-        * Listens to system boot and registers any appropriate file types and classes 
-        */
-       function filestore_init()
-       {
-               global $CONFIG;
-               
-               // Now register a default filestore
-               set_default_filestore(new ElggDiskFilestore($CONFIG->dataroot));
-               
-               // Now run this stuff, but only once
-               run_function_once("filestore_run_once");
-       }
-       
-       // Register a startup event
-       register_elgg_event_handler('init','system','filestore_init',100);      
-?>
+/// Variable holding the default datastore
+$DEFAULT_FILE_STORE = NULL;
+
+/**
+ * Return the default filestore.
+ *
+ * @return ElggFilestore
+ */
+function get_default_filestore() {
+       global $DEFAULT_FILE_STORE;
+
+       return $DEFAULT_FILE_STORE;
+}
+
+/**
+ * Set the default filestore for the system.
+ */
+function set_default_filestore(ElggFilestore $filestore) {
+       global $DEFAULT_FILE_STORE;
+
+       $DEFAULT_FILE_STORE = $filestore;
+
+       return true;
+}
+
+/**
+ * Run once and only once.
+ */
+function filestore_run_once() {
+       // Register a class
+       add_subtype("object", "file", "ElggFile");
+}
+
+/**
+ * Initialise the file modules.
+ * Listens to system boot and registers any appropriate file types and classes
+ */
+function filestore_init() {
+       global $CONFIG;
+
+       // Now register a default filestore
+       set_default_filestore(new ElggDiskFilestore($CONFIG->dataroot));
+
+       // Now run this stuff, but only once
+       run_function_once("filestore_run_once");
+}
+
+// Register a startup event
+register_elgg_event_handler('init', 'system', 'filestore_init', 100);
\ No newline at end of file
index 2941855f78f66f23cc7fda3697b3bca0685d768b..664837a27e09f9ee57d1e829b4099cecffbfee18 100644 (file)
 <?php
-       /**
       * Elgg Groups.
       * Groups contain other entities, or rather act as a placeholder for other entities to mark any given container
       * as their container.
-        * 
       * @package Elgg
       * @subpackage Core
+/**
+ * Elgg Groups.
+ * Groups contain other entities, or rather act as a placeholder for other entities to mark any given container
+ * as their container.
+ *
+ * @package Elgg
+ * @subpackage Core
 
       * @author Curverider Ltd
+ * @author Curverider Ltd
 
-        * @link http://elgg.org/
-        */
+ * @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;
+       }
 
        /**
-        * @class ElggGroup Class representing a container for other elgg entities.
-        * @author Curverider Ltd
+        * 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.
         */
-       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)); 
+       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)
-                               {                                       
-                                        foreach ($guid->attributes as $key => $value)
-                                               $this->attributes[$key] = $value;
+                       }
+                       // Is $guid is an ElggGroup? Use a copy constructor
+                       else if ($guid instanceof ElggGroup) {
+                               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)) IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
+                       }
+                       // 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)) {
+                                       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();
+
+                       else {
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
                        }
-                       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 = "");
+        * Add an ElggObject to this group.
+        *
+        * @param ElggObject $object The object.
+        * @return bool
         */
-               
-               /**
-                * 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));
-               }
+       public function addObjectToGroup(ElggObject $object) {
+               return add_object_to_group($this->getGUID(), $object->getGUID());
+       }
 
-               /**
-                * 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
+        * Remove an object from the containing group.
+        *
+        * @param int $guid The guid of the object.
+        * @return bool
         */
-               
-               /**
-                * 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);
-               }
+       public function removeObjectFromGroup($guid) {
+               return remove_object_from_group($this->getGUID(), $guid);
+       }
 
-               
-               
-               /**
-                * 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())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter
-                       
-                       // 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',
-                       ));
+       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 = "");
+ */
+
        /**
-        * Get the group entity.
-        *
-        * @param int $guid
+        * For compatibility with Friendable
         */
-       function get_group_entity_as_row($guid)
-       {
-               global $CONFIG;
-               
-               $guid = (int)$guid;
-               
-               /*$row = retrieve_cached_entity_row($guid);
-               if ($row)
-               {
-                       // We have already cached this object, so retrieve its value from the cache
-                       if (isset($CONFIG->debug) && $CONFIG->debug)
-                               error_log("** Retrieving sub part of GUID:$guid from cache");
-                               
-                       return $row;
-               }
-               else
-               {*/
-                       // Object not cached, load it.
-                       if (isset($CONFIG->debug) && $CONFIG->debug == true)
-                               error_log("** Sub part of GUID:$guid loaded from DB");
-               
-                       return get_data_row("SELECT * from {$CONFIG->dbprefix}groups_entity where guid=$guid");
-               //}
+       public function addFriend($friend_guid) {
+               return $this->join(get_entity($friend_guid));
        }
 
        /**
-        * Create or update the extras table for a given group.
-        * Call create_entity first.
-        * 
-        * @param int $guid
-        * @param string $name
-        * @param string $description
+        * For compatibility with Friendable
         */
-       function create_group_entity($guid, $name, $description)
-       {
-               global $CONFIG;
-               
-               $guid = (int)$guid;
-               $name = sanitise_string($name);
-               $description = sanitise_string($description);
-               
-               $row = get_entity_as_row($guid);
-               
-               if ($row)
-               {
-                       // Exists and you have access to it
-                       if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}groups_entity WHERE guid = {$guid}")) {
-                               $result = update_data("UPDATE {$CONFIG->dbprefix}groups_entity set name='$name', description='$description' where guid=$guid");
-                               if ($result!=false)
-                               {
-                                       // Update succeeded, continue
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('update',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete();
-                                               //delete_entity($guid);
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               // Update failed, attempt an insert.
-                               $result = insert_data("INSERT into {$CONFIG->dbprefix}groups_entity (guid, name, description) values ($guid, '$name','$description')");
-                               if ($result!==false) {
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('create',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete();
-                                               //delete_entity($guid);
-                                       }
-                               }
-                       }
-               }
-               
-               return false;
+       public function removeFriend($friend_guid) {
+               return $this->leave(get_entity($friend_guid));
        }
-       
-       
+
        /**
-        * THIS FUNCTION IS DEPRECATED.
-        * 
-        * Delete a group's extra data.
-        *
-        * @param int $guid The guid of the group
-        * @return bool
+        * For compatibility with Friendable
         */
-       function delete_group_entity($guid)
-       {
-               system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
-               
-               return 1; // Always return that we have deleted one row in order to not break existing code.
+       public function isFriend() {
+               return $this->isMember();
        }
-       
+
        /**
-        * Add an object to the given group.
-        *
-        * @param int $group_guid The group to add the object to.
-        * @param int $object_guid The guid of the elgg object (must be ElggObject or a child thereof)
-        * @return bool
+        * For compatibility with Friendable
         */
-       function add_object_to_group($group_guid, $object_guid)
-       {
-               $group_guid = (int)$group_guid;
-               $object_guid = (int)$object_guid;
-               
-               $group = get_entity($group_guid);
-               $object = get_entity($object_guid);
-               
-               if ((!$group) || (!$object)) return false;
-               
-               if (!($group instanceof ElggGroup))
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup'));
-
-               if (!($object instanceof ElggObject))
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject'));
-
-               $object->container_guid = $group_guid;
-               return $object->save();
-       }
-       
+       public function isFriendsWith($user_guid) {
+               return $this->isMember($user_guid);
+       }
+
        /**
-        * Remove an object from the given group.
-        *
-        * @param int $group_guid The group to remove the object from
-        * @param int $object_guid The object to remove
+        * For compatibility with Friendable
         */
-       function remove_object_from_group($group_guid, $object_guid)
-       {
-               $group_guid = (int)$group_guid;
-               $object_guid = (int)$object_guid;
-               
-               $group = get_entity($group_guid);
-               $object = get_entity($object_guid);
-               
-               if ((!$group) || (!$object)) return false;
-               
-               if (!($group instanceof ElggGroup))
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup'));
-
-               if (!($object instanceof ElggObject))
-                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject'));
-
-               $object->container_guid = $object->owner_guid;
-               return $object->save();
-       }
-       
+       public function isFriendOf($user_guid) {
+               return $this->isMember($user_guid);
+       }
+
        /**
-        * Return an array of objects in a given container.
-        * @see get_entities()
-        *
-        * @param int $group_guid The container (defaults to current page owner)
-        * @param string $subtype The subtype
-        * @param int $owner_guid Owner
-        * @param int $site_guid The site
-        * @param string $order_by Order
-        * @param unknown_type $limit Limit on number of elements to return, by default 10.
-        * @param unknown_type $offset Where to start, by default 0.
-        * @param unknown_type $count Whether to return the entities or a count of them.
+        * For compatibility with Friendable
         */
-       function get_objects_in_group($group_guid, $subtype = "", $owner_guid = 0, $site_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false)
-       {
-               global $CONFIG;
-               
-               if ($subtype === false || $subtype === null || $subtype === 0)
-                       return false;
-                       
-               $subtype = get_subtype_id('object', $subtype);
-               
-               if ($order_by == "") $order_by = "e.time_created desc";
-               $order_by = sanitise_string($order_by);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-               
-               $container_guid = (int)$group_guid;
-               if ($container_guid == 0)
-                       $container_guid = page_owner();
-                               
-               $where = array();
-               
-               $where[] = "e.type='object'";
-               if ($subtype!=="")
-                       $where[] = "e.subtype=$subtype";
-               if ($owner_guid != "") {
-                       if (!is_array($owner_guid)) {
-                               $owner_guid = (int) $owner_guid;
-                               $where[] = "e.container_guid = '$owner_guid'";
-                       } else if (sizeof($owner_guid) > 0) {
-                               // Cast every element to the owner_guid array to int
-                               $owner_guid = array_map("sanitise_int", $owner_guid);
-                               $owner_guid = implode(",",$owner_guid);
-                               $where[] = "e.container_guid in ({$owner_guid})";
-                       }
-               }
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-
-               if ($container_guid > 0)
-                       $where[] = "e.container_guid = {$container_guid}";
-                       
-               if (!$count) {
-                       $query = "SELECT * from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where ";
-               } else {
-                       $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where ";
-               }
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix('e'); // Add access controls
-               if (!$count) {
-                       $query .= " order by $order_by";
-                       if ($limit) $query .= " limit $offset, $limit"; // Add order and limit
-
-                       $dt = get_data($query, "entity_row_to_elggstar");
-                       return $dt;
-               } else {
-                       $total = get_data_row($query);
-                       return $total->total;
-               }
+       public function getFriends($subtype = "", $limit = 10, $offset = 0) {
+               return get_group_members($this->getGUID(), $limit, $offset);
        }
-       
+
        /**
-        * Get all the entities from metadata from a group.
-        *
-        * @param int $group_guid The ID of the group.
-        * @param mixed $meta_name 
-        * @param mixed $meta_value
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
-        * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+        * For compatibility with Friendable
         */
-       function get_entities_from_metadata_groups($group_guid, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false)
-       {
-               global $CONFIG;
-               
-               $meta_n = get_metastring_id($meta_name);
-               $meta_v = get_metastring_id($meta_value);
-                       
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if ($order_by == "") $order_by = "e.time_created desc";
-               $order_by = sanitise_string($order_by);
-               $site_guid = (int) $site_guid;
-               if (is_array($owner_guid)) {
-                       foreach($owner_guid as $key => $guid) {
-                               $owner_guid[$key] = (int) $guid;
-                       }
-               } else {
-                       $owner_guid = (int) $owner_guid;
-               }
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               $container_guid = (int)$group_guid;
-               if ($container_guid == 0)
-                       $container_guid = page_owner();
-                       
-               //$access = get_access_list();
-                       
-               $where = array();
-               
-               if ($entity_type!="")
-                       $where[] = "e.type='$entity_type'";
-               if ($entity_subtype)
-                       $where[] = "e.subtype=$entity_subtype";
-               if ($meta_name!="")
-                       $where[] = "m.name_id='$meta_n'";
-               if ($meta_value!="")
-                       $where[] = "m.value_id='$meta_v'";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               if ($container_guid > 0)
-                       $where[] = "e.container_guid = {$container_guid}";
-               if (is_array($owner_guid)) {
-                       $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
-               } else if ($owner_guid > 0)
-                       $where[] = "e.container_guid = {$owner_guid}";
-               
-               if (!$count) {
-                       $query = "SELECT distinct e.* "; 
-               } else {
-                       $query = "SELECT count(e.guid) as total ";
-               }
-                       
-               $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid where";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($row = get_data_row($query))
-                               return $row->total;
-               }
-               return false;
+       public function getFriendsOf($subtype = "", $limit = 10, $offset = 0) {
+               return get_group_members($this->getGUID(), $limit, $offset);
        }
-       
+
        /**
-        * As get_entities_from_metadata_groups() but with multiple entities.
+        * Get objects contained in this group.
         *
-        * @param int $group_guid The ID of the group.
-        * @param array $meta_array Array of 'name' => 'value' pairs
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
+        * @param string $subtype
+        * @param int $limit
         * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
-        * @return int|array List of ElggEntities, or the total number if count is set to false
+        * @return mixed
         */
-       function get_entities_from_metadata_groups_multi($group_guid, $meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false)
-       {
-               global $CONFIG;
-               
-               if (!is_array($meta_array) || sizeof($meta_array) == 0) {
-                       return false;
-               }
-               
-               $where = array();
-               
-               $mindex = 1;
-               $join = "";
-               foreach($meta_array as $meta_name => $meta_value) {
-                       $meta_n = get_metastring_id($meta_name);
-                       $meta_v = get_metastring_id($meta_value);
-                       $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid "; 
-                       if ($meta_name!="")
-                               $where[] = "m{$mindex}.name_id='$meta_n'";
-                       if ($meta_value!="")
-                               $where[] = "m{$mindex}.value_id='$meta_v'";
-                       $mindex++;
-               }
-                       
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if ($order_by == "") $order_by = "e.time_created desc";
-               $order_by = sanitise_string($order_by);
-               $owner_guid = (int) $owner_guid;
-               
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               //$access = get_access_list();
-               
-               if ($entity_type!="")
-                       $where[] = "e.type = '{$entity_type}'";
-               if ($entity_subtype)
-                       $where[] = "e.subtype = {$entity_subtype}";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               if ($owner_guid > 0)
-                       $where[] = "e.owner_guid = {$owner_guid}";
-               if ($container_guid > 0)
-                       $where[] = "e.container_guid = {$container_guid}";
-               
-               if ($count) {
-                       $query = "SELECT count(e.guid) as total ";
-               } else {
-                       $query = "SELECT distinct e.* "; 
-               }
-                       
-               $query .= " from {$CONFIG->dbprefix}entities e {$join} where";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
-                       }
-               }
-               return false;
+       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
+ */
+
        /**
-        * Return a list of this group's members.
-        * 
-        * @param int $group_guid The ID of the container/group.
-        * @param int $limit The limit
-        * @param int $offset The offset
-        * @param int $site_guid The site
-        * @param bool $count Return the users (false) or the count of them (true)
+        * Get a list of group members.
+        *
+        * @param int $limit
+        * @param int $offset
         * @return mixed
         */
-       function get_group_members($group_guid, $limit = 10, $offset = 0, $site_guid = 0, $count = false)
-       {
-               return get_entities_from_relationship('member', $group_guid, true, 'user', '', 0, "", $limit, $offset, $count, $site_guid);
+       public function getMembers($limit = 10, $offset = 0, $count = false) {
+               return get_group_members($this->getGUID(), $limit, $offset, 0 , $count);
        }
-       
+
        /**
-        * Return whether a given user is a member of the group or not.
-        * 
-        * @param int $group_guid The group ID
-        * @param int $user_guid The user guid
+        * Returns whether the current group is public membership or not.
         * @return bool
         */
-       function is_group_member($group_guid, $user_guid)
-       {
-               return check_entity_relationship($user_guid, 'member', $group_guid);
+       public function isPublicMembership() {
+               if ($this->membership == ACCESS_PUBLIC) {
+                       return true;
+               }
+
+               return false;
        }
-       
+
        /**
-        * Join a user to a group.
-        * 
-        * @param int $group_guid The group.
-        * @param int $user_guid The user.
+        * Return whether a given user is a member of this group or not.
+        *
+        * @param ElggUser $user The user
+        * @return bool
         */
-       function join_group($group_guid, $user_guid)
-       {
-               $result = add_entity_relationship($user_guid, 'member', $group_guid);
-               trigger_elgg_event('join','group',array('group' => get_entity($group_guid), 'user' => get_entity($user_guid)));
-               return $result;
+       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());
        }
-       
+
        /**
-        * Remove a user from a group.
-        * 
-        * @param int $group_guid The group.
-        * @param int $user_guid The user.
+        * Join an elgg user to this group.
+        *
+        * @param ElggUser $user
+        * @return bool
         */
-       function leave_group($group_guid, $user_guid)
-       {
-               $result = remove_entity_relationship($user_guid, 'member', $group_guid);
-               trigger_elgg_event('leave','group',array('group' => get_entity($group_guid), 'user' => get_entity($user_guid)));
-               return $result;
+       public function join(ElggUser $user) {
+               return join_group($this->getGUID(), $user->getGUID());
        }
-       
+
        /**
-        * Return all groups a user is a member of.
+        * Remove a user from the group.
         *
-        * @param unknown_type $user_guid
+        * @param ElggUser $user
         */
-       function get_users_membership($user_guid)
-       {
-               return get_entities_from_relationship('member', $user_guid, false);
+       public function leave(ElggUser $user) {
+               return leave_group($this->getGUID(), $user->getGUID());
        }
-       
+
        /**
-        * Checks access to a group.
+        * 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 boolean $forward If set to true (default), will forward the page; if set to false, will return true or false.
-        * @return true|false If $forward is set to false.
+        * @param int $guid
         */
-       function group_gatekeeper($forward = true) {
-
-               $allowed = true;
-               $url = '';
-               
-               if ($group = page_owner_entity()) {
-                       if ($group instanceof ElggGroup) {
-                               $url = $group->getURL();
-                               if (
-                                       ((!isloggedin()) && (!$group->isPublicMembership())) ||
-                                       ((!$group->isMember(get_loggedin_user()) && (!$group->isPublicMembership())))
-                               ) $allowed = false;
-                               
-                               // Admin override
-                               if (isadminloggedin()) $allowed = true;
-                       }
+       protected function load($guid) {
+               // Test to see if we have the generic stuff
+               if (!parent::load($guid)) {
+                       return false;
                }
-               
-               if ($forward && $allowed == false) {
-                       forward($url);
-                       exit;
+
+               // 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 $allowed;
-               
+
+               return true;
        }
-       
+
        /**
-        * Manages group tool options
-        *
-        * @param string $name Name of the group tool option
-        * @param string $label Used for the group edit form
-        * @param boolean $default_on True if this option should be active by default
-        * 
-        **/
-       
-       function add_group_tool_option($name,$label,$default_on=true) {
-               global $CONFIG;
-               
-               if (!isset($CONFIG->group_tool_options)) {
-                       $CONFIG->group_tool_options = array();
+        * Override the save function.
+        */
+       public function save() {
+               // Save generic stuff
+               if (!parent::save()) {
+                       return false;
                }
-               
-               $group_tool_option = new stdClass;
-               
-               $group_tool_option->name = $name;
-               $group_tool_option->label = $label;
-               $group_tool_option->default_on = $default_on;
-               
-               $CONFIG->group_tool_options[] = $group_tool_option;
-       }
-       
+
+               // Now save specific stuff
+               return create_group_entity($this->get('guid'), $this->get('name'), $this->get('description'));
+       }
+
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
+
        /**
-        * Searches for a group based on a complete or partial name or description
-        *
-        * @param string $criteria The partial or full name or description
-        * @param int $limit Limit of the search.
-        * @param int $offset Offset.
-        * @param string $order_by The order.
-        * @param boolean $count Whether to return the count of results or just the results. 
+        * Return an array of fields which can be exported.
         */
-       function search_for_group($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false)
+       public function getExportableValues() {
+               return array_merge(parent::getExportableValues(), array(
+                       'name',
+                       'description',
+               ));
+       }
+}
+
+/**
+ * Get the group entity.
+ *
+ * @param int $guid
+ */
+function get_group_entity_as_row($guid) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+
+       /*$row = retrieve_cached_entity_row($guid);
+       if ($row)
        {
-               global $CONFIG;
-               
-               $criteria = sanitise_string($criteria);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $order_by = sanitise_string($order_by);
-               
-               $access = get_access_sql_suffix("e");
-               
-               if ($order_by == "") $order_by = "e.time_created desc";
-               
-               if ($count) {
-                       $query = "SELECT count(e.guid) as total ";
-               } else {
-                       $query = "SELECT e.* "; 
-               }
-               $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}groups_entity g on e.guid=g.guid where ";
-               // $query .= " match(u.name,u.username) against ('$criteria') ";
-               $query .= "(g.name like \"%{$criteria}%\" or g.description like \"%{$criteria}%\")";
-               $query .= " and $access";
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
+               // We have already cached this object, so retrieve its value from the cache
+               if (isset($CONFIG->debug) && $CONFIG->debug)
+                       error_log("** Retrieving sub part of GUID:$guid from cache");
+
+               return $row;
+       }
+       else
+       {*/
+       // Object not cached, load it.
+       if (isset($CONFIG->debug) && $CONFIG->debug == true) {
+               error_log("** Sub part of GUID:$guid loaded from DB");
+       }
+
+       return get_data_row("SELECT * from {$CONFIG->dbprefix}groups_entity where guid=$guid");
+       //}
+}
+
+/**
+ * Create or update the extras table for a given group.
+ * Call create_entity first.
+ *
+ * @param int $guid
+ * @param string $name
+ * @param string $description
+ */
+function create_group_entity($guid, $name, $description) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+       $name = sanitise_string($name);
+       $description = sanitise_string($description);
+
+       $row = get_entity_as_row($guid);
+
+       if ($row) {
+               // Exists and you have access to it
+               if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}groups_entity WHERE guid = {$guid}")) {
+                       $result = update_data("UPDATE {$CONFIG->dbprefix}groups_entity set name='$name', description='$description' where guid=$guid");
+                       if ($result!=false) {
+                               // Update succeeded, continue
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('update',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete();
+                                       //delete_entity($guid);
+                               }
+                       }
                } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
+                       // Update failed, attempt an insert.
+                       $result = insert_data("INSERT into {$CONFIG->dbprefix}groups_entity (guid, name, description) values ($guid, '$name','$description')");
+                       if ($result!==false) {
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('create',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete();
+                                       //delete_entity($guid);
+                               }
                        }
                }
+       }
+
+       return false;
+}
+
+
+/**
+ * THIS FUNCTION IS DEPRECATED.
+ *
+ * Delete a group's extra data.
+ *
+ * @param int $guid The guid of the group
+ * @return bool
+ */
+function delete_group_entity($guid) {
+       system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
+
+       // Always return that we have deleted one row in order to not break existing code.
+       return 1;
+}
+
+/**
+ * Add an object to the given group.
+ *
+ * @param int $group_guid The group to add the object to.
+ * @param int $object_guid The guid of the elgg object (must be ElggObject or a child thereof)
+ * @return bool
+ */
+function add_object_to_group($group_guid, $object_guid) {
+       $group_guid = (int)$group_guid;
+       $object_guid = (int)$object_guid;
+
+       $group = get_entity($group_guid);
+       $object = get_entity($object_guid);
+
+       if ((!$group) || (!$object)) {
                return false;
        }
-       
-       /**
-        * Returns a formatted list of groups suitable for injecting into search.
-        *
-        */
-       function search_list_groups_by_name($hook, $user, $returnvalue, $tag) {
 
-               // Change this to set the number of groups that display on the search page
-               $threshold = 4;
+       if (!($group instanceof ElggGroup)) {
+               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup'));
+       }
+
+       if (!($object instanceof ElggObject)) {
+               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject'));
+       }
+
+       $object->container_guid = $group_guid;
+       return $object->save();
+}
+
+/**
+ * Remove an object from the given group.
+ *
+ * @param int $group_guid The group to remove the object from
+ * @param int $object_guid The object to remove
+ */
+function remove_object_from_group($group_guid, $object_guid) {
+       $group_guid = (int)$group_guid;
+       $object_guid = (int)$object_guid;
+
+       $group = get_entity($group_guid);
+       $object = get_entity($object_guid);
+
+       if ((!$group) || (!$object)) {
+               return false;
+       }
+
+       if (!($group instanceof ElggGroup)) {
+               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup'));
+       }
+
+       if (!($object instanceof ElggObject)) {
+               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject'));
+       }
+
+       $object->container_guid = $object->owner_guid;
+       return $object->save();
+}
+
+/**
+ * Return an array of objects in a given container.
+ * @see get_entities()
+ *
+ * @param int $group_guid The container (defaults to current page owner)
+ * @param string $subtype The subtype
+ * @param int $owner_guid Owner
+ * @param int $site_guid The site
+ * @param string $order_by Order
+ * @param unknown_type $limit Limit on number of elements to return, by default 10.
+ * @param unknown_type $offset Where to start, by default 0.
+ * @param unknown_type $count Whether to return the entities or a count of them.
+ */
+function get_objects_in_group($group_guid, $subtype = "", $owner_guid = 0, $site_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false) {
+       global $CONFIG;
+
+       if ($subtype === false || $subtype === null || $subtype === 0) {
+               return false;
+       }
+
+       $subtype = get_subtype_id('object', $subtype);
+
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+       $order_by = sanitise_string($order_by);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $container_guid = (int)$group_guid;
+       if ($container_guid == 0) {
+               $container_guid = page_owner();
+       }
+
+       $where = array();
+
+       $where[] = "e.type='object'";
+       if ($subtype!=="") {
+               $where[] = "e.subtype=$subtype";
+       }
+       if ($owner_guid != "") {
+               if (!is_array($owner_guid)) {
+                       $owner_guid = (int) $owner_guid;
+                       $where[] = "e.container_guid = '$owner_guid'";
+               } else if (sizeof($owner_guid) > 0) {
+                       // Cast every element to the owner_guid array to int
+                       $owner_guid = array_map("sanitise_int", $owner_guid);
+                       $owner_guid = implode(",",$owner_guid);
+                       $where[] = "e.container_guid in ({$owner_guid})";
+               }
+       }
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       if ($container_guid > 0) {
+               $where[] = "e.container_guid = {$container_guid}";
+       }
+
+       if (!$count) {
+               $query = "SELECT * from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where ";
+       } else {
+               $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where ";
+       }
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+
+       // Add access controls
+       $query .= get_access_sql_suffix('e');
+       if (!$count) {
+               $query .= " order by $order_by";
+
+               // Add order and limit
+               if ($limit) {
+                       $query .= " limit $offset, $limit";
+               }
+
+               $dt = get_data($query, "entity_row_to_elggstar");
+               return $dt;
+       } else {
+               $total = get_data_row($query);
+               return $total->total;
+       }
+}
+
+/**
+ * Get all the entities from metadata from a group.
+ *
+ * @param int $group_guid The ID of the group.
+ * @param mixed $meta_name
+ * @param mixed $meta_value
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+ */
+function get_entities_from_metadata_groups($group_guid, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) {
+       global $CONFIG;
+
+       $meta_n = get_metastring_id($meta_name);
+       $meta_v = get_metastring_id($meta_value);
+
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+       $order_by = sanitise_string($order_by);
+       $site_guid = (int) $site_guid;
+       if (is_array($owner_guid)) {
+               foreach($owner_guid as $key => $guid) {
+                       $owner_guid[$key] = (int) $guid;
+               }
+       } else {
+               $owner_guid = (int) $owner_guid;
+       }
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $container_guid = (int)$group_guid;
+       if ($container_guid == 0) {
+               $container_guid = page_owner();
+       }
+
+       //$access = get_access_list();
+
+       $where = array();
+
+       if ($entity_type!="") {
+               $where[] = "e.type='$entity_type'";
+       }
+       if ($entity_subtype) {
+               $where[] = "e.subtype=$entity_subtype";
+       }
+       if ($meta_name!="") {
+               $where[] = "m.name_id='$meta_n'";
+       }
+       if ($meta_value!="") {
+               $where[] = "m.value_id='$meta_v'";
+       }
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+       if ($container_guid > 0) {
+               $where[] = "e.container_guid = {$container_guid}";
+       }
+
+       if (is_array($owner_guid)) {
+               $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
+       } else if ($owner_guid > 0)
+               $where[] = "e.container_guid = {$owner_guid}";
+
+       if (!$count) {
+               $query = "SELECT distinct e.* ";
+       } else {
+               $query = "SELECT count(e.guid) as total ";
+       }
+
+       $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid where";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+
+       // Add access controls
+       $query .= get_access_sql_suffix("e");
+
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($row = get_data_row($query)) {
+                       return $row->total;
+               }
+       }
+       return false;
+}
+
+/**
+ * As get_entities_from_metadata_groups() but with multiple entities.
+ *
+ * @param int $group_guid The ID of the group.
+ * @param array $meta_array Array of 'name' => 'value' pairs
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+ * @return int|array List of ElggEntities, or the total number if count is set to false
+ */
+function get_entities_from_metadata_groups_multi($group_guid, $meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) {
+       global $CONFIG;
+
+       if (!is_array($meta_array) || sizeof($meta_array) == 0) {
+               return false;
+       }
+
+       $where = array();
+
+       $mindex = 1;
+       $join = "";
+       foreach($meta_array as $meta_name => $meta_value) {
+               $meta_n = get_metastring_id($meta_name);
+               $meta_v = get_metastring_id($meta_value);
+               $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid ";
+               if ($meta_name!="") {
+                       $where[] = "m{$mindex}.name_id='$meta_n'";
+               }
+
+               if ($meta_value!="") {
+                       $where[] = "m{$mindex}.value_id='$meta_v'";
+               }
+
+               $mindex++;
+       }
+
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+       $order_by = sanitise_string($order_by);
+       $owner_guid = (int) $owner_guid;
+
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       //$access = get_access_list();
+
+       if ($entity_type!="") {
+               $where[] = "e.type = '{$entity_type}'";
+       }
+
+       if ($entity_subtype) {
+               $where[] = "e.subtype = {$entity_subtype}";
+       }
+
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       if ($owner_guid > 0) {
+               $where[] = "e.owner_guid = {$owner_guid}";
+       }
+
+       if ($container_guid > 0) {
+               $where[] = "e.container_guid = {$container_guid}";
+       }
+
+       if ($count) {
+               $query = "SELECT count(e.guid) as total ";
+       } else {
+               $query = "SELECT distinct e.* ";
+       }
+
+       $query .= " from {$CONFIG->dbprefix}entities e {$join} where";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+       $query .= get_access_sql_suffix("e"); // Add access controls
+
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+       return false;
+}
+
+/**
+ * Return a list of this group's members.
+ *
+ * @param int $group_guid The ID of the container/group.
+ * @param int $limit The limit
+ * @param int $offset The offset
+ * @param int $site_guid The site
+ * @param bool $count Return the users (false) or the count of them (true)
+ * @return mixed
+ */
+function get_group_members($group_guid, $limit = 10, $offset = 0, $site_guid = 0, $count = false) {
+       return get_entities_from_relationship('member', $group_guid, true, 'user', '', 0, "", $limit, $offset, $count, $site_guid);
+}
+
+/**
+ * Return whether a given user is a member of the group or not.
+ *
+ * @param int $group_guid The group ID
+ * @param int $user_guid The user guid
+ * @return bool
+ */
+function is_group_member($group_guid, $user_guid) {
+       return check_entity_relationship($user_guid, 'member', $group_guid);
+}
+
+/**
+ * Join a user to a group.
+ *
+ * @param int $group_guid The group.
+ * @param int $user_guid The user.
+ */
+function join_group($group_guid, $user_guid) {
+       $result = add_entity_relationship($user_guid, 'member', $group_guid);
+       trigger_elgg_event('join', 'group', array('group' => get_entity($group_guid), 'user' => get_entity($user_guid)));
+       return $result;
+}
+
+/**
+ * Remove a user from a group.
+ *
+ * @param int $group_guid The group.
+ * @param int $user_guid The user.
+ */
+function leave_group($group_guid, $user_guid) {
+       $result = remove_entity_relationship($user_guid, 'member', $group_guid);
+       trigger_elgg_event('leave', 'group', array('group' => get_entity($group_guid), 'user' => get_entity($user_guid)));
+       return $result;
+}
+
+/**
+ * Return all groups a user is a member of.
+ *
+ * @param unknown_type $user_guid
+ */
+function get_users_membership($user_guid) {
+       return get_entities_from_relationship('member', $user_guid, false);
+}
 
-               $object = get_input('object');
-               
-               if (!get_input('offset') && (empty($object) || $object == 'group'))
+/**
+ * Checks access to a group.
+ *
+ * @param boolean $forward If set to true (default), will forward the page; if set to false, will return true or false.
+ * @return true|false If $forward is set to false.
+ */
+function group_gatekeeper($forward = true) {
+       $allowed = true;
+       $url = '';
+
+       if ($group = page_owner_entity()) {
+               if ($group instanceof ElggGroup) {
+                       $url = $group->getURL();
+                       if (
+                               ((!isloggedin()) && (!$group->isPublicMembership())) ||
+                               ((!$group->isMember(get_loggedin_user()) && (!$group->isPublicMembership())))
+                       ) {
+                               $allowed = false;
+                       }
+
+                       // Admin override
+                       if (isadminloggedin()) {
+                               $allowed = true;
+                       }
+               }
+       }
+
+       if ($forward && $allowed == false) {
+               forward($url);
+               exit;
+       }
+
+       return $allowed;
+}
+
+/**
+ * Manages group tool options
+ *
+ * @param string $name Name of the group tool option
+ * @param string $label Used for the group edit form
+ * @param boolean $default_on True if this option should be active by default
+ *
+ **/
+
+function add_group_tool_option($name,$label,$default_on=true) {
+       global $CONFIG;
+
+       if (!isset($CONFIG->group_tool_options)) {
+               $CONFIG->group_tool_options = array();
+       }
+
+       $group_tool_option = new stdClass;
+
+       $group_tool_option->name = $name;
+       $group_tool_option->label = $label;
+       $group_tool_option->default_on = $default_on;
+
+       $CONFIG->group_tool_options[] = $group_tool_option;
+}
+
+/**
+ * Searches for a group based on a complete or partial name or description
+ *
+ * @param string $criteria The partial or full name or description
+ * @param int $limit Limit of the search.
+ * @param int $offset Offset.
+ * @param string $order_by The order.
+ * @param boolean $count Whether to return the count of results or just the results.
+ */
+function search_for_group($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) {
+       global $CONFIG;
+
+       $criteria = sanitise_string($criteria);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $order_by = sanitise_string($order_by);
+
+       $access = get_access_sql_suffix("e");
+
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+
+       if ($count) {
+               $query = "SELECT count(e.guid) as total ";
+       } else {
+               $query = "SELECT e.* ";
+       }
+       $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}groups_entity g on e.guid=g.guid where ";
+       // $query .= " match(u.name,u.username) against ('$criteria') ";
+       $query .= "(g.name like \"%{$criteria}%\" or g.description like \"%{$criteria}%\")";
+       $query .= " and $access";
+
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+       return false;
+}
+
+/**
+ * Returns a formatted list of groups suitable for injecting into search.
+ *
+ */
+function search_list_groups_by_name($hook, $user, $returnvalue, $tag) {
+       // Change this to set the number of groups that display on the search page
+       $threshold = 4;
+
+       $object = get_input('object');
+
+       if (!get_input('offset') && (empty($object) || $object == 'group')) {
                if ($groups = search_for_group($tag,$threshold)) {
-                       
                        $countgroups = search_for_group($tag,0,0,"",true);
-                       
+
                        $return = elgg_view('group/search/startblurb',array('count' => $countgroups, 'tag' => $tag));
                        foreach($groups as $group) {
                                $return .= elgg_view_entity($group);
                        }
                        $return .= elgg_view('group/search/finishblurb',array('count' => $countgroups, 'threshold' => $threshold, 'tag' => $tag));
                        return $return;
-                       
                }
-               
        }
-       
-       /**
-        * Displays a list of group objects that have been searched for.
-        *
-        * @see elgg_view_entity_list
-        * 
-        * @param string $tag Search criteria
-        * @param int $limit The number of entities to display on a page
-        * @return string The list in a form suitable to display
-        */
-       function list_group_search($tag, $limit = 10) {
-               
-               $offset = (int) get_input('offset');
-               $limit = (int) $limit;
-               $count = (int) search_for_group($tag, 10, 0, '', true);
-               $entities = search_for_group($tag, $limit, $offset);
-               
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false);
-               
-       }
-       
-       /**
-        * Performs initialisation functions for groups
-        *
-        */
-       function group_init() {
-               // Register an entity type
-               register_entity_type('group','');
-               
-               // Register a search hook
-               register_plugin_hook('search','all','search_list_groups_by_name');
-       }
-       
-       register_elgg_event_handler('init','system','group_init');
-       
-?>
+}
+
+/**
+ * Displays a list of group objects that have been searched for.
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param string $tag Search criteria
+ * @param int $limit The number of entities to display on a page
+ * @return string The list in a form suitable to display
+ */
+function list_group_search($tag, $limit = 10) {
+       $offset = (int) get_input('offset');
+       $limit = (int) $limit;
+       $count = (int) search_for_group($tag, 10, 0, '', true);
+       $entities = search_for_group($tag, $limit, $offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false);
+
+}
+
+/**
+ * Performs initialisation functions for groups
+ *
+ */
+function group_init() {
+       // Register an entity type
+       register_entity_type('group','');
+
+       // Register a search hook
+       register_plugin_hook('search','all','search_list_groups_by_name');
+}
+
+register_elgg_event_handler('init','system','group_init');
index 49eb63f13c0c5cb479e3c647dca3666a1db287b5..289542547d34eba62e4c038129aee5e2ab2f239d 100644 (file)
 <?php
-       /**
-        * Parameter input functions.
-        * This file contains functions for getting input from get/post variables.
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd <info@elgg.com>
-
-        * @link http://elgg.org/
-        */
-
-       /**
-        * Get some input from variables passed on the GET or POST line.
-        * 
-        * @param $variable string The variable we want to return.
-        * @param $default mixed A default value for the variable if it is not found.
-        * @param $filter_result If true then the result is filtered for bad tags.
-        */
-       function get_input($variable, $default = "", $filter_result = true)
-       {
-
-               global $CONFIG;
-               
-               if (isset($CONFIG->input[$variable])) {
-                       $var = $CONFIG->input[$variable];
-                       
-                       if ($filter_result)
-                               $var = filter_tags($var);
-                               
-                       return $var;
+/**
+ * Parameter input functions.
+ * This file contains functions for getting input from get/post variables.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @link http://elgg.org/
+ */
+
+/**
+ * Get some input from variables passed on the GET or POST line.
+ *
+ * @param $variable string The variable we want to return.
+ * @param $default mixed A default value for the variable if it is not found.
+ * @param $filter_result If true then the result is filtered for bad tags.
+ */
+function get_input($variable, $default = "", $filter_result = true) {
+
+       global $CONFIG;
+
+       if (isset($CONFIG->input[$variable])) {
+               $var = $CONFIG->input[$variable];
+
+               if ($filter_result) {
+                       $var = filter_tags($var);
                }
-               
-               if (isset($_REQUEST[$variable])) {
-                       
-                       if (is_array($_REQUEST[$variable])) {
-                               $var = $_REQUEST[$variable];
-                       } else {
-                               $var = trim($_REQUEST[$variable]);
-                       }
-                       
-                       if ($filter_result)
-                               $var = filter_tags($var);
 
-                       return $var;
-                       
+               return $var;
+       }
+
+       if (isset($_REQUEST[$variable])) {
+               if (is_array($_REQUEST[$variable])) {
+                       $var = $_REQUEST[$variable];
+               } else {
+                       $var = trim($_REQUEST[$variable]);
                }
 
-               return $default;
+               if ($filter_result) {
+                       $var = filter_tags($var);
+               }
 
+               return $var;
        }
-       
-       /**
-        * Sets an input value that may later be retrieved by get_input
-        *
-        * @param string $variable The name of the variable
-        * @param string $value The value of the variable
-        */
-       function set_input($variable, $value) {
-               
-               global $CONFIG;
-               if (!isset($CONFIG->input))
-                       $CONFIG->input = array();
-                                       
-               if (is_array($value))
-               {
-                       foreach ($value as $key => $val)
-                               $value[$key] = trim($val);
-                       
-                       $CONFIG->input[trim($variable)] = $value;
+
+       return $default;
+}
+
+/**
+ * Sets an input value that may later be retrieved by get_input
+ *
+ * @param string $variable The name of the variable
+ * @param string $value The value of the variable
+ */
+function set_input($variable, $value) {
+       global $CONFIG;
+       if (!isset($CONFIG->input)) {
+               $CONFIG->input = array();
+       }
+
+       if (is_array($value)) {
+               foreach ($value as $key => $val) {
+                       $value[$key] = trim($val);
                }
-               else
-                       $CONFIG->input[trim($variable)] = trim($value);
-                       
+
+               $CONFIG->input[trim($variable)] = $value;
+       } else {
+               $CONFIG->input[trim($variable)] = trim($value);
        }
-       
-       /**
-        * Filter tags from a given string based on registered hooks.
-        * @param $var
-        * @return mixed The filtered result
-        */
-       function filter_tags($var)
-       {
-               return trigger_plugin_hook('validate', 'input', null, $var);
+}
+
+/**
+ * Filter tags from a given string based on registered hooks.
+ * @param $var
+ * @return mixed The filtered result
+ */
+function filter_tags($var) {
+       return trigger_plugin_hook('validate', 'input', null, $var);
+}
+
+/**
+ * Sanitise file paths for input, ensuring that they begin and end with slashes etc.
+ *
+ * @param string $path The path
+ * @return string
+ */
+function sanitise_filepath($path) {
+       // Convert to correct UNIX paths
+       $path = str_replace('\\', '/', $path);
+
+       // Sort trailing slash
+       $path = trim($path);
+       $path = rtrim($path, " /");
+       $path = $path . "/";
+
+       return $path;
+}
+
+
+/**
+ * Takes a string and turns any URLs into formatted links
+ *
+ * @param string $text The input string
+ * @return string The output stirng with formatted links
+ **/
+function parse_urls($text) {
+       return preg_replace_callback('/(?<!=["\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\!\(\)]+)/i',
+       create_function(
+               '$matches',
+               '
+                       $url = $matches[1];
+                       $urltext = str_replace("/", "/<wbr />", $url);
+                       return "<a href=\"$url\" style=\"text-decoration:underline;\">$urltext</a>";
+               '
+       ), $text);
+}
+
+function autop($pee, $br = 1) {
+       $pee = $pee . "\n"; // just to make things a little easier, pad the end
+       $pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
+       // Space things out a little
+       $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
+       $pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
+       $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
+       $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
+       if ( strpos($pee, '<object') !== false ) {
+               $pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
+               $pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
        }
-       
-       /**
-        * Sanitise file paths for input, ensuring that they begin and end with slashes etc.
-        *
-        * @param string $path The path
-        * @return string
-        */
-       function sanitise_filepath($path)
-       {
-               // Convert to correct UNIX paths
-               $path = str_replace('\\', '/', $path);
-               
-               // Sort trailing slash
-               $path = trim($path);
-               $path = rtrim($path, " /");
-               $path = $path . "/";
-               
-               return $path;
+       $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
+       $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
+       $pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
+       $pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);
+       $pee = preg_replace( '|<p>|', "$1<p>", $pee );
+       $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
+       $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
+       $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
+       $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
+       $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
+       $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
+       if ($br) {
+               $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
+               $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
+               $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
        }
-       
-       
-    /**
-     * Takes a string and turns any URLs into formatted links
-     * 
-     * @param string $text The input string
-     * @return string The output stirng with formatted links
-     **/
-    function parse_urls($text) {
-       
-               return preg_replace_callback('/(?<!=["\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\!\(\)]+)/i', 
-               create_function(
-            '$matches',
-            '
-               $url = $matches[1];
-               $urltext = str_replace("/", "/<wbr />", $url);
-               return "<a href=\"$url\" style=\"text-decoration:underline;\">$urltext</a>";
-            '
-        ), $text);
-    }
-       
-       function autop($pee, $br = 1) {
-               $pee = $pee . "\n"; // just to make things a little easier, pad the end
-               $pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
-               // Space things out a little
-               $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
-               $pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
-               $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
-               $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
-               if ( strpos($pee, '<object') !== false ) {
-                       $pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
-                       $pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
-               }
-               $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
-               $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
-               $pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
-               $pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);
-               $pee = preg_replace( '|<p>|', "$1<p>", $pee );
-               $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
-               $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
-               $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
-               $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
-               $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
-               $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
-               if ($br) {
-                       $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
-                       $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
-                       $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
-               }
-               $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
-               $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
-               if (strpos($pee, '<pre') !== false)
-                       $pee = preg_replace_callback('!(<pre.*?>)(.*?)</pre>!is', 'clean_pre', $pee );
-               $pee = preg_replace( "|\n</p>$|", '</p>', $pee );
-       
-               return $pee;
+       $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
+       $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
+       if (strpos($pee, '<pre') !== false) {
+               $pee = preg_replace_callback('!(<pre.*?>)(.*?)</pre>!is', 'clean_pre', $pee );
        }
-       
-       /**
-        * Page handler for autocomplete endpoint.
-        * 
-        * @param $page
-        * @return unknown_type
-        */
-       function input_livesearch_page_handler($page) {
-               global $CONFIG;
-               // only return results to logged in users.
-               if (!$user = get_loggedin_user()) {
-                       exit;
-               }
-               
-               if (!$q = get_input('q')) {
-                       exit;
-               }
+       $pee = preg_replace( "|\n</p>$|", '</p>', $pee );
 
-               $q = mysql_real_escape_string($q);
+       return $pee;
+}
 
-               // replace mysql vars with escaped strings
-               $q = str_replace(array('_', '%'), array('\_', '\%'), $q);
-               
-               $match_on = get_input('match_on', 'all');
-               if ($match_on == 'all' || $match_on[0] == 'all') {
-                       $match_on = array('users', 'groups');
-               }
-               
-               if (!is_array($match_on)) {
-                       $match_on = array($match_on);
-               }
-               
-               if (get_input('match_owner', false)) {
-                       $owner_guid = $user->getGUID();
-                       $owner_where = 'AND e.owner_guid = ' . $user->getGUID();
-               } else {
-                       $owner_guid = null;
-                       $owner_where = '';
-               }
-               
-               $limit = get_input('limit', 10);
-               
-               // grab a list of entities and send them in json.
-               $results = array();
-               foreach ($match_on as $type) {
-                       switch ($type) {
-                               case 'all':
-                                       // only need to pull up title from objects.
-                                       
-                                       if (!$entities = get_entities(null, null, $owner_guid, null, $limit) AND is_array($entities)) {
-                                               $results = array_merge($results, $entities);
-                                       }
-                                       break;
-                                       
-                               case 'users':
-                                       $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as ue, {$CONFIG->dbprefix}entities as e
-                                               WHERE e.guid = ue.guid
-                                                       AND e.enabled = 'yes'
-                                                       AND ue.banned = 'no'
-                                                       AND (ue.name LIKE '$q%' OR ue.username LIKE '$q%')
-                                               LIMIT $limit
-                                       ";
-                                       
-                                       if ($entities = get_data($query)) {
-                                               foreach ($entities as $entity) {
-                                                       $json = json_encode(array(
-                                                               'type' => 'user',
-                                                               'name' => $entity->name,
-                                                               'desc' => $entity->username,
-                                                               'icon' => '<img class="livesearch_icon" src="' . get_entity($entity->guid)->getIcon('tiny') . '" />',
-                                                               'guid' => $entity->guid
-                                                       ));
-                                                       $results[$entity->name . rand(1,100)] = $json;
-                                               }
+/**
+ * Page handler for autocomplete endpoint.
+ *
+ * @param $page
+ * @return unknown_type
+ */
+function input_livesearch_page_handler($page) {
+       global $CONFIG;
+       // only return results to logged in users.
+       if (!$user = get_loggedin_user()) {
+               exit;
+       }
+
+       if (!$q = get_input('q')) {
+               exit;
+       }
+
+       $q = mysql_real_escape_string($q);
+
+       // replace mysql vars with escaped strings
+       $q = str_replace(array('_', '%'), array('\_', '\%'), $q);
+
+       $match_on = get_input('match_on', 'all');
+       if ($match_on == 'all' || $match_on[0] == 'all') {
+               $match_on = array('users', 'groups');
+       }
+
+       if (!is_array($match_on)) {
+               $match_on = array($match_on);
+       }
+
+       if (get_input('match_owner', false)) {
+               $owner_guid = $user->getGUID();
+               $owner_where = 'AND e.owner_guid = ' . $user->getGUID();
+       } else {
+               $owner_guid = null;
+               $owner_where = '';
+       }
+
+       $limit = get_input('limit', 10);
+
+       // grab a list of entities and send them in json.
+       $results = array();
+       foreach ($match_on as $type) {
+               switch ($type) {
+                       case 'all':
+                               // only need to pull up title from objects.
+
+                               if (!$entities = get_entities(null, null, $owner_guid, null, $limit) AND is_array($entities)) {
+                                       $results = array_merge($results, $entities);
+                               }
+                               break;
+
+                       case 'users':
+                               $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as ue, {$CONFIG->dbprefix}entities as e
+                                       WHERE e.guid = ue.guid
+                                               AND e.enabled = 'yes'
+                                               AND ue.banned = 'no'
+                                               AND (ue.name LIKE '$q%' OR ue.username LIKE '$q%')
+                                       LIMIT $limit
+                               ";
+
+                               if ($entities = get_data($query)) {
+                                       foreach ($entities as $entity) {
+                                               $json = json_encode(array(
+                                                       'type' => 'user',
+                                                       'name' => $entity->name,
+                                                       'desc' => $entity->username,
+                                                       'icon' => '<img class="livesearch_icon" src="' . get_entity($entity->guid)->getIcon('tiny') . '" />',
+                                                       'guid' => $entity->guid
+                                               ));
+                                               $results[$entity->name . rand(1,100)] = $json;
                                        }
-                                       break;
-                                       
-                               case 'groups':
-                                       // don't return results if groups aren't enabled.
-                                       if (!is_plugin_enabled('groups')) {
-                                               continue;
+                               }
+                               break;
+
+                       case 'groups':
+                               // don't return results if groups aren't enabled.
+                               if (!is_plugin_enabled('groups')) {
+                                       continue;
+                               }
+                               $query = "SELECT * FROM {$CONFIG->dbprefix}groups_entity as ge, {$CONFIG->dbprefix}entities as e
+                                       WHERE e.guid = ge.guid
+                                               AND e.enabled = 'yes'
+                                               $owner_where
+                                               AND (ge.name LIKE '$q%' OR ge.description LIKE '%$q%')
+                                       LIMIT $limit
+                               ";
+                               if ($entities = get_data($query)) {
+                                       foreach ($entities as $entity) {
+                                               $json = json_encode(array(
+                                                       'type' => 'group',
+                                                       'name' => $entity->name,
+                                                       'desc' => strip_tags($entity->description),
+                                                       'icon' => '<img class="livesearch_icon" src="' . get_entity($entity->guid)->getIcon('tiny') . '" />',
+                                                       'guid' => $entity->guid
+                                               ));
+                                               //$results[$entity->name . rand(1,100)] = "$json|{$entity->guid}";
+                                               $results[$entity->name . rand(1,100)] = $json;
                                        }
-                                       $query = "SELECT * FROM {$CONFIG->dbprefix}groups_entity as ge, {$CONFIG->dbprefix}entities as e
-                                               WHERE e.guid = ge.guid
-                                                       AND e.enabled = 'yes'
-                                                       $owner_where
-                                                       AND (ge.name LIKE '$q%' OR ge.description LIKE '%$q%')
-                                               LIMIT $limit
-                                       ";
-                                       if ($entities = get_data($query)) {
-                                               foreach ($entities as $entity) {
-                                                       $json = json_encode(array(
-                                                               'type' => 'group',
-                                                               'name' => $entity->name,
-                                                               'desc' => strip_tags($entity->description),
-                                                               'icon' => '<img class="livesearch_icon" src="' . get_entity($entity->guid)->getIcon('tiny') . '" />',
-                                                               'guid' => $entity->guid
-                                                       ));
-                                                       //$results[$entity->name . rand(1,100)] = "$json|{$entity->guid}";
-                                                       $results[$entity->name . rand(1,100)] = $json;
-                                               }
+                               }
+                               break;
+
+                       case 'friends':
+                               $access = get_access_sql_suffix();
+                               $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as ue, {$CONFIG->dbprefix}entity_relationships as er, {$CONFIG->dbprefix}entities as e
+                                       WHERE er.relationship = 'friend'
+                                               AND er.guid_one = {$user->getGUID()}
+                                               AND er.guid_two = ue.guid
+                                               AND e.guid = ue.guid
+                                               AND e.enabled = 'yes'
+                                               AND ue.banned = 'no'
+                                               AND (ue.name LIKE '$q%' OR ue.username LIKE '$q%')
+                                       LIMIT $limit
+                               ";
+
+                               if ($entities = get_data($query)) {
+                                       foreach ($entities as $entity) {
+                                               $json = json_encode(array(
+                                                       'type' => 'user',
+                                                       'name' => $entity->name,
+                                                       'desc' => $entity->username,
+                                                       'icon' => '<img class="livesearch_icon" src="' . get_entity($entity->guid)->getIcon('tiny') . '" />',
+                                                       'guid' => $entity->guid
+                                               ));
+                                               $results[$entity->name . rand(1,100)] = $json;
                                        }
-                                       break;
-                                       
-                               case 'friends':
-                                       $access = get_access_sql_suffix();
-                                       $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as ue, {$CONFIG->dbprefix}entity_relationships as er, {$CONFIG->dbprefix}entities as e
-                                               WHERE er.relationship = 'friend'
-                                                       AND er.guid_one = {$user->getGUID()}
-                                                       AND er.guid_two = ue.guid
-                                                       AND e.guid = ue.guid
-                                                       AND e.enabled = 'yes'
-                                                       AND ue.banned = 'no'
-                                                       AND (ue.name LIKE '$q%' OR ue.username LIKE '$q%')
-                                               LIMIT $limit
-                                       ";
-                                       
-                                       if ($entities = get_data($query)) {
-                                               foreach ($entities as $entity) {
-                                                       $json = json_encode(array(
-                                                               'type' => 'user',
-                                                               'name' => $entity->name,
-                                                               'desc' => $entity->username,
-                                                               'icon' => '<img class="livesearch_icon" src="' . get_entity($entity->guid)->getIcon('tiny') . '" />',
-                                                               'guid' => $entity->guid
-                                                       ));
-                                                       $results[$entity->name . rand(1,100)] = $json;
-                                               }
+                               }
+                               break;
+
+                       default:
+                               // arbitrary subtype.
+                               get_entities(null, $type, $owner_guid);
+                               break;
+               }
+       }
+
+       ksort($results);
+       echo implode($results, "\n");
+       exit;
+}
+
+
+function input_init() {
+       // register an endpoint for live search / autocomplete.
+       register_page_handler('livesearch', 'input_livesearch_page_handler');
+
+       if (ini_get_bool('magic_quotes_gpc') ) {
+               //do keys as well, cos array_map ignores them
+               function stripslashes_arraykeys($array) {
+                       if (is_array($array)) {
+                               $array2 = array();
+                               foreach ($array as $key => $data) {
+                                       if ($key != stripslashes($key)) {
+                                               $array2[stripslashes($key)] = $data;
+                                       } else {
+                                               $array2[$key] = $data;
                                        }
-                                       break;
-                                       
-                               default:
-                                       // arbitrary subtype.
-                                       get_entities(null, $type, $owner_guid);
-                                       break;
+                               }
+                               return $array2;
+                       } else {
+                               return $array;
                        }
                }
-               
-               ksort($results);
-               echo implode($results, "\n");
-               exit;
-       }
 
-       
-       function input_init() {
-               
-               // register an endpoint for live search / autocomplete.
-               register_page_handler('livesearch', 'input_livesearch_page_handler');
-               
-               if (ini_get_bool('magic_quotes_gpc') ) {
-                   
-                   //do keys as well, cos array_map ignores them
-                   function stripslashes_arraykeys($array) {
-                       if (is_array($array)) {
-                           $array2 = array();
-                           foreach ($array as $key => $data) {
-                               if ($key != stripslashes($key)) {
-                                   $array2[stripslashes($key)] = $data;
-                               } else {
-                                   $array2[$key] = $data;
-                               }
-                           }
-                           return $array2;
-                       } else {
-                           return $array;
-                       }
-                   }
-                   
-                   function stripslashes_deep($value) {
-                       if (is_array($value)) {
-                           $value = stripslashes_arraykeys($value);
-                           $value = array_map('stripslashes_deep', $value);
-                       } else {
-                           $value = stripslashes($value);
-                       }
-                       return $value;
-                   }
-                   
-                   $_POST = stripslashes_arraykeys($_POST);
-                   $_GET = stripslashes_arraykeys($_GET);
-                   $_COOKIE = stripslashes_arraykeys($_COOKIE);
-                   $_REQUEST = stripslashes_arraykeys($_REQUEST);
-                   
-                   $_POST = array_map('stripslashes_deep', $_POST);
-                   $_GET = array_map('stripslashes_deep', $_GET);
-                   $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
-                   $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
-                   if (!empty($_SERVER['REQUEST_URI'])) {
-                       $_SERVER['REQUEST_URI'] = stripslashes($_SERVER['REQUEST_URI']);
-                   }
-                   if (!empty($_SERVER['QUERY_STRING'])) {
-                       $_SERVER['QUERY_STRING'] = stripslashes($_SERVER['QUERY_STRING']);
-                   }
-                   if (!empty($_SERVER['HTTP_REFERER'])) {
-                       $_SERVER['HTTP_REFERER'] = stripslashes($_SERVER['HTTP_REFERER']);
-                   }
-                   if (!empty($_SERVER['PATH_INFO'])) {
-                       $_SERVER['PATH_INFO'] = stripslashes($_SERVER['PATH_INFO']);
-                   }
-                   if (!empty($_SERVER['PHP_SELF'])) {
-                       $_SERVER['PHP_SELF'] = stripslashes($_SERVER['PHP_SELF']);
-                   }
-                   if (!empty($_SERVER['PATH_TRANSLATED'])) {
-                       $_SERVER['PATH_TRANSLATED'] = stripslashes($_SERVER['PATH_TRANSLATED']);
-                   }
-                   
+               function stripslashes_deep($value) {
+                       if (is_array($value)) {
+                               $value = stripslashes_arraykeys($value);
+                               $value = array_map('stripslashes_deep', $value);
+                       } else {
+                               $value = stripslashes($value);
+                       }
+                       return $value;
+               }
+
+               $_POST = stripslashes_arraykeys($_POST);
+               $_GET = stripslashes_arraykeys($_GET);
+               $_COOKIE = stripslashes_arraykeys($_COOKIE);
+               $_REQUEST = stripslashes_arraykeys($_REQUEST);
+
+               $_POST = array_map('stripslashes_deep', $_POST);
+               $_GET = array_map('stripslashes_deep', $_GET);
+               $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
+               $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
+               if (!empty($_SERVER['REQUEST_URI'])) {
+                       $_SERVER['REQUEST_URI'] = stripslashes($_SERVER['REQUEST_URI']);
+               }
+               if (!empty($_SERVER['QUERY_STRING'])) {
+                       $_SERVER['QUERY_STRING'] = stripslashes($_SERVER['QUERY_STRING']);
+               }
+               if (!empty($_SERVER['HTTP_REFERER'])) {
+                       $_SERVER['HTTP_REFERER'] = stripslashes($_SERVER['HTTP_REFERER']);
+               }
+               if (!empty($_SERVER['PATH_INFO'])) {
+                       $_SERVER['PATH_INFO'] = stripslashes($_SERVER['PATH_INFO']);
+               }
+               if (!empty($_SERVER['PHP_SELF'])) {
+                       $_SERVER['PHP_SELF'] = stripslashes($_SERVER['PHP_SELF']);
+               }
+               if (!empty($_SERVER['PATH_TRANSLATED'])) {
+                       $_SERVER['PATH_TRANSLATED'] = stripslashes($_SERVER['PATH_TRANSLATED']);
                }
-               
        }
-       
-       register_elgg_event_handler('init','system','input_init');
-        
-       
-?>
+}
+
+register_elgg_event_handler('init','system','input_init');
\ No newline at end of file
index 03abede141c20b2414d61b0909f965e4c1a83d1b..1b363b9501ec7e5008f6576c1efe04d7f088e013 100644 (file)
 <?php
 
-       /**
-        * Elgg installation
-        * Various functions to assist with installing and upgrading the system
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd
-
-        * @link http://elgg.org/
-        */
-
-               /**
-                * Check that the installed version of PHP meets the minimum requirements (currently 5.2 or greater).
-                * 
-                * @return bool
-                */
-               function php_check_version()
-               {
-                       /*
-                       if ( // TODO: Remove this when Redhat pulls its finger out
-                               (version_compare(phpversion(), '5.1.6', '>=')) &&
-                               (version_compare(phpversion(), '5.2.0', '<'))
-                       )
-                               register_error(elgg_echo('configurationwarning:phpversion'));
-                       */
-                       
-                       if (version_compare(phpversion(), '5.1.2', '>='))
-                               return true;
-                               
+/**
+ * Elgg installation
+ * Various functions to assist with installing and upgrading the system
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
+
+/**
+ * Check that the installed version of PHP meets the minimum requirements (currently 5.2 or greater).
+ *
+ * @return bool
+ */
+function php_check_version() {
+       if (version_compare(phpversion(), '5.1.2', '>=')) {
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ * Validate the platform Elgg is being installed on.
+ *
+ * @throws ConfigurationException if the validation fails.
+ * @return bool
+ */
+function validate_platform() {
+       // Get database version
+       if (!db_check_version()) {
+               throw new ConfigurationException(elgg_echo('ConfigurationException:BadDatabaseVersion'));
+       }
+
+       // Now check PHP
+       if (!php_check_version()) {
+               throw new ConfigurationException(elgg_echo('ConfigurationException:BadPHPVersion'));
+       }
+
+       // TODO: Consider checking for installed modules etc
+       return true;
+}
+
+/**
+ * Returns whether or not the database has been installed
+ *
+ * @return true|false Whether the database has been installed
+ */
+function is_db_installed() {
+       global $CONFIG;
+
+       if (isset($CONFIG->db_installed)) {
+               return $CONFIG->db_installed;
+       }
+
+       if ($dblink = get_db_link('read')) {
+               mysql_query("select name from {$CONFIG->dbprefix}datalists limit 1", $dblink);
+               if (mysql_errno($dblink) > 0) {
                        return false;
                }
-       
-               /**
-                * Validate the platform Elgg is being installed on.
-                *
-                * @throws ConfigurationException if the validation fails.
-                * @return bool
-                */
-               function validate_platform()
-               {
-                       // Get database version
-                       if (!db_check_version())
-                               throw new ConfigurationException(elgg_echo('ConfigurationException:BadDatabaseVersion'));
-                       
-                       // Now check PHP
-                       if (!php_check_version())
-                               throw new ConfigurationException(elgg_echo('ConfigurationException:BadPHPVersion'));
-                               
-                       // TODO: Consider checking for installed modules etc
-                               
-                       return true;
-               }
+       } else {
+               return false;
+       }
 
-       /**
-        * Returns whether or not the database has been installed
-        *
-        * @return true|false Whether the database has been installed
-        */
-               function is_db_installed() {
-                       
-                       global $CONFIG;
-
-                       if (isset($CONFIG->db_installed)) {
-                               return $CONFIG->db_installed;
-                       }
-
-                       if ($dblink = get_db_link('read')) {
-                               mysql_query("select name from {$CONFIG->dbprefix}datalists limit 1",$dblink);
-                               if (mysql_errno($dblink) > 0) return false;
-                       } else return false; 
-                       
-                       $CONFIG->db_installed = true; // Set flag if db is installed (if false then we want to check every time)
-                       
-                       return true;
-                       
-               }
-               
-       /**
-        * Returns whether or not other settings have been set
-        *
-        * @return true|false Whether or not the rest of the installation has been followed through with
-        */
-               function is_installed() {
-                       
-                       global $CONFIG;
-                       return datalist_get('installed');
-                       
-               }
-               
-               /**
-                * Copy and create a new settings.php from settings.example.php, substituting the variables in
-                * $vars where appropriate.
-                * 
-                * $vars is an associate array of $key => $value, where $key is the variable text you wish to substitute (eg
-                * CONFIG_DBNAME will replace {{CONFIG_DBNAME}} in the settings file.
-                *
-                * @param array $vars The array of vars
-                * @param string $in_file Optional input file (if not settings.example.php)
-                * @return string The file containing substitutions.
-                */
-               function create_settings(array $vars, $in_file="engine/settings.example.php")
-               {
-                       $file = file_get_contents($in_file);
-                       
-                       if (!$file) return false; 
-                       
-                       foreach ($vars as $k => $v)
-                               $file = str_replace("{{".$k."}}", $v, $file);
-                       
-                       return $file;
-               }
-               
-       /**
-        * Initialisation for installation functions
-        *
-        */
-               function install_init() {
-                       register_action("systemsettings/install",true);                 
-               }
-               
-               register_elgg_event_handler("boot","system","install_init");
-               
-?>
\ No newline at end of file
+       // Set flag if db is installed (if false then we want to check every time)
+       $CONFIG->db_installed = true;
+
+       return true;
+}
+
+/**
+ * Returns whether or not other settings have been set
+ *
+ * @return true|false Whether or not the rest of the installation has been followed through with
+ */
+function is_installed() {
+       global $CONFIG;
+       return datalist_get('installed');
+}
+
+/**
+ * Copy and create a new settings.php from settings.example.php, substituting the variables in
+ * $vars where appropriate.
+ *
+ * $vars is an associate array of $key => $value, where $key is the variable text you wish to substitute (eg
+ * CONFIG_DBNAME will replace {{CONFIG_DBNAME}} in the settings file.
+ *
+ * @param array $vars The array of vars
+ * @param string $in_file Optional input file (if not settings.example.php)
+ * @return string The file containing substitutions.
+ */
+function create_settings(array $vars, $in_file="engine/settings.example.php") {
+       $file = file_get_contents($in_file);
+
+       if (!$file) {
+               return false;
+       }
+
+       foreach ($vars as $k => $v) {
+               $file = str_replace("{{".$k."}}", $v, $file);
+       }
+
+       return $file;
+}
+
+/**
+ * Initialisation for installation functions
+ *
+ */
+function install_init() {
+       register_action("systemsettings/install",true);
+}
+
+register_elgg_event_handler("boot","system","install_init");
\ No newline at end of file
index dd97d0927fd320d2db62697b09534ffaf2e6933f..19f3c138aa01d28dee5e13442ba33c78c604af92 100644 (file)
 <?php
+/**
+ * Elgg language module
+ * Functions to manage language and translations.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Elgg language module
-        * Functions to manage language and translations.
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd
-
-        * @link http://elgg.org/
-        */
-
-       /**
-        * Add a translation.
-        * 
-        * Translations are arrays in the Zend Translation array format, eg:
-        * 
-        *      $english = array('message1' => 'message1', 'message2' => 'message2');
-        *  $german = array('message1' => 'Nachricht1','message2' => 'Nachricht2');
-        *
-        * @param string $country_code Standard country code (eg 'en', 'nl', 'es')
-        * @param array $language_array Formatted array of strings
-        * @return true|false Depending on success
-        */
-
-               function add_translation($country_code, $language_array) {
-                       
-                       global $CONFIG;
-                       if (!isset($CONFIG->translations))
-                               $CONFIG->translations = array();
-                                                       
-                       $country_code = strtolower($country_code);
-                       $country_code = trim($country_code);
-                       if (is_array($language_array) && sizeof($language_array) > 0 && $country_code != "") {
-                               
-                               if (!isset($CONFIG->translations[$country_code])) {
-                                       $CONFIG->translations[$country_code] = $language_array;
-                               } else {
-                                       $CONFIG->translations[$country_code] = $language_array + $CONFIG->translations[$country_code];
-                               }
-                               
-                               return true;
-                               
-                       }
-                       return false;
-                       
+/**
+ * Add a translation.
+ *
+ * Translations are arrays in the Zend Translation array format, eg:
+ *
+ *     $english = array('message1' => 'message1', 'message2' => 'message2');
+ *  $german = array('message1' => 'Nachricht1','message2' => 'Nachricht2');
+ *
+ * @param string $country_code Standard country code (eg 'en', 'nl', 'es')
+ * @param array $language_array Formatted array of strings
+ * @return true|false Depending on success
+ */
+function add_translation($country_code, $language_array) {
+       global $CONFIG;
+       if (!isset($CONFIG->translations)) {
+               $CONFIG->translations = array();
+       }
+
+       $country_code = strtolower($country_code);
+       $country_code = trim($country_code);
+       if (is_array($language_array) && sizeof($language_array) > 0 && $country_code != "") {
+               if (!isset($CONFIG->translations[$country_code])) {
+                       $CONFIG->translations[$country_code] = $language_array;
+               } else {
+                       $CONFIG->translations[$country_code] = $language_array + $CONFIG->translations[$country_code];
                }
-               
-       /**
-        * Detect the current language being used by the current site or logged in user.
-        *
-        */
-       function get_current_language()
-       {
-               global $CONFIG;
-               
-               $language = get_language();
-                       
-               if (!$language)
-                       $language = 'en';
-                       
+               return true;
+       }
+       return false;
+}
+
+/**
+ * Detect the current language being used by the current site or logged in user.
+ *
+ */
+function get_current_language() {
+       global $CONFIG;
+
+       $language = get_language();
+
+       if (!$language) {
+               $language = 'en';
+       }
+
+       return $language;
+}
+
+/**
+ * Gets the current language in use by the system or user.
+ *
+ * [Marcus Povey 20090216: Not sure why this func is necessary.]
+ *
+ * @return string The language code (eg "en")
+ */
+function get_language() {
+       global $CONFIG;
+
+       $user = get_loggedin_user();
+       $language = false;
+
+       if (($user) && ($user->language)) {
+               $language = $user->language;
+       }
+
+       if ((!$language) && (isset($CONFIG->language)) && ($CONFIG->language)) {
+               $language = $CONFIG->language;
+       }
+
+       if ($language) {
                return $language;
        }
-               
-       /**
-        * Gets the current language in use by the system or user.
-        * 
-        * [Marcus Povey 20090216: Not sure why this func is necessary.]
-        *
-        * @return string The language code (eg "en")
-        */
-               function get_language() {
-                       
-                       global $CONFIG;
-               
-                       $user = get_loggedin_user();  
-                       $language = false;
-       
-                       if (($user) && ($user->language))
-                               $language = $user->language;
-
-                       if ((!$language) && (isset($CONFIG->language)) && ($CONFIG->language))
-                               $language = $CONFIG->language;
-                               
-                       if ($language) {
-                               return $language;
-                       }               
-                       return false;
-                       
-               }
-       
-       /**
-        * Given a message shortcode, returns an appropriately translated full-text string 
-        *
-        * @param string $message_key The short message code
-        * @param string $language Optionally, the standard language code (defaults to the site default, then English)
-        * @return string Either the translated string, or the original English string, or an empty string
-        */
-               function elgg_echo($message_key, $language = "") {
-                       
-                       global $CONFIG;
-                               
-                       static $CURRENT_LANGUAGE;
-                       if ((!$CURRENT_LANGUAGE) && (!$language)) 
-                               $CURRENT_LANGUAGE = $language = get_language();
-                       else 
-                               $language = $CURRENT_LANGUAGE;
-
-                       if (isset($CONFIG->translations[$language][$message_key])) {
-                               return $CONFIG->translations[$language][$message_key];
-                       } else if (isset($CONFIG->translations["en"][$message_key])) {
-                               return $CONFIG->translations["en"][$message_key];
-                       }
-                               
-                       return $message_key;
-                       
-               }
-               
-       /**
-        * When given a full path, finds translation files and loads them
-        *
-        * @param string $path Full path
-        * @param bool $load_all If true all languages are loaded, if false only the current language + en are loaded
-        */
-               function register_translations($path, $load_all = false) {
-                       global $CONFIG;
-                       
-                       // Make a note of this path just incase we need to register this language later
-                       if(!isset($CONFIG->language_paths)) $CONFIG->language_paths = array();
-                       $CONFIG->language_paths[$path] = true;
-                       
-                       // Get the current language based on site defaults and user preference
-                       $current_language = get_current_language();
-
-                       if (isset($CONFIG->debug) && $CONFIG->debug == true) error_log("Translations loaded from : $path");
-               
-                       if ($handle = opendir($path)) {
-                               while ($language = readdir($handle)) {
-                               
-                                       if (
-                                               ((in_array($language, array('en.php', $current_language . '.php'))) /*&& (!is_dir($path . $language))*/) ||
-                                               (($load_all) && (strpos($language, '.php')!==false)/* && (!is_dir($path . $language))*/) 
-                                       )
-                                               include_once($path . $language);
-                                       
-                               }
-                       }
-                       else
-                               error_log("Missing translation path $path");
-                               
-               }
-               
-               /** 
-                * Reload all translations from all registered paths.
-                * 
-                * This is only called by functions which need to know all possible translations, namely the
-                * statistic gathering ones.
-                * 
-                * TODO: Better on demand loading based on language_paths array
-                * 
-                * @return bool
-                */
-               function reload_all_translations() 
-               {
-                       global $CONFIG;
-                       
-                       static $LANG_RELOAD_ALL_RUN;
-                       if ($LANG_RELOAD_ALL_RUN) return null;
-                       
-                       foreach ($CONFIG->language_paths as $path => $dummy)
-                               register_translations($path, true);
-
-                       $LANG_RELOAD_ALL_RUN = true;
-               }
-               
-       /**
-        * Return an array of installed translations as an associative array "two letter code" => "native language name".
-        */
-               function get_installed_translations()
-               {
-                       global $CONFIG;
-                       
-                       // Ensure that all possible translations are loaded
-                       reload_all_translations();
-                       
-                       $installed = array();
-                       
-                       foreach ($CONFIG->translations as $k => $v)
-                       {
-                               $installed[$k] = elgg_echo($k, $k);
-                               
-                               $completeness = get_language_completeness($k);
-                               if ((isadminloggedin()) && ($completeness<100) && ($k!='en'))
-                                       $installed[$k] .= " (" . $completeness . "% " . elgg_echo('complete') . ")";
+
+       return false;
+}
+
+/**
+ * Given a message shortcode, returns an appropriately translated full-text string
+ *
+ * @param string $message_key The short message code
+ * @param string $language Optionally, the standard language code (defaults to the site default, then English)
+ * @return string Either the translated string, or the original English string, or an empty string
+ */
+function elgg_echo($message_key, $language = "") {
+       global $CONFIG;
+
+       static $CURRENT_LANGUAGE;
+       if ((!$CURRENT_LANGUAGE) && (!$language)) {
+               $CURRENT_LANGUAGE = $language = get_language();
+       } else {
+               $language = $CURRENT_LANGUAGE;
+       }
+
+       if (isset($CONFIG->translations[$language][$message_key])) {
+               return $CONFIG->translations[$language][$message_key];
+       } else if (isset($CONFIG->translations["en"][$message_key])) {
+               return $CONFIG->translations["en"][$message_key];
+       }
+
+       return $message_key;
+}
+
+/**
+ * When given a full path, finds translation files and loads them
+ *
+ * @param string $path Full path
+ * @param bool $load_all If true all languages are loaded, if false only the current language + en are loaded
+ */
+function register_translations($path, $load_all = false) {
+       global $CONFIG;
+
+       // Make a note of this path just incase we need to register this language later
+       if(!isset($CONFIG->language_paths)) $CONFIG->language_paths = array();
+       $CONFIG->language_paths[$path] = true;
+
+       // Get the current language based on site defaults and user preference
+       $current_language = get_current_language();
+
+       if (isset($CONFIG->debug) && $CONFIG->debug == true) {
+               error_log("Translations loaded from : $path");
+       }
+
+       if ($handle = opendir($path)) {
+               while ($language = readdir($handle)) {
+                       if (
+                               ((in_array($language, array('en.php', $current_language . '.php'))) /*&& (!is_dir($path . $language))*/) ||
+                               (($load_all) && (strpos($language, '.php')!==false)/* && (!is_dir($path . $language))*/)
+                       ) {
+                               include_once($path . $language);
                        }
-                       
-                       return $installed;
                }
-               
-       /**
-        * Return the level of completeness for a given language code (compared to english)
-        */
-               function get_language_completeness($language)
-               {
-                       global $CONFIG;
-                       
-                       // Ensure that all possible translations are loaded
-                       reload_all_translations();
-                       
-                       $language = sanitise_string($language);
-                       
-                       $en = count($CONFIG->translations['en']);
-                       
-                       $missing = get_missing_language_keys($language);
-                       if ($missing) $missing = count($missing); else $missing = 0;
-                       
-                       //$lang = count($CONFIG->translations[$language]);
-                       $lang = $en - $missing;
-                       
-                       return round(($lang / $en) * 100, 2);
+       } else {
+               error_log("Missing translation path $path");
+       }
+}
+
+/**
+ * Reload all translations from all registered paths.
+ *
+ * This is only called by functions which need to know all possible translations, namely the
+ * statistic gathering ones.
+ *
+ * TODO: Better on demand loading based on language_paths array
+ *
+ * @return bool
+ */
+function reload_all_translations() {
+       global $CONFIG;
+
+       static $LANG_RELOAD_ALL_RUN;
+       if ($LANG_RELOAD_ALL_RUN) {
+               return null;
+       }
+
+       foreach ($CONFIG->language_paths as $path => $dummy) {
+               register_translations($path, true);
+       }
+
+       $LANG_RELOAD_ALL_RUN = true;
+}
+
+/**
+ * Return an array of installed translations as an associative array "two letter code" => "native language name".
+ */
+function get_installed_translations() {
+       global $CONFIG;
+
+       // Ensure that all possible translations are loaded
+       reload_all_translations();
+
+       $installed = array();
+
+       foreach ($CONFIG->translations as $k => $v) {
+               $installed[$k] = elgg_echo($k, $k);
+
+               $completeness = get_language_completeness($k);
+               if ((isadminloggedin()) && ($completeness<100) && ($k!='en')) {
+                       $installed[$k] .= " (" . $completeness . "% " . elgg_echo('complete') . ")";
                }
-               
-       /**
-        * Return the translation keys missing from a given language, or those that are identical to the english version.
-        */
-               function get_missing_language_keys($language)
-               {
-                       global $CONFIG;
-                       
-                       // Ensure that all possible translations are loaded
-                       reload_all_translations();
-                       
-                       $missing = array();
-                       
-                       foreach ($CONFIG->translations['en'] as $k => $v)
-                       {
-                               if ((!isset($CONFIG->translations[$language][$k])) 
-                               || ($CONFIG->translations[$language][$k] == $CONFIG->translations['en'][$k])) 
-                                       $missing[] = $k;
-                       }
-                       
-                       if (count($missing))
-                               return $missing;
-                               
-                       return false;
+       }
+
+       return $installed;
+}
+
+/**
+ * Return the level of completeness for a given language code (compared to english)
+ */
+function get_language_completeness($language) {
+       global $CONFIG;
+
+       // Ensure that all possible translations are loaded
+       reload_all_translations();
+
+       $language = sanitise_string($language);
+
+       $en = count($CONFIG->translations['en']);
+
+       $missing = get_missing_language_keys($language);
+       if ($missing) {
+               $missing = count($missing);
+       } else {
+               $missing = 0;
+       }
+
+       //$lang = count($CONFIG->translations[$language]);
+       $lang = $en - $missing;
+
+       return round(($lang / $en) * 100, 2);
+}
+
+/**
+ * Return the translation keys missing from a given language, or those that are identical to the english version.
+ */
+function get_missing_language_keys($language) {
+       global $CONFIG;
+
+       // Ensure that all possible translations are loaded
+       reload_all_translations();
+
+       $missing = array();
+
+       foreach ($CONFIG->translations['en'] as $k => $v) {
+               if ((!isset($CONFIG->translations[$language][$k]))
+               || ($CONFIG->translations[$language][$k] == $CONFIG->translations['en'][$k])) {
+                       $missing[] = $k;
                }
-               
-               register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
-               
-?>
\ No newline at end of file
+       }
+
+       if (count($missing)) {
+               return $missing;
+       }
+
+       return false;
+}
+
+register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
\ No newline at end of file
index 0edada0aead5ebbb8b9fe49940068dbef95f0de3..21ee7d5fa3e4e9571cf8cfe91ea6bfef5ebea9db 100644 (file)
 <?php
+/**
+ * Elgg geo-location tagging library.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
+
+/**
+ * Define an interface for geo-tagging entities.
+ *
+ */
+interface Locatable {
+       /** Set a location text */
+       public function setLocation($location);
 
        /**
-        * Elgg geo-location tagging library.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
-        * @link http://elgg.org/
+        * Set latitude and longitude tags for a given entity.
+        *
+        * @param float $lat
+        * @param float $long
         */
+       public function setLatLong($lat, $long);
 
        /**
-        * Define an interface for geo-tagging entities.
+        * Get the contents of the ->geo:lat field.
         *
         */
-       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();
-       }
+       public function getLatitude();
 
        /**
-        * Encode a location into a latitude and longitude, caching the result.
+        * Get the contents of the ->geo:lat field.
         *
-        * Works by triggering the 'geocode' 'location' plugin hook, and requires a geocoding module to be installed
-        * activated in order to work.
-        * 
-        * @param String $location The location, e.g. "London", or "24 Foobar Street, Gotham City"
         */
-       function elgg_geocode_location($location)
-       {
-               global $CONFIG;
-               
-               // Handle cases where we are passed an array (shouldn't be but can happen if location is a tag field)
-               if (is_array($location))
-                       $location = implode(', ', $location);
-                       
-               $location = sanitise_string($location);
-               
-               // Look for cached version
-               $cached_location = get_data_row("SELECT * from {$CONFIG->dbprefix}geocode_cache WHERE location='$location'");
-               
-               if ($cached_location)
-                       return array('lat' => $cached_location->lat, 'long' => $cached_location->long);
-               
-               // Trigger geocode event if not cached
-               $return = false;
-               $return = trigger_plugin_hook('geocode', 'location', array('location' => $location), $return);
-               
-               // If returned, cache and return value
-               if (($return) && (is_array($return)))
-               {
-                       $lat = (float)$return['lat'];
-                       $long = (float)$return['long'];
-                       
-                       // Put into cache at the end of the page since we don't really care that much
-                       execute_delayed_write_query("INSERT DELAYED INTO {$CONFIG->dbprefix}geocode_cache (location, lat, `long`) VALUES ('$location', '{$lat}', '{$long}') ON DUPLICATE KEY UPDATE lat='{$lat}', `long`='{$long}'");
-               }
-               
-               return $return;
-       }
-       
+       public function getLongitude();
+
        /**
-        * Return entities within a given geographic area.
+        * Get the ->location metadata.
         *
-        * @param real $lat Latitude
-        * @param real $long Longitude
-        * @param real $radius The radius
-        * @param string $type The type of entity (eg "user", "object" etc)
-        * @param string $subtype The arbitrary subtype of the entity
-        * @param int $owner_guid The GUID of the owning user
-        * @param string $order_by The field to order by; by default, time_created desc
-        * @param int $limit The number of entities to return; 10 by default
-        * @param int $offset The indexing offset, 0 by default
-        * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param int|array $container_guid The container or containers to get entities from (default: all containers).
-        * @return array A list of entities. 
         */
-       function get_entities_in_area($lat, $long, $radius, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid)
-       {
-               global $CONFIG;
-               
-               if ($subtype === false || $subtype === null || $subtype === 0)
-                       return false;
-                       
-               $lat = (real)$lat;
-               $long = (real)$long;
-               $radius = (real)$radius;
-
-               $order_by = sanitise_string($order_by);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               $where = array();
-               
-               if (is_array($type)) {                  
-                       $tempwhere = "";
-                       if (sizeof($type))
+       public function getLocation();
+}
+
+/**
+ * Encode a location into a latitude and longitude, caching the result.
+ *
+ * Works by triggering the 'geocode' 'location' plugin hook, and requires a geocoding module to be installed
+ * activated in order to work.
+ *
+ * @param String $location The location, e.g. "London", or "24 Foobar Street, Gotham City"
+ */
+function elgg_geocode_location($location) {
+       global $CONFIG;
+
+       // Handle cases where we are passed an array (shouldn't be but can happen if location is a tag field)
+       if (is_array($location)) {
+               $location = implode(', ', $location);
+       }
+
+       $location = sanitise_string($location);
+
+       // Look for cached version
+       $cached_location = get_data_row("SELECT * from {$CONFIG->dbprefix}geocode_cache WHERE location='$location'");
+
+       if ($cached_location) {
+               return array('lat' => $cached_location->lat, 'long' => $cached_location->long);
+       }
+
+       // Trigger geocode event if not cached
+       $return = false;
+       $return = trigger_plugin_hook('geocode', 'location', array('location' => $location), $return);
+
+       // If returned, cache and return value
+       if (($return) && (is_array($return))) {
+               $lat = (float)$return['lat'];
+               $long = (float)$return['long'];
+
+               // Put into cache at the end of the page since we don't really care that much
+               execute_delayed_write_query("INSERT DELAYED INTO {$CONFIG->dbprefix}geocode_cache (location, lat, `long`) VALUES ('$location', '{$lat}', '{$long}') ON DUPLICATE KEY UPDATE lat='{$lat}', `long`='{$long}'");
+       }
+
+       return $return;
+}
+
+/**
+ * Return entities within a given geographic area.
+ *
+ * @param real $lat Latitude
+ * @param real $long Longitude
+ * @param real $radius The radius
+ * @param string $type The type of entity (eg "user", "object" etc)
+ * @param string $subtype The arbitrary subtype of the entity
+ * @param int $owner_guid The GUID of the owning user
+ * @param string $order_by The field to order by; by default, time_created desc
+ * @param int $limit The number of entities to return; 10 by default
+ * @param int $offset The indexing offset, 0 by default
+ * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param int|array $container_guid The container or containers to get entities from (default: all containers).
+ * @return array A list of entities.
+ */
+function get_entities_in_area($lat, $long, $radius, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid) {
+       global $CONFIG;
+
+       if ($subtype === false || $subtype === null || $subtype === 0) {
+               return false;
+       }
+
+       $lat = (real)$lat;
+       $long = (real)$long;
+       $radius = (real)$radius;
+
+       $order_by = sanitise_string($order_by);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $where = array();
+
+       if (is_array($type)) {
+               $tempwhere = "";
+               if (sizeof($type)) {
                        foreach($type as $typekey => $subtypearray) {
                                foreach($subtypearray as $subtypeval) {
                                        $typekey = sanitise_string($typekey);
                                        }
                                        if (!empty($tempwhere)) $tempwhere .= " or ";
                                        $tempwhere .= "(e.type = '{$typekey}' and e.subtype = {$subtypeval})";
-                               }                                                               
+                               }
                        }
-                       if (!empty($tempwhere)) $where[] = "({$tempwhere})";
-                       
-               } else {
-               
-                       $type = sanitise_string($type);
-                       $subtype = get_subtype_id($type, $subtype);
-                       
-                       if ($type != "")
-                               $where[] = "e.type='$type'";
-                       if ($subtype!=="")
-                               $where[] = "e.subtype=$subtype";
-                               
                }
+               if (!empty($tempwhere)) {
+                       $where[] = "({$tempwhere})";
+               }
+       } else {
+               $type = sanitise_string($type);
+               $subtype = get_subtype_id($type, $subtype);
 
-               if ($owner_guid != "") {
-                       if (!is_array($owner_guid)) {
-                               $owner_array = array($owner_guid);
-                               $owner_guid = (int) $owner_guid;
-                               $where[] = "e.owner_guid = '$owner_guid'";
-                       } else if (sizeof($owner_guid) > 0) {
-                               $owner_array = array_map('sanitise_int', $owner_guid);
-                               // Cast every element to the owner_guid array to int
-                               $owner_guid = implode(",",$owner_guid); //
-                               $where[] = "e.owner_guid in ({$owner_guid})" ; //
-                       }
-                       if (is_null($container_guid)) {
-                               $container_guid = $owner_array;
-                       }
+               if ($type != "") {
+                       $where[] = "e.type='$type'";
                }
-               
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-                       
-               if (!is_null($container_guid)) {
-                       if (is_array($container_guid)) {
-                               foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val;
-                               $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")";
-                       } else {
-                               $container_guid = (int) $container_guid;
-                               $where[] = "e.container_guid = {$container_guid}";
-                       }
-               }       
-       
-               // Add the calendar stuff
-               $loc_join = "
-                       JOIN {$CONFIG->dbprefix}metadata loc_start on e.guid=loc_start.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings loc_start_name on loc_start.name_id=loc_start_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings loc_start_value on loc_start.value_id=loc_start_value.id
-                       
-                       JOIN {$CONFIG->dbprefix}metadata loc_end on e.guid=loc_end.entity_guid
-                       JOIN {$CONFIG->dbprefix}metastrings loc_end_name on loc_end.name_id=loc_end_name.id
-                       JOIN {$CONFIG->dbprefix}metastrings loc_end_value on loc_end.value_id=loc_end_value.id
-               ";      
-
-               $lat_min = $lat - $radius;
-               $lat_max = $lat + $radius;
-               $long_min = $long - $radius;
-               $long_max = $long + $radius;
-                       
-               $where[] = "loc_start_name.string='geo:lat'";
-               $where[] = "loc_start_value.string>=$lat_min";
-               $where[] = "loc_start_value.string<=$lat_max";
-               $where[] = "loc_end_name.string='geo:long'";
-               $where[] = "loc_end_value.string >= $long_min";
-               $where[] = "loc_end_value.string <= $long_max";
-               
-               
-               if (!$count) {
-                       $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $loc_join where ";
-               } else {
-                       $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $loc_join where ";
+
+               if ($subtype!=="") {
+                       $where[] = "e.subtype=$subtype";
+               }
+       }
+
+       if ($owner_guid != "") {
+               if (!is_array($owner_guid)) {
+                       $owner_array = array($owner_guid);
+                       $owner_guid = (int) $owner_guid;
+                       $where[] = "e.owner_guid = '$owner_guid'";
+               } else if (sizeof($owner_guid) > 0) {
+                       $owner_array = array_map('sanitise_int', $owner_guid);
+                       // Cast every element to the owner_guid array to int
+                       $owner_guid = implode(",",$owner_guid); //
+                       $where[] = "e.owner_guid in ({$owner_guid})" ; //
                }
-               foreach ($where as $w)
-                       $query .= " $w and ";
-                       
-               $query .= get_access_sql_suffix('e'); // Add access controls
-               
-               if (!$count) {
-                       $query .= " order by n.calendar_start $order_by";
-                       if ($limit) $query .= " limit $offset, $limit"; // Add order and limit
-                       $dt = get_data($query, "entity_row_to_elggstar");
-                       return $dt;
+               if (is_null($container_guid)) {
+                       $container_guid = $owner_array;
+               }
+       }
+
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       if (!is_null($container_guid)) {
+               if (is_array($container_guid)) {
+                       foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val;
+                       $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")";
                } else {
-                       $total = get_data_row($query);
-                       return $total->total;
-               }       
+                       $container_guid = (int) $container_guid;
+                       $where[] = "e.container_guid = {$container_guid}";
+               }
        }
-       
-       /**
-        * List entities in a given location
-        *
-        * @param string $location Location
-        * @param string $type The type of entity (eg "user", "object" etc)
-        * @param string $subtype The arbitrary subtype of the entity
-        * @param int $owner_guid The GUID of the owning user
-        * @param int $limit The number of entities to display per page (default: 10)
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow gallery view 
-        * @param true|false $pagination Display pagination? Default: true
-        * @return string A viewable list of entities
-        */
-       function list_entities_location($location, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
-               return list_entities_from_metadata('location', $location, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation);
+
+       // Add the calendar stuff
+       $loc_join = "
+               JOIN {$CONFIG->dbprefix}metadata loc_start on e.guid=loc_start.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings loc_start_name on loc_start.name_id=loc_start_name.id
+               JOIN {$CONFIG->dbprefix}metastrings loc_start_value on loc_start.value_id=loc_start_value.id
+
+               JOIN {$CONFIG->dbprefix}metadata loc_end on e.guid=loc_end.entity_guid
+               JOIN {$CONFIG->dbprefix}metastrings loc_end_name on loc_end.name_id=loc_end_name.id
+               JOIN {$CONFIG->dbprefix}metastrings loc_end_value on loc_end.value_id=loc_end_value.id
+       ";
+
+       $lat_min = $lat - $radius;
+       $lat_max = $lat + $radius;
+       $long_min = $long - $radius;
+       $long_max = $long + $radius;
+
+       $where[] = "loc_start_name.string='geo:lat'";
+       $where[] = "loc_start_value.string>=$lat_min";
+       $where[] = "loc_start_value.string<=$lat_max";
+       $where[] = "loc_end_name.string='geo:long'";
+       $where[] = "loc_end_value.string >= $long_min";
+       $where[] = "loc_end_value.string <= $long_max";
+
+       if (!$count) {
+               $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $loc_join where ";
+       } else {
+               $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $loc_join where ";
+       }
+       foreach ($where as $w) {
+               $query .= " $w and ";
        }
-       
-       /**
-        * List items within a given geographic area.
-        *
-        * @param real $lat Latitude
-        * @param real $long Longitude
-        * @param real $radius The radius
-        * @param string $type The type of entity (eg "user", "object" etc)
-        * @param string $subtype The arbitrary subtype of the entity
-        * @param int $owner_guid The GUID of the owning user
-        * @param int $limit The number of entities to display per page (default: 10)
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow gallery view 
-        * @param true|false $pagination Display pagination? Default: true
-        * @return string A viewable list of entities
-        */
-       function list_entities_in_area($lat, $long, $radius, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
-               
-               $offset = (int) get_input('offset');
-               $count = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset, true);
-               $entities = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset);
 
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation);
+       $query .= get_access_sql_suffix('e'); // Add access controls
+
+       if (!$count) {
+               $query .= " order by n.calendar_start $order_by";
+               // Add order and limit
+               if ($limit) {
+                       $query .= " limit $offset, $limit";
+               }
+               $dt = get_data($query, "entity_row_to_elggstar");
+               return $dt;
+       } else {
+               $total = get_data_row($query);
+               return $total->total;
        }
-       
-       // Some distances in degrees (approximate)
-       define("MILE", 0.01515);
-       define("KILOMETER", 0.00932);
-       
-       
-       // TODO: get objects within x miles by entities, metadata and relationship
-       
-       // TODO: List 
-       
-       
-?>
\ No newline at end of file
+}
+
+/**
+ * List entities in a given location
+ *
+ * @param string $location Location
+ * @param string $type The type of entity (eg "user", "object" etc)
+ * @param string $subtype The arbitrary subtype of the entity
+ * @param int $owner_guid The GUID of the owning user
+ * @param int $limit The number of entities to display per page (default: 10)
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow gallery view
+ * @param true|false $pagination Display pagination? Default: true
+ * @return string A viewable list of entities
+ */
+function list_entities_location($location, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
+       return list_entities_from_metadata('location', $location, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation);
+}
+
+/**
+ * List items within a given geographic area.
+ *
+ * @param real $lat Latitude
+ * @param real $long Longitude
+ * @param real $radius The radius
+ * @param string $type The type of entity (eg "user", "object" etc)
+ * @param string $subtype The arbitrary subtype of the entity
+ * @param int $owner_guid The GUID of the owning user
+ * @param int $limit The number of entities to display per page (default: 10)
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow gallery view
+ * @param true|false $pagination Display pagination? Default: true
+ * @return string A viewable list of entities
+ */
+function list_entities_in_area($lat, $long, $radius, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) {
+
+       $offset = (int) get_input('offset');
+       $count = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset, true);
+       $entities = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation);
+}
+
+// Some distances in degrees (approximate)
+define("MILE", 0.01515);
+define("KILOMETER", 0.00932);
+
+// TODO: get objects within x miles by entities, metadata and relationship
+
+// TODO: List
\ No newline at end of file
index 6221f4aa15b52c84e6b6e235851ac5d9eb8e558e..2cef15c64da129906d5911280934340e8f6209a0 100644 (file)
@@ -1,62 +1,61 @@
 <?php
-       /**
       * Elgg wrapper functions for multibyte string support.
-        * 
       * @package Elgg
       * @subpackage Core
       * @author Curverider Ltd
       * @link http://elgg.org/
       */
+/**
+ * Elgg wrapper functions for multibyte string support.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Wrapper function: Returns the result of mb_strtolower if mb_support is present, else the
-        * result of strtolower is returned.
-        *
-        * @param string $string The string.
-        * @param string $charset The charset (if multibyte support is present) : default 'UTF8'
-        * @return string
-        */
-       function elgg_strtolower($string, $charset = 'UTF8')
-       {
-               if (is_callable('mb_strtolower'))
-                       return mb_strtolower($string, $charset);
-                       
-               return strtolower($string);
+/**
+ * Wrapper function: Returns the result of mb_strtolower if mb_support is present, else the
+ * result of strtolower is returned.
+ *
+ * @param string $string The string.
+ * @param string $charset The charset (if multibyte support is present) : default 'UTF8'
+ * @return string
+ */
+function elgg_strtolower($string, $charset = 'UTF8') {
+       if (is_callable('mb_strtolower')) {
+               return mb_strtolower($string, $charset);
        }
-       
-       /**
-        * Wrapper function: Returns the result of mb_strtoupper if mb_support is present, else the
-        * result of strtoupper is returned.
-        *
-        * @param string $string The string.
-        * @param string $charset The charset (if multibyte support is present) : default 'UTF8'
-        * @return string
-        */
-       function elgg_strtoupper($string, $charset = 'UTF8')
-       {
-               if (is_callable('mb_strtoupper'))
-                       return mb_strtoupper($string, $charset);
-                       
-               return strtoupper($string);
+
+       return strtolower($string);
+}
+
+/**
+ * Wrapper function: Returns the result of mb_strtoupper if mb_support is present, else the
+ * result of strtoupper is returned.
+ *
+ * @param string $string The string.
+ * @param string $charset The charset (if multibyte support is present) : default 'UTF8'
+ * @return string
+ */
+function elgg_strtoupper($string, $charset = 'UTF8') {
+       if (is_callable('mb_strtoupper')) {
+               return mb_strtoupper($string, $charset);
        }
-       
-       /**
-        * Wrapper function: Returns the result of mb_substr if mb_support is present, else the 
-        * result of substr is returned.
-        *
-        * @param string $string The string.
       * @param int $start Start position.
-        * @param int $length Length.
-        * @param string $charset The charset (if multibyte support is present) : default 'UTF8'
-        * @return string
-        */
-       function elgg_substr($string, $start = 0, $length = null, $charset = 'UTF8')
-       {
-               if (is_callable('mb_substr'))
-                       return mb_substr($string, $start, $length, $charset);
-               
-               return substr($string, $start, $length);
+
+       return strtoupper($string);
+}
+
+/**
+ * Wrapper function: Returns the result of mb_substr if mb_support is present, else the
* result of substr is returned.
+ *
+ * @param string $string The string.
+ * @param int $start Start position.
+ * @param int $length Length.
+ * @param string $charset The charset (if multibyte support is present) : default 'UTF8'
+ * @return string
+ */
+function elgg_substr($string, $start = 0, $length = null, $charset = 'UTF8') {
+       if (is_callable('mb_substr')) {
+               return mb_substr($string, $start, $length, $charset);
        }
-       
-       // TODO: Other wrapper functions
-?>
\ No newline at end of file
+
+       return substr($string, $start, $length);
+}
+
+// TODO: Other wrapper functions
\ No newline at end of file
index 5f65ce9a753584779b8dbcd771072de6700f5b1d..498d1ff4fee587cc1e35ab697fdee29c729f23ca 100644 (file)
 <?php
+/**
+ * Elgg memcache support.
+ *
+ * Requires php5-memcache to work.
+ *
+ * @package Elgg
+ * @subpackage API
+ * @author Curverider Ltd <info@elgg.com>
+ * @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';
+
        /**
-        * Elgg memcache support.
-        * 
-        * Requires php5-memcache to work.
-        * 
-        * @package Elgg
-        * @subpackage API
-        * @author Curverider Ltd <info@elgg.com>
-        * @link http://elgg.org/
+        * Memcache object
         */
+       private $memcache;
 
        /**
-        * Memcache wrapper class.
-        * @author Curverider Ltd <info@elgg.com>
+        * Expiry of saved items (default timeout after a day to prevent anything getting too stale)
         */
-       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);
+       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
-                       {
-                               if ((isset($CONFIG->debug)) && ($CONFIG->debug == true))
-                                       error_log(elgg_echo('memcache:noaddserver'));
-                                       
-                               $server = $CONFIG->memcache_servers[0];
-                               if (is_array($server))
-                               {
-                                       $this->memcache->connect($server[0], $server[1]);
-                               }
-                               else
-                                       $this->memcache->addServer($server, 11211);
+               } else {
+                       if ((isset($CONFIG->debug)) && ($CONFIG->debug == true)) {
+                               error_log(elgg_echo('memcache:noaddserver'));
+                       }
+
+                       $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 ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result))
-                               error_log("MEMCACHE: FAILED TO SAVE $key"); 
-                       
-                       return $result;                 
-               }
-               
-               public function load($key, $offset = 0, $limit = null)
-               {
-                       $key = $this->make_memcache_key($key);
-
-                       $result = $this->memcache->get($key);
-                       if ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result))
-                               error_log("MEMCACHE: FAILED TO LOAD $key");
-                       
-                       return $result;
                }
-               
-               public function delete($key) 
-               {
-                       $key = $this->make_memcache_key($key);
-                       
-                       return $this->memcache->delete($key, 0);
+
+               // 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));
                }
-               
-               public function clear()
-               {
-                       // DISABLE clearing for now - you must use delete on a specific key.
-                       return true;
-                       
-                       //TODO: Namespaces as in #532
+
+               // Set some defaults
+               if (isset($CONFIG->memcache_expires)) {
+                       $this->expires = $CONFIG->memcache_expires;
                }
-               
        }
-       
+
        /**
-        * Return true if memcache is available and configured.
+        * Set the default expiry.
         *
-        * @return bool
+        * @param int $expires The lifetime as a unix timestamp or time from now. Defaults forever.
         */
-       function is_memcache_available()
-       {
-               global $CONFIG;
-               
-               static $memcache_available;
-               
-               if ((!isset($CONFIG->memcache)) || (!$CONFIG->memcache))
-                       return false;
-               
-               if (($memcache_available!==true) && ($memcache_available!==false)) // If we haven't set variable to something
-               {
-                       try {
-                               $tmp = new ElggMemcache();
-                               $memcache_available = true; // No exception thrown so we have memcache available
-                       } catch (Exception $e) { $memcache_available = false; }
+       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 ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result)) {
+                       error_log("MEMCACHE: FAILED TO SAVE $key");
+               }
+
+               return $result;
+       }
+
+       public function load($key, $offset = 0, $limit = null) {
+               $key = $this->make_memcache_key($key);
+
+               $result = $this->memcache->get($key);
+               if ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result)) {
+                       error_log("MEMCACHE: FAILED TO LOAD $key");
+               }
+
+               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
+       }
+}
+
+/**
+ * Return true if memcache is available and configured.
+ *
+ * @return bool
+ */
+function is_memcache_available() {
+       global $CONFIG;
+
+       static $memcache_available;
+
+       if ((!isset($CONFIG->memcache)) || (!$CONFIG->memcache)) {
+               return false;
+       }
+
+       // If we haven't set variable to something
+       if (($memcache_available!==true) && ($memcache_available!==false))  {
+               try {
+                       $tmp = new ElggMemcache();
+                       // No exception thrown so we have memcache available
+                       $memcache_available = true;
+               } catch (Exception $e) {
+                       $memcache_available = false;
                }
-               
-               return $memcache_available;
        }
-?>
\ No newline at end of file
+
+       return $memcache_available;
+}
\ No newline at end of file
index c6e5db4cdc8155ab8aacc1f6c33b5cda4a854317..5ca39b586f079628192ef0b8723f4c71535aea34 100644 (file)
 <?php
-       /**
-        * Elgg metadata
-        * Functions to manage object metadata.
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd <info@elgg.com>
-
-        * @link http://elgg.org/
-        */
+/**
+ * Elgg metadata
+ * Functions to manage object metadata.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @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 {
        /**
-        * ElggMetadata
-        * This class describes metadata that can be attached to ElggEntities.
-        * 
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Core
+        * Construct a new site object, optionally from a given id value or row.
+        *
+        * @param mixed $id
         */
-       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)) {
-                               
-                               if ($id instanceof stdClass)
-                                       $metadata = $id; // Create from db row
-                               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);
-               }
+       function __construct($id = null) {
+               $this->attributes = array();
 
-               /**
-                * 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);
+               if (!empty($id)) {
+                       // Create from db row
+                       if ($id instanceof stdClass) {
+                               $metadata = $id;
+                       } else {
+                               $metadata = get_metadata($id);
                        }
-                       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_new('IOException:UnableToSaveNew'), get_class()));
-                               return $this->id;
+
+                       if ($metadata) {
+                               $objarray = (array) $metadata;
+                               foreach($objarray as $key => $value) {
+                                       $this->attributes[$key] = $value;
+                               }
+                               $this->attributes['type'] = "metadata";
                        }
-                       
                }
-               
-               /**
-                * 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); }
        }
 
        /**
-        * Convert a database row to a new ElggMetadata
+        * Class member get overloading
         *
-        * @param stdClass $row
-        * @return stdClass or ElggMetadata
+        * @param string $name
+        * @return mixed
         */
-       function row_to_elggmetadata($row) 
-       {
-               if (!($row instanceof stdClass))
-                       return $row;
-                       
-               return new ElggMetadata($row);
+       function __get($name) {
+               return $this->get($name);
        }
 
-                       
        /**
-        * Get a specific item of metadata.
-        * 
-        * @param $id int The item of metadata being retrieved.
+        * Class member set overloading
+        *
+        * @param string $name
+        * @param mixed $value
+        * @return mixed
         */
-       function get_metadata($id)
-       {
-               global $CONFIG;
-
-               $id = (int)$id;
-               $access = get_access_sql_suffix("e");
-               $md_access = get_access_sql_suffix("m");
-
-               return row_to_elggmetadata(get_data_row("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.id=$id and $access and $md_access"));
+       function __set($name, $value) {
+               return $this->set($name, $value);
        }
-       
+
        /**
-        * Removes metadata on an entity with a particular name, optionally with a given value.
+        * Determines whether or not the user can edit this piece of metadata
         *
-        * @param int $entity_guid The entity GUID
-        * @param string $name The name of the metadata
-        * @param string $value The optional value of the item (useful for removing a single item in a multiple set)
-        * @return true|false Depending on success
+        * @return true|false Depending on permissions
         */
-       function remove_metadata($entity_guid, $name, $value = "") {
-               
-               global $CONFIG;
-               $entity_guid = (int) $entity_guid;
-               $name = sanitise_string($name);
-               $value = sanitise_string($value);
-
-               $query = "SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name);
-               if ($value!="")
-                       $query .= " and value_id=" . add_metastring($value);
-               
-               if ($existing = get_data($query)) {
-                       foreach($existing as $ex)
-                               delete_metadata($ex->id);
-                       return true;
+       function canEdit() {
+               if ($entity = get_entity($this->get('entity_guid'))) {
+                       return $entity->canEditMetadata($this);
                }
                return false;
-               
        }
-       
+
        /**
-        * Create a new metadata object, or update an existing one.
+        * Save matadata object
         *
-        * @param int $entity_guid
-        * @param string $name
-        * @param string $value
-        * @param string $value_type
-        * @param int $owner_guid
-        * @param int $access_id
-        * @param bool $allow_multiple
+        * @return int the metadata object id
         */
-       function create_metadata($entity_guid, $name, $value, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false)
-       {
-               global $CONFIG;
-
-               $entity_guid = (int)$entity_guid;
-               //$name = sanitise_string(trim($name));
-               //$value = sanitise_string(trim($value));
-               $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type)));
-               $time = time();         
-               $owner_guid = (int)$owner_guid;
-               $allow_multiple = (boolean)$allow_multiple;
-               
-               if ($owner_guid==0) $owner_guid = get_loggedin_userid();
-               
-               $access_id = (int)$access_id;
-
-               $id = false;
-       
-               $existing = get_data_row("SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name) . " limit 1");
-               if (($existing) && (!$allow_multiple) && (isset($value))) 
-               { 
-                       $id = $existing->id;
-                       $result = update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id);
-                       
-                       if (!$result) return false;
-               }
-               else if (isset($value))
-               {
-                       // Support boolean types
-                       if (is_bool($value)) {
-                               if ($value)
-                                       $value = 1;
-                               else
-                                       $value = 0;
-                       }
-                       
-                       // Add the metastrings
-                       $value = add_metastring($value);
-                       if (!$value) return false;
-                       
-                       $name = add_metastring($name);
-                       if (!$name) return false;
-                       
-                       // If ok then add it
-                       $id = insert_data("INSERT into {$CONFIG->dbprefix}metadata (entity_guid, name_id, value_id, value_type, owner_guid, time_created, access_id) VALUES ($entity_guid, '$name','$value','$value_type', $owner_guid, $time, $access_id)");
-                       
-                       if ($id!==false) {
-                               $obj = get_metadata($id);
-                               if (trigger_elgg_event('create', 'metadata', $obj)) {
-                                       return true;
-                               } else {
-                                       delete_metadata($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_new('IOException:UnableToSaveNew'), get_class()));
                        }
-                       
-               } else if ($existing) {
-// TODO: Check... are you sure you meant to do this Ben? :)                    
-                       $id = $existing->id;
-                       delete_metadata($id);
-                       
+                       return $this->id;
                }
-               
-               return $id;
        }
-       
+
+       /**
+        * Delete a given metadata.
+        */
+       function delete() {
+               return delete_metadata($this->id);
+       }
+
        /**
-        * Update an item of metadata.
+        * Get a url for this item of metadata.
         *
-        * @param int $id
-        * @param string $name
-        * @param string $value
-        * @param string $value_type
-        * @param int $owner_guid
-        * @param int $access_id
+        * @return string
         */
-       function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id)
-       {
-               global $CONFIG;
+       public function getURL() {
+               return get_metadata_url($this->id);
+       }
 
-               $id = (int)$id;
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
 
-               if (!$md = get_metadata($id)) return false;     
-               if (!$md->canEdit()) return false;
+       /**
+        * 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);
+       }
+}
 
-               // If memcached then we invalidate the cache for this entry
-               static $metabyname_memcache;
-               if ((!$metabyname_memcache) && (is_memcache_available()))
-                       $metabyname_memcache = new ElggMemcache('metabyname_memcache');
-               if ($metabyname_memcache) $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}");
-               
-               //$name = sanitise_string(trim($name));
-               //$value = sanitise_string(trim($value));
-               $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type)));
-               
-               $owner_guid = (int)$owner_guid;
-               if ($owner_guid==0) $owner_guid = get_loggedin_userid();
-               
-               $access_id = (int)$access_id;
-               
-               $access = get_access_sql_suffix();
-               
-               // Support boolean types (as integers)
+/**
+ * Convert a database row to a new ElggMetadata
+ *
+ * @param stdClass $row
+ * @return stdClass or ElggMetadata
+ */
+function row_to_elggmetadata($row) {
+       if (!($row instanceof stdClass)) {
+               return $row;
+       }
+
+       return new ElggMetadata($row);
+}
+
+/**
+ * Get a specific item of metadata.
+ *
+ * @param $id int The item of metadata being retrieved.
+ */
+function get_metadata($id) {
+       global $CONFIG;
+
+       $id = (int)$id;
+       $access = get_access_sql_suffix("e");
+       $md_access = get_access_sql_suffix("m");
+
+       return row_to_elggmetadata(get_data_row("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.id=$id and $access and $md_access"));
+}
+
+/**
+ * Removes metadata on an entity with a particular name, optionally with a given value.
+ *
+ * @param int $entity_guid The entity GUID
+ * @param string $name The name of the metadata
+ * @param string $value The optional value of the item (useful for removing a single item in a multiple set)
+ * @return true|false Depending on success
+ */
+function remove_metadata($entity_guid, $name, $value = "") {
+       global $CONFIG;
+       $entity_guid = (int) $entity_guid;
+       $name = sanitise_string($name);
+       $value = sanitise_string($value);
+
+       $query = "SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name);
+       if ($value!="") {
+               $query .= " and value_id=" . add_metastring($value);
+       }
+
+       if ($existing = get_data($query)) {
+               foreach($existing as $ex) {
+                       delete_metadata($ex->id);
+               }
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ * Create a new metadata object, or update an existing one.
+ *
+ * @param int $entity_guid
+ * @param string $name
+ * @param string $value
+ * @param string $value_type
+ * @param int $owner_guid
+ * @param int $access_id
+ * @param bool $allow_multiple
+ */
+function create_metadata($entity_guid, $name, $value, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false) {
+       global $CONFIG;
+
+       $entity_guid = (int)$entity_guid;
+       //$name = sanitise_string(trim($name));
+       //$value = sanitise_string(trim($value));
+       $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type)));
+       $time = time();
+       $owner_guid = (int)$owner_guid;
+       $allow_multiple = (boolean)$allow_multiple;
+
+       if ($owner_guid==0) {
+               $owner_guid = get_loggedin_userid();
+       }
+
+       $access_id = (int)$access_id;
+
+       $id = false;
+
+       $existing = get_data_row("SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name) . " limit 1");
+       if (($existing) && (!$allow_multiple) && (isset($value))) {
+               $id = $existing->id;
+               $result = update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id);
+
+               if (!$result) {
+                       return false;
+               }
+       }
+       else if (isset($value)) {
+               // Support boolean types
                if (is_bool($value)) {
-                       if ($value)
+                       if ($value) {
                                $value = 1;
-                       else
+                       } else {
                                $value = 0;
+                       }
                }
-               
-               // Add the metastring
+
+               // Add the metastrings
                $value = add_metastring($value);
-               if (!$value) return false;
-               
+               if (!$value) {
+                       return false;
+               }
+
                $name = add_metastring($name);
-               if (!$name) return false;
+               if (!$name) {
+                       return false;
+               }
+
+               // If ok then add it
+               $id = insert_data("INSERT into {$CONFIG->dbprefix}metadata (entity_guid, name_id, value_id, value_type, owner_guid, time_created, access_id) VALUES ($entity_guid, '$name','$value','$value_type', $owner_guid, $time, $access_id)");
 
-                               // If ok then add it
-               $result = update_data("UPDATE {$CONFIG->dbprefix}metadata set value_id='$value', value_type='$value_type', access_id=$access_id, owner_guid=$owner_guid where id=$id and name_id='$name'");
-               if ($result!==false) {
+               if ($id!==false) {
                        $obj = get_metadata($id);
-                       if (trigger_elgg_event('update', 'metadata', $obj)) {
+                       if (trigger_elgg_event('create', 'metadata', $obj)) {
                                return true;
                        } else {
                                delete_metadata($id);
                        }
                }
-                       
-               return $result;
+
+       } else if ($existing) {
+               // TODO: Check... are you sure you meant to do this Ben? :)
+               $id = $existing->id;
+               delete_metadata($id);
        }
-       
-       /**
-        * This function creates metadata from an associative array of "key => value" pairs.
-        * 
-        * @param int $entity_guid
-        * @param string $name_and_values
-        * @param string $value_type
-        * @param int $owner_guid
-        * @param int $access_id
-        * @param bool $allow_multiple
-        */
-       function create_metadata_from_array($entity_guid, array $name_and_values, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false)
-       {
-               foreach ($name_and_values as $k => $v)
-                       if (!create_metadata($entity_guid, $k, $v, $value_type, $owner_guid, $access_id, $allow_multiple)) return false;
-               
-               return true;
+
+       return $id;
+}
+
+/**
+ * Update an item of metadata.
+ *
+ * @param int $id
+ * @param string $name
+ * @param string $value
+ * @param string $value_type
+ * @param int $owner_guid
+ * @param int $access_id
+ */
+function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id) {
+       global $CONFIG;
+
+       $id = (int)$id;
+
+       if (!$md = get_metadata($id)) {
+               return false;
        }
-       
-       /**
-        * Delete an item of metadata, where the current user has access.
-        * 
-        * @param $id int The item of metadata to delete.
-        */
-       function delete_metadata($id)
-       {
-               global $CONFIG;
-
-               $id = (int)$id;
-               $metadata = get_metadata($id);
-               
-               if ($metadata) {
-                       // Tidy up if memcache is enabled.
-                       static $metabyname_memcache;
-                       if ((!$metabyname_memcache) && (is_memcache_available()))
-                               $metabyname_memcache = new ElggMemcache('metabyname_memcache');
-                       if ($metabyname_memcache) $metabyname_memcache->delete("{$metadata->entity_guid}:{$metadata->name_id}");
-                       
-                       if (($metadata->canEdit()) && (trigger_elgg_event('delete', 'metadata', $metadata)))
-                               return delete_data("DELETE from {$CONFIG->dbprefix}metadata where id=$id");
-               }
-               
+       if (!$md->canEdit()) {
                return false;
        }
-       
-       /**
-        * Return the metadata values that match your query.
-        * 
-        * @param string $meta_name
-        * @return mixed either a value, an array of ElggMetadata or false.
-        */
-       function get_metadata_byname($entity_guid,  $meta_name)
-       {
-               global $CONFIG;
-       
-               $meta_name = get_metastring_id($meta_name);
-               
-               if (empty($meta_name)) return false;
-               
-               $entity_guid = (int)$entity_guid;
-               $access = get_access_sql_suffix("e");
-               $md_access = get_access_sql_suffix("m");
-               
-               // If memcache is available then cache this (cache only by name for now since this is the most common query)
-               $meta = null;
-               static $metabyname_memcache;
-               if ((!$metabyname_memcache) && (is_memcache_available()))
-                       $metabyname_memcache = new ElggMemcache('metabyname_memcache');
-               if ($metabyname_memcache) $meta = $metabyname_memcache->load("{$entity_guid}:{$meta_name}");
-               if ($meta) return $meta;        
 
-               $result = get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and m.name_id='$meta_name' and $access and $md_access", "row_to_elggmetadata");
-               if (!$result) 
-                       return false;
-                       
-               // Cache if memcache available
-               if ($metabyname_memcache)
-               { 
-                       if (count($result) == 1) $r = $result[0]; else $r = $result;
-                       $metabyname_memcache->setDefaultExpiry(3600); // This is a bit of a hack - we shorten the expiry on object metadata so that it'll be gone in an hour. This means that deletions and more importantly updates will filter through eventually.
-                       $metabyname_memcache->save("{$entity_guid}:{$meta_name}", $r);
-                       
-               }
-               if (count($result) == 1)
-                       return $result[0];
-                       
-               return $result;
+       // If memcached then we invalidate the cache for this entry
+       static $metabyname_memcache;
+       if ((!$metabyname_memcache) && (is_memcache_available())) {
+               $metabyname_memcache = new ElggMemcache('metabyname_memcache');
        }
-       
-       /**
-        * Return all the metadata for a given GUID.
-        * 
-        * @param int $entity_guid
-        */
-       function get_metadata_for_entity($entity_guid)
-       {
-               global $CONFIG;
-       
-               $entity_guid = (int)$entity_guid;
-               $access = get_access_sql_suffix("e");
-               $md_access = get_access_sql_suffix("m");
-               
-               return get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and $access and $md_access", "row_to_elggmetadata");
+
+       if ($metabyname_memcache) {
+               $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}");
        }
 
-       /**
-        * Get the metadata where the entities they are referring to match a given criteria.
-        * 
-        * @param mixed $meta_name 
-        * @param mixed $meta_value
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
-        * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        */
-       function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $entity_subtype = "", $limit = 10, $offset = 0, $order_by = "", $site_guid = 0)
-       {
-               global $CONFIG;
-               
-               $meta_n = get_metastring_id($meta_name);
-               $meta_v = get_metastring_id($meta_value);
-               
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if ($order_by == "") $order_by = "e.time_created desc";
-               $order_by = sanitise_string($order_by);
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-                       
-               $where = array();
-               
-               if ($entity_type!="")
-                       $where[] = "e.type='$entity_type'";
-               if ($entity_subtype)
-                       $where[] = "e.subtype=$entity_subtype";
-               if ($meta_name!="") {
-                       if (!$meta_v) return false; // The value is set, but we didn't get a value... so something went wrong.
-                       $where[] = "m.name_id='$meta_n'";
-               }
-               if ($meta_value!="") {
-                       if (!$meta_v) return false; // The value is set, but we didn't get a value... so something went wrong.
-                       $where[] = "m.value_id='$meta_v'";
-               }
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               
-               $query = "SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls
-               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+       //$name = sanitise_string(trim($name));
+       //$value = sanitise_string(trim($value));
+       $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type)));
 
-               return get_data($query, "row_to_elggmetadata");
+       $owner_guid = (int)$owner_guid;
+       if ($owner_guid==0) {
+               $owner_guid = get_loggedin_userid();
        }
-       
-       /**
-        * Return a list of entities based on the given search criteria.
-        * 
-        * @param mixed $meta_name 
-        * @param mixed $meta_value
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
-        * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
-        * 
-        * @return int|array A list of entities, or a count if $count is set to true
-        */
-       function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false)
-       {
-               global $CONFIG;
-               
-               $meta_n = get_metastring_id($meta_name);
-               $meta_v = get_metastring_id($meta_value);
-                       
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if ($order_by == "") 
-                       $order_by = "e.time_created desc";
-               else
-                       $order_by = "e.time_created, {$order_by}";
-               $order_by = sanitise_string($order_by);
-               $site_guid = (int) $site_guid;
-               if ((is_array($owner_guid) && (count($owner_guid)))) {
-                       foreach($owner_guid as $key => $guid) {
-                               $owner_guid[$key] = (int) $guid;
-                       }
-               } else {
-                       $owner_guid = (int) $owner_guid;
-               }
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               //$access = get_access_list();
-                       
-               $where = array();
-               
-               if ($entity_type!=="")
-                       $where[] = "e.type='$entity_type'";
-               if ($entity_subtype)
-                       $where[] = "e.subtype=$entity_subtype";
-               if ($meta_name!=="")
-                       $where[] = "m.name_id='$meta_n'";
-               if ($meta_value!=="")
-                       $where[] = "m.value_id='$meta_v'";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               if (is_array($owner_guid)) {
-                       $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
-               } else if ($owner_guid > 0)
-                       $where[] = "e.container_guid = {$owner_guid}";
-               
-               if (!$count) {
-                       $query = "SELECT distinct e.* "; 
-               } else {
-                       $query = "SELECT count(distinct e.guid) as total ";
-               }
-                       
-               $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid where";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
+
+       $access_id = (int)$access_id;
+
+       $access = get_access_sql_suffix();
+
+       // Support boolean types (as integers)
+       if (is_bool($value)) {
+               if ($value) {
+                       $value = 1;
                } else {
-                       if ($row = get_data_row($query))
-                               return $row->total;
+                       $value = 0;
                }
+       }
+
+       // Add the metastring
+       $value = add_metastring($value);
+       if (!$value) {
                return false;
        }
-       
-       /**
-        * Return a list of entities suitable for display based on the given search criteria.
-        * 
-        * @see elgg_view_entity_list
-        * 
-        * @param mixed $meta_name Metadata name to search on
-        * @param mixed $meta_value The value to match, optionally
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity
-        * @param int $limit Number of entities to display per page
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true
-        * @param true|false $pagination Display pagination? Default: true
-        * 
-        * @return string A list of entities suitable for display
-        */
-       function list_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) {
-               
-               $offset = (int) get_input('offset');
-               $limit = (int) $limit;
-               $count = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true);
-               $entities = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false);
-               
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-               
+
+       $name = add_metastring($name);
+       if (!$name) {
+               return false;
        }
 
-       /**
-        * Returns a list of entities based on the given search criteria.
-        *
-        * @param array $meta_array Array of 'name' => 'value' pairs
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
-        * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
-        * @param string $meta_array_operator Operator used for joining the metadata array together
-        * @return int|array List of ElggEntities, or the total number if count is set to false
-        */
-       function get_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false, $meta_array_operator = 'and')
-       {
-               global $CONFIG;
-               
-               if (!is_array($meta_array) || sizeof($meta_array) == 0) {
+       // If ok then add it
+       $result = update_data("UPDATE {$CONFIG->dbprefix}metadata set value_id='$value', value_type='$value_type', access_id=$access_id, owner_guid=$owner_guid where id=$id and name_id='$name'");
+       if ($result!==false) {
+               $obj = get_metadata($id);
+               if (trigger_elgg_event('update', 'metadata', $obj)) {
+                       return true;
+               } else {
+                       delete_metadata($id);
+               }
+       }
+
+       return $result;
+}
+
+/**
+ * This function creates metadata from an associative array of "key => value" pairs.
+ *
+ * @param int $entity_guid
+ * @param string $name_and_values
+ * @param string $value_type
+ * @param int $owner_guid
+ * @param int $access_id
+ * @param bool $allow_multiple
+ */
+function create_metadata_from_array($entity_guid, array $name_and_values, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false) {
+       foreach ($name_and_values as $k => $v) {
+               if (!create_metadata($entity_guid, $k, $v, $value_type, $owner_guid, $access_id, $allow_multiple)) {
                        return false;
                }
-               
-               $where = array();
-               
-               $mindex = 1;
-               $join = "";
-               $metawhere = array();
-               $meta_array_operator = sanitise_string($meta_array_operator);
-               foreach($meta_array as $meta_name => $meta_value) {
-                       $meta_n = get_metastring_id($meta_name);
-                       $meta_v = get_metastring_id($meta_value);
-                       $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid "; 
-                       /*if ($meta_name!=="")
-                               $where[] = "m{$mindex}.name_id='$meta_n'";
-                       if ($meta_value!=="")
-                               $where[] = "m{$mindex}.value_id='$meta_v'";*/
-                       $metawhere[] = "(m{$mindex}.name_id='$meta_n' AND m{$mindex}.value_id='$meta_v')";
-                       $mindex++;
+       }
+       return true;
+}
+
+/**
+ * Delete an item of metadata, where the current user has access.
+ *
+ * @param $id int The item of metadata to delete.
+ */
+function delete_metadata($id) {
+       global $CONFIG;
+
+       $id = (int)$id;
+       $metadata = get_metadata($id);
+
+       if ($metadata) {
+               // Tidy up if memcache is enabled.
+               static $metabyname_memcache;
+               if ((!$metabyname_memcache) && (is_memcache_available())) {
+                       $metabyname_memcache = new ElggMemcache('metabyname_memcache');
                }
-               $where[] = "(".implode($meta_array_operator, $metawhere).")";
-                       
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if ($order_by == "") $order_by = "e.time_created desc";
-               $order_by = sanitise_string($order_by);
-               if ((is_array($owner_guid) && (count($owner_guid)))) {
-                       foreach($owner_guid as $key => $guid) {
-                               $owner_guid[$key] = (int) $guid;
-                       }
-               } else {
-                       $owner_guid = (int) $owner_guid;
+
+               if ($metabyname_memcache) {
+                       $metabyname_memcache->delete("{$metadata->entity_guid}:{$metadata->name_id}");
                }
-               
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               //$access = get_access_list();
-               
-               if ($entity_type!="")
-                       $where[] = "e.type = '{$entity_type}'";
-               if ($entity_subtype)
-                       $where[] = "e.subtype = {$entity_subtype}";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               if (is_array($owner_guid)) {
-                       $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
-               } else if ($owner_guid > 0)
-                       $where[] = "e.container_guid = {$owner_guid}";
-               //if ($owner_guid > 0)
-               //      $where[] = "e.container_guid = {$owner_guid}";
-               
-               if ($count) {
-                       $query = "SELECT count(distinct e.guid) as total ";
+
+               if (($metadata->canEdit()) && (trigger_elgg_event('delete', 'metadata', $metadata))) {
+                       return delete_data("DELETE from {$CONFIG->dbprefix}metadata where id=$id");
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Return the metadata values that match your query.
+ *
+ * @param string $meta_name
+ * @return mixed either a value, an array of ElggMetadata or false.
+ */
+function get_metadata_byname($entity_guid,  $meta_name) {
+       global $CONFIG;
+
+       $meta_name = get_metastring_id($meta_name);
+
+       if (empty($meta_name)) {
+               return false;
+       }
+
+       $entity_guid = (int)$entity_guid;
+       $access = get_access_sql_suffix("e");
+       $md_access = get_access_sql_suffix("m");
+
+       // If memcache is available then cache this (cache only by name for now since this is the most common query)
+       $meta = null;
+       static $metabyname_memcache;
+       if ((!$metabyname_memcache) && (is_memcache_available())) {
+               $metabyname_memcache = new ElggMemcache('metabyname_memcache');
+       }
+       if ($metabyname_memcache) {
+               $meta = $metabyname_memcache->load("{$entity_guid}:{$meta_name}");
+       }
+       if ($meta) {
+               return $meta;
+       }
+
+       $result = get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and m.name_id='$meta_name' and $access and $md_access", "row_to_elggmetadata");
+       if (!$result) {
+               return false;
+       }
+
+       // Cache if memcache available
+       if ($metabyname_memcache) {
+               if (count($result) == 1) {
+                       $r = $result[0];
                } else {
-                       $query = "SELECT distinct e.* "; 
+                       $r = $result;
                }
-                       
-               $query .= " from {$CONFIG->dbprefix}entities e {$join} where";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-       
-               $mindex = 1;
-               foreach($meta_array as $meta_name => $meta_value) {
-                       $query .= ' and ' . get_access_sql_suffix("m{$mindex}"); // Add access controls
-                       $mindex++;
+               // This is a bit of a hack - we shorten the expiry on object
+               // metadata so that it'll be gone in an hour. This means that
+               // deletions and more importantly updates will filter through eventually.
+               $metabyname_memcache->setDefaultExpiry(3600);
+               $metabyname_memcache->save("{$entity_guid}:{$meta_name}", $r);
+       }
+       if (count($result) == 1) {
+               return $result[0];
+       }
+
+       return $result;
+}
+
+/**
+ * Return all the metadata for a given GUID.
+ *
+ * @param int $entity_guid
+ */
+function get_metadata_for_entity($entity_guid) {
+       global $CONFIG;
+
+       $entity_guid = (int)$entity_guid;
+       $access = get_access_sql_suffix("e");
+       $md_access = get_access_sql_suffix("m");
+
+       return get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and $access and $md_access", "row_to_elggmetadata");
+}
+
+/**
+ * Get the metadata where the entities they are referring to match a given criteria.
+ *
+ * @param mixed $meta_name
+ * @param mixed $meta_value
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ */
+function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $entity_subtype = "", $limit = 10, $offset = 0, $order_by = "", $site_guid = 0) {
+       global $CONFIG;
+
+       $meta_n = get_metastring_id($meta_name);
+       $meta_v = get_metastring_id($meta_value);
+
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+
+       $order_by = sanitise_string($order_by);
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $where = array();
+
+       if ($entity_type!="") {
+               $where[] = "e.type='$entity_type'";
+       }
+
+       if ($entity_subtype) {
+               $where[] = "e.subtype=$entity_subtype";
+       }
+
+       if ($meta_name!="") {
+               if (!$meta_v) {
+                       // The value is set, but we didn't get a value... so something went wrong.
+                       return false;
                }
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
-                       }
+               $where[] = "m.name_id='$meta_n'";
+       }
+       if ($meta_value!="") {
+               // The value is set, but we didn't get a value... so something went wrong.
+               if (!$meta_v) {
+                       return false;
                }
-               return false;
+               $where[] = "m.value_id='$meta_v'";
        }
-       
-       /**
-        * Returns a viewable list of entities based on the given search criteria.
-        *
-        * @see elgg_view_entity_list
-        * 
-        * @param array $meta_array Array of 'name' => 'value' pairs
-        * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
-        * @param string $entity_subtype The subtype of the entity.
-        * @param int $limit 
-        * @param int $offset
-        * @param string $order_by Optional ordering.
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true
-        * @param true|false $pagination Display pagination? Default: true
-        * @return string List of ElggEntities suitable for display
-        */
-       function list_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) {
-               
-               $offset = (int) get_input('offset');
-               $limit = (int) $limit;
-               $count = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, true);
-               $entities = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, false);
-       
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-               
-       }
-       
-       /**
-        * Clear all the metadata for a given entity, assuming you have access to that metadata.
-        * 
-        * @param int $guid
-        */
-       function clear_metadata($entity_guid)
-       {
-               global $CONFIG;
-               
-               $entity_guid = (int)$entity_guid;
-               if ($entity = get_entity($entity_guid)) {
-                       if ($entity->canEdit())
-                               return delete_data("DELETE from {$CONFIG->dbprefix}metadata where entity_guid={$entity_guid}");
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       $query = "SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+       $query .= get_access_sql_suffix("e"); // Add access controls
+       $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls
+       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+
+       return get_data($query, "row_to_elggmetadata");
+}
+
+/**
+ * Return a list of entities based on the given search criteria.
+ *
+ * @param mixed $meta_name
+ * @param mixed $meta_value
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+ *
+ * @return int|array A list of entities, or a count if $count is set to true
+ */
+function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) {
+       global $CONFIG;
+
+       $meta_n = get_metastring_id($meta_name);
+       $meta_v = get_metastring_id($meta_value);
+
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       } else {
+               $order_by = "e.time_created, {$order_by}";
+       }
+       $order_by = sanitise_string($order_by);
+       $site_guid = (int) $site_guid;
+       if ((is_array($owner_guid) && (count($owner_guid)))) {
+               foreach($owner_guid as $key => $guid) {
+                       $owner_guid[$key] = (int) $guid;
                }
+       } else {
+               $owner_guid = (int) $owner_guid;
+       }
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       //$access = get_access_list();
+
+       $where = array();
+
+       if ($entity_type!=="") {
+               $where[] = "e.type='$entity_type'";
+       }
+
+       if ($entity_subtype) {
+               $where[] = "e.subtype=$entity_subtype";
+       }
+       if ($meta_name!=="") {
+               $where[] = "m.name_id='$meta_n'";
+       }
+       if ($meta_value!=="") {
+               $where[] = "m.value_id='$meta_v'";
+       }
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+       if (is_array($owner_guid)) {
+               $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
+       } else if ($owner_guid > 0) {
+               $where[] = "e.container_guid = {$owner_guid}";
+       }
+
+       if (!$count) {
+               $query = "SELECT distinct e.* ";
+       } else {
+               $query = "SELECT count(distinct e.guid) as total ";
+       }
+
+       $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid where";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+       $query .= get_access_sql_suffix("e"); // Add access controls
+       $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls
+
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($row = get_data_row($query)) {
+                       return $row->total;
+               }
+       }
+       return false;
+}
+
+/**
+ * Return a list of entities suitable for display based on the given search criteria.
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param mixed $meta_name Metadata name to search on
+ * @param mixed $meta_value The value to match, optionally
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity
+ * @param int $limit Number of entities to display per page
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true
+ * @param true|false $pagination Display pagination? Default: true
+ *
+ * @return string A list of entities suitable for display
+ */
+function list_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) {
+       $offset = (int) get_input('offset');
+       $limit = (int) $limit;
+       $count = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true);
+       $entities = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Returns a list of entities based on the given search criteria.
+ *
+ * @param array $meta_array Array of 'name' => 'value' pairs
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+ * @param string $meta_array_operator Operator used for joining the metadata array together
+ * @return int|array List of ElggEntities, or the total number if count is set to false
+ */
+function get_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false, $meta_array_operator = 'and') {
+       global $CONFIG;
+
+       if (!is_array($meta_array) || sizeof($meta_array) == 0) {
                return false;
        }
-       
-       /**
-        * Clear all annotations belonging to a given owner_guid
-        *
-        * @param int $owner_guid The owner
-        */
-       function clear_metadata_by_owner($owner_guid)
-       {
-               global $CONFIG;
-               
-               $owner_guid = (int)$owner_guid;
-               
-               $metas = get_data("SELECT id from {$CONFIG->dbprefix}metadata WHERE owner_guid=$owner_guid");
-               $deleted = 0;
-               
-               foreach ($metas as $id)
-               {
-                       if (delete_metadata($id->id)) // Is this the best way?
-                               $deleted++;
+
+       $where = array();
+
+       $mindex = 1;
+       $join = "";
+       $metawhere = array();
+       $meta_array_operator = sanitise_string($meta_array_operator);
+       foreach($meta_array as $meta_name => $meta_value) {
+               $meta_n = get_metastring_id($meta_name);
+               $meta_v = get_metastring_id($meta_value);
+               $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid ";
+               /*if ($meta_name!=="")
+                       $where[] = "m{$mindex}.name_id='$meta_n'";
+               if ($meta_value!=="")
+                       $where[] = "m{$mindex}.value_id='$meta_v'";*/
+               $metawhere[] = "(m{$mindex}.name_id='$meta_n' AND m{$mindex}.value_id='$meta_v')";
+               $mindex++;
+       }
+       $where[] = "(".implode($meta_array_operator, $metawhere).")";
+
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+       $order_by = sanitise_string($order_by);
+       if ((is_array($owner_guid) && (count($owner_guid)))) {
+               foreach($owner_guid as $key => $guid) {
+                       $owner_guid[$key] = (int) $guid;
                }
-               
-               return $deleted;
+       } else {
+               $owner_guid = (int) $owner_guid;
        }
-       
-       /**
-        * Handler called by trigger_plugin_hook on the "export" event.
-        */
-       function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params)
-       {
-               // Sanity check values
-               if ((!is_array($params)) && (!isset($params['guid'])))
-                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport'));
-                       
-               if (!is_array($returnvalue))
-                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue'));
-               
-               $guid = (int)$params['guid'];
-               $name = $params['name'];        
-               
-               $result = get_metadata_for_entity($guid); 
-                               
-               if ($result)
-               {
-                       foreach ($result as $r)
-                               $returnvalue[] = $r->export();
+
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       //$access = get_access_list();
+
+       if ($entity_type!="") {
+               $where[] = "e.type = '{$entity_type}'";
+       }
+
+       if ($entity_subtype) {
+               $where[] = "e.subtype = {$entity_subtype}";
+       }
+
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       if (is_array($owner_guid)) {
+               $where[] = "e.container_guid in (".implode(",",$owner_guid).")";
+       } else if ($owner_guid > 0) {
+               $where[] = "e.container_guid = {$owner_guid}";
+       }
+
+       //if ($owner_guid > 0)
+       //      $where[] = "e.container_guid = {$owner_guid}";
+
+       if ($count) {
+               $query = "SELECT count(distinct e.guid) as total ";
+       } else {
+               $query = "SELECT distinct e.* ";
+       }
+
+       $query .= " from {$CONFIG->dbprefix}entities e {$join} where";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+       $query .= get_access_sql_suffix("e"); // Add access controls
+
+       $mindex = 1;
+       foreach($meta_array as $meta_name => $meta_value) {
+               $query .= ' and ' . get_access_sql_suffix("m{$mindex}"); // Add access controls
+               $mindex++;
+       }
+
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
                }
-               
-               return $returnvalue;
        }
-       
-       /**
-        * Takes in a comma-separated string and returns an array of tags which have been trimmed and set to lower case
-        *
-        * @param string $string Comma-separated tag string
-        * @return array|false An array of strings, or false on failure
-        */
-       function string_to_tag_array($string) {
-               
-               if (is_string($string)) {
-                       $ar = explode(",",$string);
-                       $ar = array_map('trim', $ar); // trim blank spaces
-                       $ar = array_map('elgg_strtolower', $ar); // make lower case : [Marcus Povey 20090605 - Using mb wrapper function using UTF8 safe function where available]
-                       $ar = array_filter($ar, 'is_not_null'); // Remove null values
-                       return $ar;
+       return false;
+}
+
+/**
+ * Returns a viewable list of entities based on the given search criteria.
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param array $meta_array Array of 'name' => 'value' pairs
+ * @param string $entity_type The type of entity to look for, eg 'site' or 'object'
+ * @param string $entity_subtype The subtype of the entity.
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by Optional ordering.
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true
+ * @param true|false $pagination Display pagination? Default: true
+ * @return string List of ElggEntities suitable for display
+ */
+function list_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) {
+       $offset = (int) get_input('offset');
+       $limit = (int) $limit;
+       $count = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, true);
+       $entities = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, false);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Clear all the metadata for a given entity, assuming you have access to that metadata.
+ *
+ * @param int $guid
+ */
+function clear_metadata($entity_guid) {
+       global $CONFIG;
+
+       $entity_guid = (int)$entity_guid;
+       if ($entity = get_entity($entity_guid)) {
+               if ($entity->canEdit()) {
+                       return delete_data("DELETE from {$CONFIG->dbprefix}metadata where entity_guid={$entity_guid}");
                }
-               return false;
-               
        }
-       
-       /**
-        * Takes a metadata array (which has all kinds of properties) and turns it into a simple array of strings 
-        *
-        * @param array $array Metadata array
-        * @return array Array of strings
-        */
-       function metadata_array_to_values($array) {
-               
-               $valuearray = array();
-               
-               if (is_array($array)) {
-                       foreach($array as $element) {
-                               $valuearray[] = $element->value;
-                       }
+       return false;
+}
+
+/**
+ * Clear all annotations belonging to a given owner_guid
+ *
+ * @param int $owner_guid The owner
+ */
+function clear_metadata_by_owner($owner_guid) {
+       global $CONFIG;
+
+       $owner_guid = (int)$owner_guid;
+
+       $metas = get_data("SELECT id from {$CONFIG->dbprefix}metadata WHERE owner_guid=$owner_guid");
+       $deleted = 0;
+
+       foreach ($metas as $id) {
+               // Is this the best way?
+               if (delete_metadata($id->id)) {
+                       $deleted++;
                }
-               
-               return $valuearray;
-               
        }
-       
-       /**
-        * Get the URL for this item of metadata, by default this links to the export handler in the current view.
-        *
-        * @param int $id
-        */
-       function get_metadata_url($id)
-       {
-               $id = (int)$id;
-               
-               if ($extender = get_metadata($id)) {
-                       return get_extender_url($extender);     
-               } 
-               return false;
+
+       return $deleted;
+}
+
+/**
+ * Handler called by trigger_plugin_hook on the "export" event.
+ */
+function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params) {
+       // Sanity check values
+       if ((!is_array($params)) && (!isset($params['guid']))) {
+               throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport'));
        }
-       
-       /**
-        * Mark entities with a particular type and subtype as having access permissions
-        * that can be changed independently from their parent entity
-        *
-        * @param string $type The type - object, user, etc
-        * @param string $subtype The subtype; all subtypes by default
-        */
-       function register_metadata_as_independent($type, $subtype = '*') {
-               global $CONFIG;
-               if (!isset($CONFIG->independents)) $CONFIG->independents = array();
-               $CONFIG->independents[$type][$subtype] = true;
+
+       if (!is_array($returnvalue)) {
+               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue'));
        }
-       
-       /**
-        * Determines whether entities of a given type and subtype should not change
-        * their metadata in line with their parent entity 
-        *
-        * @param string $type The type - object, user, etc
-        * @param string $subtype The entity subtype
-        * @return true|false
-        */
-       function is_metadata_independent($type, $subtype) {
-               global $CONFIG;
-               if (empty($CONFIG->independents)) return false;
-               if (!empty($CONFIG->independents[$type][$subtype])
-                       || !empty($CONFIG->independents[$type]['*'])) return true;
+
+       $guid = (int)$params['guid'];
+       $name = $params['name'];
+
+       $result = get_metadata_for_entity($guid);
+
+       if ($result) {
+               foreach ($result as $r) {
+                       $returnvalue[] = $r->export();
+               }
+       }
+
+       return $returnvalue;
+}
+
+/**
+ * Takes in a comma-separated string and returns an array of tags which have been trimmed and set to lower case
+ *
+ * @param string $string Comma-separated tag string
+ * @return array|false An array of strings, or false on failure
+ */
+function string_to_tag_array($string) {
+       if (is_string($string)) {
+               $ar = explode(",",$string);
+               $ar = array_map('trim', $ar); // trim blank spaces
+               $ar = array_map('elgg_strtolower', $ar); // make lower case : [Marcus Povey 20090605 - Using mb wrapper function using UTF8 safe function where available]
+               $ar = array_filter($ar, 'is_not_null'); // Remove null values
+               return $ar;
+       }
+       return false;
+
+}
+
+/**
+ * Takes a metadata array (which has all kinds of properties) and turns it into a simple array of strings
+ *
+ * @param array $array Metadata array
+ * @return array Array of strings
+ */
+function metadata_array_to_values($array) {
+       $valuearray = array();
+
+       if (is_array($array)) {
+               foreach($array as $element) {
+                       $valuearray[] = $element->value;
+               }
+       }
+
+       return $valuearray;
+}
+
+/**
+ * Get the URL for this item of metadata, by default this links to the export handler in the current view.
+ *
+ * @param int $id
+ */
+function get_metadata_url($id) {
+       $id = (int)$id;
+
+       if ($extender = get_metadata($id)) {
+               return get_extender_url($extender);
+       }
+       return false;
+}
+
+/**
+ * Mark entities with a particular type and subtype as having access permissions
+ * that can be changed independently from their parent entity
+ *
+ * @param string $type The type - object, user, etc
+ * @param string $subtype The subtype; all subtypes by default
+ */
+function register_metadata_as_independent($type, $subtype = '*') {
+       global $CONFIG;
+       if (!isset($CONFIG->independents)) {
+               $CONFIG->independents = array();
+       }
+       $CONFIG->independents[$type][$subtype] = true;
+}
+
+/**
+ * Determines whether entities of a given type and subtype should not change
+ * their metadata in line with their parent entity
+ *
+ * @param string $type The type - object, user, etc
+ * @param string $subtype The entity subtype
+ * @return true|false
+ */
+function is_metadata_independent($type, $subtype) {
+       global $CONFIG;
+       if (empty($CONFIG->independents)) {
                return false;
        }
-       
-       /**
-        * When an entity is updated, resets the access ID on all of its child metadata
-        *
-        * @param string $event The name of the event
-        * @param string $object_type The type of object
-        * @param ElggEntity $object The entity itself
-        */
-       function metadata_update($event, $object_type, $object) {
-               if ($object instanceof ElggEntity) {
-                       if (!is_metadata_independent($object->getType(), $object->getSubtype())) {
-                               global $CONFIG;
-                               $access_id = (int) $object->access_id;
-                               $guid = (int) $object->getGUID();
-                               update_data("update {$CONFIG->dbprefix}metadata set access_id = {$access_id} where entity_guid = {$guid}");
-                       }
-               }       
-               return true;    
+       if (!empty($CONFIG->independents[$type][$subtype])
+               || !empty($CONFIG->independents[$type]['*'])) {
+                       return true;
+               }
+       return false;
+}
+
+/**
+ * When an entity is updated, resets the access ID on all of its child metadata
+ *
+ * @param string $event The name of the event
+ * @param string $object_type The type of object
+ * @param ElggEntity $object The entity itself
+ */
+function metadata_update($event, $object_type, $object) {
+       if ($object instanceof ElggEntity) {
+               if (!is_metadata_independent($object->getType(), $object->getSubtype())) {
+                       global $CONFIG;
+                       $access_id = (int) $object->access_id;
+                       $guid = (int) $object->getGUID();
+                       update_data("update {$CONFIG->dbprefix}metadata set access_id = {$access_id} where entity_guid = {$guid}");
+               }
        }
-       
-       /**
-        * Register a metadata url handler.
-        *
-        * @param string $function_name The function.
-        * @param string $extender_name The name, default 'all'.
-        */
-       function register_metadata_url_handler($function_name, $extender_name = "all") {
-               return register_extender_url_handler($function_name, 'metadata', $extender_name);
-       }
-               
-       /** Register the hook */
-       register_plugin_hook("export", "all", "export_metadata_plugin_hook", 2);
-       /** Call a function whenever an entity is updated **/
-       register_elgg_event_handler('update','all','metadata_update');
-       
-?>
+       return true;
+}
+
+/**
+ * Register a metadata url handler.
+ *
+ * @param string $function_name The function.
+ * @param string $extender_name The name, default 'all'.
+ */
+function register_metadata_url_handler($function_name, $extender_name = "all") {
+       return register_extender_url_handler($function_name, 'metadata', $extender_name);
+}
+
+/** Register the hook */
+register_plugin_hook("export", "all", "export_metadata_plugin_hook", 2);
+/** Call a function whenever an entity is updated **/
+register_elgg_event_handler('update','all','metadata_update');
\ No newline at end of file
index 31981efab8b7add07d07058b8bf6720f6bcb51c2..519d186e4782b853abd0069d3fb1ba8baed4998a 100644 (file)
 <?php
-       /**
-        * Elgg metastrngs
-        * Functions to manage object metastrings.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd <info@elgg.com>
-        * @link http://elgg.org/
-        */
-
-       /** Cache metastrings for a page */
-       $METASTRINGS_CACHE = array();
-       
-       /** Keep a record of strings we know don't exist */
-       $METASTRINGS_DEADNAME_CACHE = array();
-
-       /**
-        * Return the meta string id for a given tag, or false.
-        * 
-        * @param string $string The value (whatever that is) to be stored
-        * @param bool $case_sensitive Do we want to make the query case sensitive?
-        * @return mixed Integer tag or false.
-        */
-       function get_metastring_id($string, $case_sensitive = true)
-       {
-               global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
-               
-               $string = sanitise_string($string);
-               $result = array_search($string, $METASTRINGS_CACHE);
-               if ($result!==false) {
-                       
-                       if (isset($CONFIG->debug) && $CONFIG->debug)
-                               error_log("** Returning id for string:$string from cache.");
-                       
-                       return $result;
-               }
-                       
-               // See if we have previously looked for this and found nothing
-               if (in_array($string, $METASTRINGS_DEADNAME_CACHE))
-                       return false;
-               
-               // Experimental memcache
-               $msfc = null;
-               static $metastrings_memcache;
-               if ((!$metastrings_memcache) && (is_memcache_available()))
-                       $metastrings_memcache = new ElggMemcache('metastrings_memcache');
-               if ($metastrings_memcache) $msfc = $metastrings_memcache->load($string);
-               if ($msfc) return $msfc;
-                       
-               // Case sensitive
-               $cs = "";
-               if ($case_sensitive) $cs = " BINARY ";
-               
-               $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where string=$cs'$string' limit 1");
-               if ($row) { 
-                       $METASTRINGS_CACHE[$row->id] = $row->string; // Cache it
-                       
-                       // Attempt to memcache it if memcache is available
-                       if ($metastrings_memcache) $metastrings_memcache->save($row->string, $row->id);
-                       
-                       if (isset($CONFIG->debug) && $CONFIG->debug)
-                               error_log("** Cacheing string '{$row->string}'");
-                               
-                       return $row->id;
+/**
+ * Elgg metastrngs
+ * Functions to manage object metastrings.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @link http://elgg.org/
+ */
+
+/** Cache metastrings for a page */
+$METASTRINGS_CACHE = array();
+
+/** Keep a record of strings we know don't exist */
+$METASTRINGS_DEADNAME_CACHE = array();
+
+/**
+ * Return the meta string id for a given tag, or false.
+ *
+ * @param string $string The value (whatever that is) to be stored
+ * @param bool $case_sensitive Do we want to make the query case sensitive?
+ * @return mixed Integer tag or false.
+ */
+function get_metastring_id($string, $case_sensitive = true) {
+       global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
+
+       $string = sanitise_string($string);
+       $result = array_search($string, $METASTRINGS_CACHE);
+       if ($result!==false) {
+               if (isset($CONFIG->debug) && $CONFIG->debug) {
+                       error_log("** Returning id for string:$string from cache.");
                }
-               else
-                       $METASTRINGS_DEADNAME_CACHE[$string] = $string;
-                       
+
+               return $result;
+       }
+
+       // See if we have previously looked for this and found nothing
+       if (in_array($string, $METASTRINGS_DEADNAME_CACHE)) {
                return false;
        }
-       
-       /**
-        * When given an ID, returns the corresponding metastring
-        *
-        * @param int $id Metastring ID
-        * @return string Metastring
-        */
-       function get_metastring($id) {
-               
-               global $CONFIG, $METASTRINGS_CACHE;
-               
-               $id = (int) $id;
-               
-               if (isset($METASTRINGS_CACHE[$id])) {
-                       
-                       if ($CONFIG->debug)
-                               error_log("** Returning string for id:$id from cache.");
-                       
-                       return $METASTRINGS_CACHE[$id];
+
+       // Experimental memcache
+       $msfc = null;
+       static $metastrings_memcache;
+       if ((!$metastrings_memcache) && (is_memcache_available())) {
+               $metastrings_memcache = new ElggMemcache('metastrings_memcache');
+       }
+       if ($metastrings_memcache) {
+               $msfc = $metastrings_memcache->load($string);
+       }
+       if ($msfc) {
+               return $msfc;
+       }
+
+       // Case sensitive
+       $cs = "";
+       if ($case_sensitive) {
+               $cs = " BINARY ";
+       }
+
+       $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where string=$cs'$string' limit 1");
+       if ($row) {
+               $METASTRINGS_CACHE[$row->id] = $row->string; // Cache it
+
+               // Attempt to memcache it if memcache is available
+               if ($metastrings_memcache) {
+                       $metastrings_memcache->save($row->string, $row->id);
                }
-               
-               $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where id='$id' limit 1");
-               if ($row) {
-                       $METASTRINGS_CACHE[$id] = $row->string; // Cache it
-                       
-                       if ($CONFIG->debug)
-                               error_log("** Cacheing string '{$row->string}'");
-                       
-                       return $row->string;
+
+               if (isset($CONFIG->debug) && $CONFIG->debug) {
+                       error_log("** Cacheing string '{$row->string}'");
                }
-                       
-               return false;
-               
+
+               return $row->id;
+       } else {
+               $METASTRINGS_DEADNAME_CACHE[$string] = $string;
+       }
+
+       return false;
+}
+
+/**
+ * When given an ID, returns the corresponding metastring
+ *
+ * @param int $id Metastring ID
+ * @return string Metastring
+ */
+function get_metastring($id) {
+       global $CONFIG, $METASTRINGS_CACHE;
+
+       $id = (int) $id;
+
+       if (isset($METASTRINGS_CACHE[$id])) {
+               if ($CONFIG->debug) {
+                       error_log("** Returning string for id:$id from cache.");
+               }
+
+               return $METASTRINGS_CACHE[$id];
        }
 
-       /**
-        * Add a metastring.
-        * It returns the id of the tag, whether by creating it or updating it.
-        * 
-        * @param string $string The value (whatever that is) to be stored
-        * @param bool $case_sensitive Do we want to make the query case sensitive?
-        * @return mixed Integer tag or false.
-        */
-       function add_metastring($string, $case_sensitive = true)
-       {
-               global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
-               
-               $sanstring = sanitise_string($string);
-               
-               $id = get_metastring_id($string, $case_sensitive);
-               if ($id) return $id;
-               
-               $result = insert_data("INSERT into {$CONFIG->dbprefix}metastrings (string) values ('$sanstring')");
-               if ($result) {
-                       $METASTRINGS_CACHE[$result] = $string;
-                       if (isset($METASTRINGS_DEADNAME_CACHE[$string])) unset($METASTRINGS_DEADNAME_CACHE[$string]);
+       $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where id='$id' limit 1");
+       if ($row) {
+               $METASTRINGS_CACHE[$id] = $row->string; // Cache it
+
+               if ($CONFIG->debug) {
+                       error_log("** Cacheing string '{$row->string}'");
                }
-                       
-               return $result;
+
+               return $row->string;
+       }
+
+       return false;
+}
+
+/**
+ * Add a metastring.
+ * It returns the id of the tag, whether by creating it or updating it.
+ *
+ * @param string $string The value (whatever that is) to be stored
+ * @param bool $case_sensitive Do we want to make the query case sensitive?
+ * @return mixed Integer tag or false.
+ */
+function add_metastring($string, $case_sensitive = true) {
+       global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
+
+       $sanstring = sanitise_string($string);
+
+       $id = get_metastring_id($string, $case_sensitive);
+       if ($id) {
+               return $id;
        }
-       
-       /**
-        * Delete any orphaned entries in metastrings. This is run by the garbage collector.
-        * 
-        */
-       function delete_orphaned_metastrings()
-       {
-               global $CONFIG;
-               
-               // If memcache is enabled then we need to flush it of deleted values
-               if (is_memcache_available())
-               {
-                       $select_query = "
-                       SELECT * 
-                       from {$CONFIG->dbprefix}metastrings where 
-                       ( 
-                               (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND 
-                               (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND 
-                               (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND 
-                               (id not in (select value_id from {$CONFIG->dbprefix}annotations))   
-                       )";
-                       
-                       $dead = get_data($select_query);
-                       if ($dead)
-                       {
-                               static $metastrings_memcache;
-                               if (!$metastrings_memcache)
-                                       $metastrings_memcache = new ElggMemcache('metastrings_memcache');
-                               foreach ($dead as $d)
-                                       $metastrings_memcache->delete($d->string);
+
+       $result = insert_data("INSERT into {$CONFIG->dbprefix}metastrings (string) values ('$sanstring')");
+       if ($result) {
+               $METASTRINGS_CACHE[$result] = $string;
+               if (isset($METASTRINGS_DEADNAME_CACHE[$string])) {
+                       unset($METASTRINGS_DEADNAME_CACHE[$string]);
+               }
+       }
+
+       return $result;
+}
+
+/**
+ * Delete any orphaned entries in metastrings. This is run by the garbage collector.
+ *
+ */
+function delete_orphaned_metastrings() {
+       global $CONFIG;
+
+       // If memcache is enabled then we need to flush it of deleted values
+       if (is_memcache_available()) {
+               $select_query = "
+               SELECT *
+               from {$CONFIG->dbprefix}metastrings where
+               (
+                       (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND
+                       (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND
+                       (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND
+                       (id not in (select value_id from {$CONFIG->dbprefix}annotations))
+               )";
+
+               $dead = get_data($select_query);
+               if ($dead) {
+                       static $metastrings_memcache;
+                       if (!$metastrings_memcache) {
+                               $metastrings_memcache = new ElggMemcache('metastrings_memcache');
+                       }
+
+                       foreach ($dead as $d) {
+                               $metastrings_memcache->delete($d->string);
                        }
                }
-               
-               $query = "
-                       DELETE 
-                       from {$CONFIG->dbprefix}metastrings where 
-                       ( 
-                               (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND 
-                               (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND 
-                               (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND 
-                               (id not in (select value_id from {$CONFIG->dbprefix}annotations))   
-                       )";
-                       
-               return delete_data($query);
        }
-       
-?>
\ No newline at end of file
+
+       $query = "
+               DELETE
+               from {$CONFIG->dbprefix}metastrings where
+               (
+                       (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND
+                       (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND
+                       (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND
+                       (id not in (select value_id from {$CONFIG->dbprefix}annotations))
+               )";
+
+       return delete_data($query);
+}
\ No newline at end of file
index d80c17ca059100b90f12a272ec54575ea1441ea0..6284e874d753ce438d6f60ae63b07a065ba609e5 100644 (file)
 <?php
-       /**
-        * Notifications
-        * This file contains classes and functions which allow plugins to register and send notifications.
-        * 
-        * There are notification methods which are provided out of the box (see notification_init() ). Each method
-        * is identified by a string, e.g. "email".
-        * 
-        * To register an event use register_notification_handler() and pass the method name and a handler function.
-        * 
-        * To send a notification call notify() passing it the method you wish to use combined with a number of method 
-        * specific addressing parameters.
-        * 
-        * Catch NotificationException to trap errors.
-        * 
-        * @package Elgg
-        * @subpackage API
-
-        * @author Curverider Ltd
-
-        * @link http://elgg.org/
-        */
-
-       /** Notification handlers */
-       $NOTIFICATION_HANDLERS = array();
-       
-       /**
-        * This function registers a handler for a given notification type (eg "email")
-        *
-        * @param string $method The method
-        * @param string $handler The handler function, in the format "handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL)". This function should return false on failure, and true/a tracking message ID on success.
-        * @param array $params A associated array of other parameters for this handler defining some properties eg. supported message length or rich text support.
-        */
-       function register_notification_handler($method, $handler, $params = NULL)
-       {
-               global $NOTIFICATION_HANDLERS;
-               
-               if (is_callable($handler)) 
-               {
-                       $NOTIFICATION_HANDLERS[$method] = new stdClass;
-
-                       $NOTIFICATION_HANDLERS[$method]->handler = $handler;
-                       if ($params)
-                       {
-                               foreach ($params as $k => $v)
-                                       $NOTIFICATION_HANDLERS[$method]->$k = $v;
+/**
+ * Notifications
+ * This file contains classes and functions which allow plugins to register and send notifications.
+ *
+ * There are notification methods which are provided out of the box (see notification_init() ). Each method
+ * is identified by a string, e.g. "email".
+ *
+ * To register an event use register_notification_handler() and pass the method name and a handler function.
+ *
+ * To send a notification call notify() passing it the method you wish to use combined with a number of method
+ * specific addressing parameters.
+ *
+ * Catch NotificationException to trap errors.
+ *
+ * @package Elgg
+ * @subpackage API
+
+ * @author Curverider Ltd
+
+ * @link http://elgg.org/
+ */
+
+/** Notification handlers */
+$NOTIFICATION_HANDLERS = array();
+
+/**
+ * This function registers a handler for a given notification type (eg "email")
+ *
+ * @param string $method The method
+ * @param string $handler The handler function, in the format "handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL)". This function should return false on failure, and true/a tracking message ID on success.
+ * @param array $params A associated array of other parameters for this handler defining some properties eg. supported message length or rich text support.
+ */
+function register_notification_handler($method, $handler, $params = NULL) {
+       global $NOTIFICATION_HANDLERS;
+
+       if (is_callable($handler)) {
+               $NOTIFICATION_HANDLERS[$method] = new stdClass;
+
+               $NOTIFICATION_HANDLERS[$method]->handler = $handler;
+               if ($params) {
+                       foreach ($params as $k => $v) {
+                               $NOTIFICATION_HANDLERS[$method]->$k = $v;
                        }
-                       
-                       return true;
                }
-               
-               return false;
+
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ * Notify a user via their preferences.
+ *
+ * @param mixed $to Either a guid or an array of guid's to notify.
+ * @param int $from GUID of the sender, which may be a user, site or object.
+ * @param string $subject Message subject.
+ * @param string $message Message body.
+ * @param array $params Misc additional parameters specific to various methods.
+ * @param mixed $methods_override A string, or an array of strings specifying the delivery methods to use - or leave blank
+ *                             for delivery using the user's chosen delivery methods.
+ * @return array Compound array of each delivery user/delivery method's success or failure.
+ * @throws NotificationException
+ */
+function notify_user($to, $from, $subject, $message, array $params = NULL, $methods_override = "") {
+       global $NOTIFICATION_HANDLERS, $CONFIG;
+
+       // Sanitise
+       if (!is_array($to)) {
+               $to = array((int)$to);
+       }
+       $from = (int)$from;
+       //$subject = sanitise_string($subject);
+
+       // Get notification methods
+       if (($methods_override) && (!is_array($methods_override))) {
+               $methods_override = array($methods_override);
        }
-       
-       /**
-        * Notify a user via their preferences.
-        *
-        * @param mixed $to Either a guid or an array of guid's to notify.
-        * @param int $from GUID of the sender, which may be a user, site or object.
-        * @param string $subject Message subject.
-        * @param string $message Message body.
-        * @param array $params Misc additional parameters specific to various methods.
-        * @param mixed $methods_override A string, or an array of strings specifying the delivery methods to use - or leave blank
-        *                              for delivery using the user's chosen delivery methods.
-        * @return array Compound array of each delivery user/delivery method's success or failure.
-        * @throws NotificationException
-        */
-       function notify_user($to, $from, $subject, $message, array $params = NULL, $methods_override = "")
-       {
-               global $NOTIFICATION_HANDLERS, $CONFIG;
-       
-               // Sanitise
-               if (!is_array($to))
-                       $to = array((int)$to);
-               $from = (int)$from;
-               //$subject = sanitise_string($subject);
-                       
-               // Get notification methods
-               if (($methods_override) && (!is_array($methods_override)))
-                       $methods_override = array($methods_override);
-                       
-               $result = array();
-               
-               foreach ($to as $guid)
-               {
-                       // Results for a user are...
-                       $result[$guid] = array();
-                       
-                       if ($guid) { // Is the guid > 0? 
-                               // Are we overriding delivery?
-                               $methods = $methods_override;
-                               if (!$methods)
-                               {
-                                       $tmp = (array)get_user_notification_settings($guid);
-                                       $methods = array(); 
-                                       foreach($tmp as $k => $v)
-                                               if ($v) $methods[] = $k; // Add method if method is turned on for user!
+
+       $result = array();
+
+       foreach ($to as $guid) {
+               // Results for a user are...
+               $result[$guid] = array();
+
+               if ($guid) { // Is the guid > 0?
+                       // Are we overriding delivery?
+                       $methods = $methods_override;
+                       if (!$methods) {
+                               $tmp = (array)get_user_notification_settings($guid);
+                               $methods = array();
+                               foreach($tmp as $k => $v) {
+                                       // Add method if method is turned on for user!
+                                       if ($v) {
+                                               $methods[] = $k;
+                                       }
                                }
-                               
-                               if ($methods)
-                               {
-                                       // Deliver
-                                       foreach ($methods as $method)
-                                       {
-                                               // Extract method details from list
-                                               $details = $NOTIFICATION_HANDLERS[$method];
-                                               $handler = $details->handler;
-                                       
-                                               if ((!$NOTIFICATION_HANDLERS[$method]) || (!$handler))
-                                                       error_log(sprintf(elgg_echo('NotificationException:NoHandlerFound'), $method));
-               
-                                               if ($CONFIG->debug)
-                                                       error_log("Sending message to $guid using $method");                                    
-                                                       
-                                               // Trigger handler and retrieve result.
-                                               try {
-                                                       $result[$guid][$method] = $handler(
-                                                               $from ? get_entity($from) : NULL,       // From entity
-                                                               get_entity($guid),                                      // To entity
-                                                               $subject,                                                       // The subject
-                                                               $message,                       // Message
-                                                               $params                                                         // Params
-                                                       );
-                                               } catch (Exception $e) {
-                                                       error_log($e->getMessage());
-                                               }
-                                               
+                       }
+
+                       if ($methods) {
+                               // Deliver
+                               foreach ($methods as $method) {
+                                       // Extract method details from list
+                                       $details = $NOTIFICATION_HANDLERS[$method];
+                                       $handler = $details->handler;
+
+                                       if ((!$NOTIFICATION_HANDLERS[$method]) || (!$handler)) {
+                                               error_log(sprintf(elgg_echo('NotificationException:NoHandlerFound'), $method));
+                                       }
+
+                                       if ($CONFIG->debug) {
+                                               error_log("Sending message to $guid using $method");
+                                       }
+
+                                       // Trigger handler and retrieve result.
+                                       try {
+                                               $result[$guid][$method] = $handler(
+                                                       $from ? get_entity($from) : NULL,       // From entity
+                                                       get_entity($guid),                                      // To entity
+                                                       $subject,                                                       // The subject
+                                                       $message,                       // Message
+                                                       $params                                                         // Params
+                                               );
+                                       } catch (Exception $e) {
+                                               error_log($e->getMessage());
                                        }
+
                                }
-                       }               
+                       }
                }
-       
-               return $result;
        }
-       
-       /**
-        * Get the notification settings for a given user.
-        *
-        * @param int $user_guid The user id
-        * @return stdClass 
-        */
-       function get_user_notification_settings($user_guid = 0)
-       {
-               $user_guid = (int)$user_guid;
-               
-               if ($user_guid == 0) $user_guid = get_loggedin_userid();
-               
-               $all_metadata = get_metadata_for_entity($user_guid);
-               if ($all_metadata)
-               {
-                       $prefix = "notification:method:";
-                       $return = new stdClass;
-                       
-                       foreach ($all_metadata as $meta)
-                       {
-                               $name = substr($meta->name, strlen($prefix));
-                               $value = $meta->value;
-                       
-                               if (strpos($meta->name, $prefix) === 0)
-                                       $return->$name = $value;
-                       }
 
-                       return $return;                 
-               }
-               
-               return false;
+       return $result;
+}
+
+/**
+ * Get the notification settings for a given user.
+ *
+ * @param int $user_guid The user id
+ * @return stdClass
+ */
+function get_user_notification_settings($user_guid = 0) {
+       $user_guid = (int)$user_guid;
+
+       if ($user_guid == 0) {
+               $user_guid = get_loggedin_userid();
        }
-       
-       /**
-        * Set a user notification pref.
-        *
-        * @param int $user_guid The user id.
-        * @param string $method The delivery method (eg. email)
-        * @param bool $value On(true) or off(false).
-        * @return bool
-        */
-       function set_user_notification_setting($user_guid, $method, $value)
-       {
-               $user_guid = (int)$user_guid;
-               $method = sanitise_string($method);
-                       
-               $user = get_entity($user_guid);
-               if (!$user) $user = get_loggedin_user();
-               
-               if (($user) && ($user instanceof ElggUser))
-               {                       
-                       $prefix = "notification:method:$method";
-                       $user->$prefix = $value;
-                       $user->save();
-               
-                       return true;
+
+       $all_metadata = get_metadata_for_entity($user_guid);
+       if ($all_metadata) {
+               $prefix = "notification:method:";
+               $return = new stdClass;
+
+               foreach ($all_metadata as $meta) {
+                       $name = substr($meta->name, strlen($prefix));
+                       $value = $meta->value;
+
+                       if (strpos($meta->name, $prefix) === 0) {
+                               $return->$name = $value;
+                       }
                }
-                       
-               return false;
+
+               return $return;
        }
-       
-       /**
-        * Notification exception.
-        * @author Curverider Ltd
-        */
-       class NotificationException extends Exception {}
-
-       
-       /**
-        * Send a notification via email.
-        *
-        * @param ElggEntity $from The from user/site/object
-        * @param ElggUser $to To which user?
-        * @param string $subject The subject of the message.
-        * @param string $message The message body
-        * @param array $params Optional parameters (none taken in this instance)
-        * @return bool
-        */
-       function email_notify_handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL)
-       {
-               global $CONFIG;
-               
-               if (!$from)
-                       throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'from'));
-                        
-               if (!$to)
-                       throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'to'));
-               
-               if ($to->email=="")
-                       throw new NotificationException(sprintf(elgg_echo('NotificationException:NoEmailAddress'), $to->guid));                 
-
-               // Sanitise subject
-               $subject = preg_replace("/(\r\n|\r|\n)/", " ", $subject); // Strip line endings
-                       
-               // To 
-               $to = $to->email;
-               
-               // From
-               $site = get_entity($CONFIG->site_guid);
-               if ((isset($from->email)) && (!($from instanceof ElggUser))) // If there's an email address, use it - but only if its not from a user.
-                       $from = $from->email;
-               else if (($site) && (isset($site->email))) // Has the current site got a from email address?
-                       $from = $site->email;
-               else if (isset($from->url)) // If we have a url then try and use that.
-               {
-                       $breakdown = parse_url($from->url);
-                       $from = 'noreply@' . $breakdown['host']; // Handle anything with a url
-               }
-               else // If all else fails, use the domain of the site.
-                       $from = 'noreply@' . get_site_domain($CONFIG->site_guid); 
-       
-               if (is_callable('mb_internal_encoding')) {
-                       mb_internal_encoding('UTF-8');
-               }
-               $site = get_entity($CONFIG->site_guid);
-               $sitename = $site->name;
-               if (is_callable('mb_encode_mimeheader')) {
-                       $sitename = mb_encode_mimeheader($site->name,"UTF-8", "B");
-               }
-               
-               $header_eol = "\r\n";
-               if ( 
-                       (isset($CONFIG->broken_mta)) &&
-                       ($CONFIG->broken_mta)
-               )
-                       $header_eol = "\n"; // Allow non-RFC 2822 mail headers to support some broken MTAs
-               
-               $from_email = "\"$sitename\" <$from>";
-               if (strtolower(substr(PHP_OS, 0 , 3)) == 'win')
-                       $from_email = "$from"; // Windows is somewhat broken, so we use a different format from header
-                       
-               $headers = "From: $from_email{$header_eol}"
-                       . "Content-Type: text/plain; charset=UTF-8; format=flowed{$header_eol}"
-               . "MIME-Version: 1.0{$header_eol}"
-               . "Content-Transfer-Encoding: 8bit{$header_eol}";
-
-       if (is_callable('mb_encode_mimeheader')) {
-                       $subject = mb_encode_mimeheader($subject,"UTF-8", "B");
-       }       
-       
-               // Format message
-               $message = html_entity_decode($message, ENT_COMPAT, 'UTF-8'); // Decode any html entities
-       $message = strip_tags($message); // Strip tags from message
-       $message = preg_replace("/(\r\n|\r)/", "\n", $message); // Convert to unix line endings in body
-       $message = preg_replace("/^From/", ">From", $message); // Change lines starting with From to >From      
-               
-               return mail($to, $subject, wordwrap($message), $headers);
+
+       return false;
+}
+
+/**
+ * Set a user notification pref.
+ *
+ * @param int $user_guid The user id.
+ * @param string $method The delivery method (eg. email)
+ * @param bool $value On(true) or off(false).
+ * @return bool
+ */
+function set_user_notification_setting($user_guid, $method, $value) {
+       $user_guid = (int)$user_guid;
+       $method = sanitise_string($method);
+
+       $user = get_entity($user_guid);
+       if (!$user) {
+               $user = get_loggedin_user();
        }
 
-       /**
-        * Correctly initialise notifications and register the email handler.
-        *
-        */
-       function notification_init()
-       {
-               // Register a notification handler for the default email method
-               register_notification_handler("email", "email_notify_handler");
-               
-               // Add settings view to user settings & register action
-               extend_elgg_settings_page('notifications/settings/usersettings', 'usersettings/user');
-               
-               register_plugin_hook('usersettings:save','user','notification_user_settings_save');
-               
-               //register_action("notifications/settings/usersettings/save");
-               
-               
-               // Register some APIs
-               expose_function('user.notification.get', 'get_user_notification_settings', array(
-                       'user_guid' => array ('type' => 'int')
-               ), elgg_echo('user.notification.get'));
-               
-               expose_function('user.notification.set', 'set_user_notification_settings', array(
-                       'user_guid' => array ('type' => 'int'),
-                       'method' => array ('type' => 'string'),
-                       'value' => array ('type' => 'bool')
-               ), elgg_echo('user.notification.set'));
-               
+       if (($user) && ($user instanceof ElggUser)) {
+               $prefix = "notification:method:$method";
+               $user->$prefix = $value;
+               $user->save();
+
+               return true;
        }
-       
-       function notification_user_settings_save() {
-               
-               global $CONFIG;
-               include($CONFIG->path . "actions/notifications/settings/usersettings/save.php");
-               
+
+       return false;
+}
+
+/**
+ * Notification exception.
+ * @author Curverider Ltd
+ */
+class NotificationException extends Exception {}
+
+
+/**
+ * Send a notification via email.
+ *
+ * @param ElggEntity $from The from user/site/object
+ * @param ElggUser $to To which user?
+ * @param string $subject The subject of the message.
+ * @param string $message The message body
+ * @param array $params Optional parameters (none taken in this instance)
+ * @return bool
+ */
+function email_notify_handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL) {
+       global $CONFIG;
+
+       if (!$from) {
+               throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'from'));
        }
-       
-       /**
-        * Register an entity type and subtype to be eligible for notifications
-        *
-        * @param string $entity_type The type of entity
-        * @param string $object_subtype Its subtype
-        * @param string $english_name It's English notification string (eg "New blog post")
-        */
-       function register_notification_object($entity_type, $object_subtype, $english_name) {
-               global $CONFIG;
-               
-               if ($entity_type == '') $entity_type = '__BLANK__';
-               if ($object_subtype == '') $object_subtype = '__BLANK__';
-               
-               if (!isset($CONFIG->register_objects)) {
-                       $CONFIG->register_objects = array();
-               }
-               if (!isset($CONFIG->register_objects[$entity_type])) {
-                       $CONFIG->register_objects[$entity_type] = array();
-               }
-               $CONFIG->register_objects[$entity_type][$object_subtype] = $english_name;
+
+       if (!$to) {
+               throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'to'));
+       }
+
+       if ($to->email=="") {
+               throw new NotificationException(sprintf(elgg_echo('NotificationException:NoEmailAddress'), $to->guid));
+       }
+
+       // Sanitise subject
+       $subject = preg_replace("/(\r\n|\r|\n)/", " ", $subject); // Strip line endings
+
+       // To
+       $to = $to->email;
+
+       // From
+       $site = get_entity($CONFIG->site_guid);
+       // If there's an email address, use it - but only if its not from a user.
+       if ((isset($from->email)) && (!($from instanceof ElggUser))) {
+               $from = $from->email;
+       } else if (($site) && (isset($site->email))) {
+               // Has the current site got a from email address?
+               $from = $site->email;
+       } else if (isset($from->url))  {
+               // If we have a url then try and use that.
+               $breakdown = parse_url($from->url);
+               $from = 'noreply@' . $breakdown['host']; // Handle anything with a url
+       } else {
+               // If all else fails, use the domain of the site.
+               $from = 'noreply@' . get_site_domain($CONFIG->site_guid);
+       }
+
+       if (is_callable('mb_internal_encoding')) {
+               mb_internal_encoding('UTF-8');
+       }
+       $site = get_entity($CONFIG->site_guid);
+       $sitename = $site->name;
+       if (is_callable('mb_encode_mimeheader')) {
+               $sitename = mb_encode_mimeheader($site->name,"UTF-8", "B");
+       }
+
+       $header_eol = "\r\n";
+       if (
+               (isset($CONFIG->broken_mta)) &&
+               ($CONFIG->broken_mta)
+       ) {
+               // Allow non-RFC 2822 mail headers to support some broken MTAs
+               $header_eol = "\n";
        }
-       
-       /**
-        * Establish a 'notify' relationship between the user and a content author
-        *
-        * @param int $user_guid The GUID of the user who wants to follow a user's content
-        * @param int $author_guid The GUID of the user whose content the user wants to follow
-        * @return true|false Depending on success
-        */
-       function register_notification_interest($user_guid, $author_guid) {
-               return add_entity_relationship($user_guid, 'notify', $author_guid);
+
+       $from_email = "\"$sitename\" <$from>";
+       if (strtolower(substr(PHP_OS, 0 , 3)) == 'win') {
+               // Windows is somewhat broken, so we use a different format from header
+               $from_email = "$from";
        }
-       
-       /**
-        * Remove a 'notify' relationship between the user and a content author
-        *
-        * @param int $user_guid The GUID of the user who is following a user's content
-        * @param int $author_guid The GUID of the user whose content the user wants to unfollow
-        * @return true|false Depending on success
-        */
-       function remove_notification_interest($user_guid, $author_guid) {
-               return remove_entity_relationship($user_guid, 'notify', $author_guid);
+
+       $headers = "From: $from_email{$header_eol}"
+               . "Content-Type: text/plain; charset=UTF-8; format=flowed{$header_eol}"
+               . "MIME-Version: 1.0{$header_eol}"
+               . "Content-Transfer-Encoding: 8bit{$header_eol}";
+
+       if (is_callable('mb_encode_mimeheader')) {
+               $subject = mb_encode_mimeheader($subject,"UTF-8", "B");
        }
-       
-       /**
-        * Automatically triggered notification on 'create' events that looks at registered
-        * objects and attempts to send notifications to anybody who's interested
-        *
-        * @see register_notification_object
-        */
-       function object_notifications($event, $object_type, $object) {
-               
-               // We only want to trigger notification events for ElggEntities
-               if ($object instanceof ElggEntity) {
-                       
-                       // Get config data
-                       global $CONFIG, $SESSION, $NOTIFICATION_HANDLERS;
-                       
-                       $hookresult = trigger_plugin_hook('object:notifications',$object_type,array(
-                                                                               'event' => $event,
-                                                                               'object_type' => $object_type,
-                                                                               'object' => $object,
-                                                                       ),false);
-                       if ($hookresult === true) return true;
-                       
-                       // Have we registered notifications for this type of entity?
-                       $object_type = $object->getType(); if (empty($object_type)) $object_type = '__BLANK__';
-                       $object_subtype = $object->getSubtype(); if (empty($object_subtype)) $object_subtype = '__BLANK__';
-                       if (isset($CONFIG->register_objects[$object_type][$object_subtype])) {
-
-                               $descr = $CONFIG->register_objects[$object_type][$object_subtype];
-                               $string = $descr . ": " . $object->getURL();
-                               
-                               // Get users interested in content from this person and notify them
-                               // (Person defined by container_guid so we can also subscribe to groups if we want)
-                               foreach($NOTIFICATION_HANDLERS as $method => $foo)
-                               if ($interested_users = get_entities_from_relationship('notify' . $method,$object->container_guid,true,'user','',0,'',99999)) {
-                                       
-                                       if (is_array($interested_users))
-                                               foreach($interested_users as $user) {
-                                                       if ($user instanceof ElggUser) {
-                                                               
-                                                               if (!$user->isBanned())
-                                                               if (($user->guid != $SESSION['user']->guid) && has_access_to_entity($object,$user)
-                                                                       && $object->access_id != ACCESS_PRIVATE) { 
-               
-                                                                                               $methodstring = trigger_plugin_hook('notify:entity:message',$object->getType(),array(
-                                                                                                       'entity' => $object,
-                                                                                                       'to_entity' => $user,
-                                                                                                       'method' => $method),$string);
-                                                                                               if (empty($methodstring) && $methodstring !== false) $methodstring = $string;
-                                                                                               if ($methodstring !== false)
-                                                                                                       notify_user($user->guid,$object->container_guid,$descr,$methodstring,NULL,array($method));
+
+       // Format message
+       $message = html_entity_decode($message, ENT_COMPAT, 'UTF-8'); // Decode any html entities
+       $message = strip_tags($message); // Strip tags from message
+       $message = preg_replace("/(\r\n|\r)/", "\n", $message); // Convert to unix line endings in body
+       $message = preg_replace("/^From/", ">From", $message); // Change lines starting with From to >From
+
+       return mail($to, $subject, wordwrap($message), $headers);
+}
+
+/**
+ * Correctly initialise notifications and register the email handler.
+ *
+ */
+function notification_init() {
+       // Register a notification handler for the default email method
+       register_notification_handler("email", "email_notify_handler");
+
+       // Add settings view to user settings & register action
+       extend_elgg_settings_page('notifications/settings/usersettings', 'usersettings/user');
+
+       register_plugin_hook('usersettings:save','user','notification_user_settings_save');
+
+       //register_action("notifications/settings/usersettings/save");
+
+       // Register some APIs
+       expose_function('user.notification.get', 'get_user_notification_settings', array(
+               'user_guid' => array ('type' => 'int')
+       ), elgg_echo('user.notification.get'));
+
+       expose_function('user.notification.set', 'set_user_notification_settings', array(
+               'user_guid' => array ('type' => 'int'),
+               'method' => array ('type' => 'string'),
+               'value' => array ('type' => 'bool')
+       ), elgg_echo('user.notification.set'));
+}
+
+function notification_user_settings_save() {
+       global $CONFIG;
+       include($CONFIG->path . "actions/notifications/settings/usersettings/save.php");
+}
+
+/**
+ * Register an entity type and subtype to be eligible for notifications
+ *
+ * @param string $entity_type The type of entity
+ * @param string $object_subtype Its subtype
+ * @param string $english_name It's English notification string (eg "New blog post")
+ */
+function register_notification_object($entity_type, $object_subtype, $english_name) {
+       global $CONFIG;
+
+       if ($entity_type == '') {
+               $entity_type = '__BLANK__';
+       }
+       if ($object_subtype == '') {
+               $object_subtype = '__BLANK__';
+       }
+
+       if (!isset($CONFIG->register_objects)) {
+               $CONFIG->register_objects = array();
+       }
+
+       if (!isset($CONFIG->register_objects[$entity_type])) {
+               $CONFIG->register_objects[$entity_type] = array();
+       }
+
+       $CONFIG->register_objects[$entity_type][$object_subtype] = $english_name;
+}
+
+/**
+ * Establish a 'notify' relationship between the user and a content author
+ *
+ * @param int $user_guid The GUID of the user who wants to follow a user's content
+ * @param int $author_guid The GUID of the user whose content the user wants to follow
+ * @return true|false Depending on success
+ */
+function register_notification_interest($user_guid, $author_guid) {
+       return add_entity_relationship($user_guid, 'notify', $author_guid);
+}
+
+/**
+ * Remove a 'notify' relationship between the user and a content author
+ *
+ * @param int $user_guid The GUID of the user who is following a user's content
+ * @param int $author_guid The GUID of the user whose content the user wants to unfollow
+ * @return true|false Depending on success
+ */
+function remove_notification_interest($user_guid, $author_guid) {
+       return remove_entity_relationship($user_guid, 'notify', $author_guid);
+}
+
+/**
+ * Automatically triggered notification on 'create' events that looks at registered
+ * objects and attempts to send notifications to anybody who's interested
+ *
+ * @see register_notification_object
+ */
+function object_notifications($event, $object_type, $object) {
+       // We only want to trigger notification events for ElggEntities
+       if ($object instanceof ElggEntity) {
+
+               // Get config data
+               global $CONFIG, $SESSION, $NOTIFICATION_HANDLERS;
+
+               $hookresult = trigger_plugin_hook('object:notifications',$object_type,array(
+                       'event' => $event,
+                       'object_type' => $object_type,
+                       'object' => $object,
+               ), false);
+               if ($hookresult === true) {
+                       return true;
+               }
+
+               // Have we registered notifications for this type of entity?
+               $object_type = $object->getType();
+               if (empty($object_type)) {
+                       $object_type = '__BLANK__';
+               }
+
+               $object_subtype = $object->getSubtype();
+               if (empty($object_subtype)) {
+                       $object_subtype = '__BLANK__';
+               }
+
+               if (isset($CONFIG->register_objects[$object_type][$object_subtype])) {
+                       $descr = $CONFIG->register_objects[$object_type][$object_subtype];
+                       $string = $descr . ": " . $object->getURL();
+
+                       // Get users interested in content from this person and notify them
+                       // (Person defined by container_guid so we can also subscribe to groups if we want)
+                       foreach($NOTIFICATION_HANDLERS as $method => $foo) {
+                               $interested_users = get_entities_from_relationship('notify' . $method,
+                                       $object->container_guid, true, 'user', '', 0, '', 99999);
+
+                               if ($interested_users && is_array($interested_users)) {
+                                       foreach($interested_users as $user) {
+                                               if ($user instanceof ElggUser && !$user->isBanned()) {
+                                                       if (($user->guid != $SESSION['user']->guid) && has_access_to_entity($object,$user)
+                                                       && $object->access_id != ACCESS_PRIVATE) {
+                                                               $methodstring = trigger_plugin_hook('notify:entity:message',$object->getType(),array(
+                                                                       'entity' => $object,
+                                                                       'to_entity' => $user,
+                                                                       'method' => $method),$string);
+                                                               if (empty($methodstring) && $methodstring !== false) {
+                                                                       $methodstring = $string;
                                                                }
-                                                       }                                               
+                                                               if ($methodstring !== false) {
+                                                                       notify_user($user->guid,$object->container_guid,$descr,$methodstring,NULL,array($method));
+                                                               }
+                                                       }
                                                }
+                                       }
                                }
-                               
                        }
-                       
                }
-               
        }
+}
 
-       // Register a startup event
-       register_elgg_event_handler('init','system','notification_init',0);
-       register_elgg_event_handler('create','object','object_notifications');
-
-?>
+// Register a startup event
+register_elgg_event_handler('init','system','notification_init',0);
+register_elgg_event_handler('create','object','object_notifications');
\ No newline at end of file
index 8d09b178b9c86dab7d8a503ac4f8059ceb092d25..a81925ce169d55f095c6380593275c6a43e36b9a 100644 (file)
 <?php
 
-       /**
-        * Elgg objects
-        * Functions to manage multiple or single objects in an Elgg install
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd
+/**
+ * Elgg objects
+ * Functions to manage multiple or single objects in an Elgg install
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-        * @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;
+       }
 
        /**
-        * ElggObject
-        * Representation of an "object" in the system.
-        * 
-        * @package Elgg
-        * @subpackage Core
+        * 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.
         */
-       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)); 
+       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)
-                               {                                       
-                                        foreach ($guid->attributes as $key => $value) 
-                                               $this->attributes[$key] = $value;
+                       }
+
+                       // Is $guid is an ElggObject? Use a copy constructor
+                       else if ($guid instanceof ElggObject) {
+                               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)) IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
+                       }
+
+                       // 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)) {
+                                       IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
                                }
-                               
-                               else
-                                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
+                       }
+
+                       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())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter
-                                               
-                       // 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);
+       /**
+        * 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;
                }
-               
-               /**
-                * Return the container GUID of this object.
-                *
-                * @return int
-                */
-               function getContainer()
-               {
-                       return $this->get('container_guid');
+
+               // Check the type
+               if ($this->attributes['type']!='object') {
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
                }
-               
-               /**
-                * 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;
+
+               // 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'] ++;
                }
-               
-               /**
-                * 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',
-                       ));
+
+               // Now put these into the attributes array as core values
+               $objarray = (array) $row;
+               foreach($objarray as $key => $value) {
+                       $this->attributes[$key] = $value;
                }
+
+               return true;
        }
 
        /**
-        * Return the object specific details of a object by a row.
-        * 
-        * @param int $guid
+        * Override the save function.
+        * @return true|false
         */
-       function get_object_entity_as_row($guid)
-       {
-               global $CONFIG;
-               
-               $guid = (int)$guid;
-               
-               /*$row = retrieve_cached_entity_row($guid);
-               if ($row)
-               {
-                       // We have already cached this object, so retrieve its value from the cache
-                       if (isset($CONFIG->debug) && $CONFIG->debug)
-                               error_log("** Retrieving sub part of GUID:$guid from cache");
-                               
-                       return $row;
+       public function save() {
+               // Save generic stuff
+               if (!parent::save()) {
+                       return false;
                }
-               else
-               {*/
-                       // Object not cached, load it.
-                       if ($CONFIG->debug)
-                               error_log("** Sub part of GUID:$guid loaded from DB");
-               
-                       return get_data_row("SELECT * from {$CONFIG->dbprefix}objects_entity where guid=$guid");
-               //}
+
+               // Now save specific stuff
+               return create_object_entity($this->get('guid'), $this->get('title'), $this->get('description'), $this->get('container_guid'));
        }
-       
+
        /**
-        * Create or update the extras table for a given object.
-        * Call create_entity first.
-        * 
-        * @param int $guid The guid of the entity you're creating (as obtained by create_entity)
-        * @param string $title The title of the object
-        * @param string $description The object's description
+        * 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 create_object_entity($guid, $title, $description)
-       {
-               global $CONFIG;
-               
-               $guid = (int)$guid;
-               $title = sanitise_string($title);
-               $description = sanitise_string($description);
-               
-               $row = get_entity_as_row($guid);
-               
-               if ($row)
-               {
-                       // Core entities row exists and we have access to it
-                       if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}objects_entity where guid = {$guid}")) {
-                               $result = update_data("UPDATE {$CONFIG->dbprefix}objects_entity set title='$title', description='$description' where guid=$guid");
-                               if ($result!=false)
-                               {
-                                       // Update succeeded, continue
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('update',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete();
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               
-                               // Update failed, attempt an insert.
-                               $result = insert_data("INSERT into {$CONFIG->dbprefix}objects_entity (guid, title, description) values ($guid, '$title','$description')");
-                               if ($result!==false) {
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('create',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete();
-                                               //delete_entity($guid);
-                                       }
-                               }
-                       }
-                       
-               }
-               
-               return false;
+       function getSites($subtype="", $limit = 10, $offset = 0) {
+               return get_site_objects($this->getGUID(), $subtype, $limit, $offset);
        }
-       
+
        /**
-        * THIS FUNCTION IS DEPRECATED.
-        * 
-        * Delete a object's extra data.
-        * 
-        * @param int $guid
+        * Add this object to a particular site
+        *
+        * @param int $site_guid The guid of the site to add it to
+        * @return true|false
         */
-       function delete_object_entity($guid)
-       {
-               system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
-               
-               return 1; // Always return that we have deleted one row in order to not break existing code.
+       function addToSite($site_guid) {
+               return add_site_object($this->getGUID(), $site_guid);
        }
-       
+
        /**
-        * Searches for an object based on a complete or partial title or description using full text searching.
-        * 
-        * IMPORTANT NOTE: With MySQL's default setup:
-        * 1) $criteria must be 4 or more characters long
-        * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED!
+        * Set the container for this object.
         *
-        * @param string $criteria The partial or full name or username.
-        * @param int $limit Limit of the search.
-        * @param int $offset Offset.
-        * @param string $order_by The order.
-        * @param boolean $count Whether to return the count of results or just the results.
+        * @param int $container_guid The ID of the container.
+        * @return bool
         */
-       function search_for_object($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false)
-       {
-               global $CONFIG;
-               
-               $criteria = sanitise_string($criteria);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $order_by = sanitise_string($order_by);
+       function setContainer($container_guid) {
                $container_guid = (int)$container_guid;
-               
-               $access = get_access_sql_suffix("e");
-               
-               if ($order_by == "") $order_by = "e.time_created desc";
-               
-               if ($count) {
-                       $query = "SELECT count(e.guid) as total ";
-               } else {
-                       $query = "SELECT e.* "; 
-               }
-               $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where match(o.title,o.description) against ('$criteria') and $access";
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
-                       }
+
+               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 sites this object is part of
+        * Get the collections associated with a object.
         *
-        * @param int $object_guid The object's GUID
-        * @param int $limit Number of results to return
+        * @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 false|array On success, an array of ElggSites
+        * @return unknown
         */
-       function get_object_sites($object_guid, $limit = 10, $offset = 0) {
-               $object_guid = (int)$object_guid;
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               
-               return get_entities_from_relationship("member_of_site", $object_guid, false, "site", "", 0, "time_created desc", $limit, $offset);
+       //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',
+               ));
+       }
+}
+
+/**
+ * Return the object specific details of a object by a row.
+ *
+ * @param int $guid
+ */
+function get_object_entity_as_row($guid) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+
+       /*$row = retrieve_cached_entity_row($guid);
+       if ($row)
+       {
+               // We have already cached this object, so retrieve its value from the cache
+               if (isset($CONFIG->debug) && $CONFIG->debug)
+                       error_log("** Retrieving sub part of GUID:$guid from cache");
+
+               return $row;
+       }
+       else
+       {*/
+               // Object not cached, load it.
+               if ($CONFIG->debug) {
+                       error_log("** Sub part of GUID:$guid loaded from DB");
+               }
+
+               return get_data_row("SELECT * from {$CONFIG->dbprefix}objects_entity where guid=$guid");
+       //}
+}
+
+/**
+ * Create or update the extras table for a given object.
+ * Call create_entity first.
+ *
+ * @param int $guid The guid of the entity you're creating (as obtained by create_entity)
+ * @param string $title The title of the object
+ * @param string $description The object's description
+ */
+function create_object_entity($guid, $title, $description) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+       $title = sanitise_string($title);
+       $description = sanitise_string($description);
+
+       $row = get_entity_as_row($guid);
+
+       if ($row) {
+               // Core entities row exists and we have access to it
+               if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}objects_entity where guid = {$guid}")) {
+                       $result = update_data("UPDATE {$CONFIG->dbprefix}objects_entity set title='$title', description='$description' where guid=$guid");
+                       if ($result!=false) {
+                               // Update succeeded, continue
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('update',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete();
+                               }
+                       }
+               } else {
+                       // Update failed, attempt an insert.
+                       $result = insert_data("INSERT into {$CONFIG->dbprefix}objects_entity (guid, title, description) values ($guid, '$title','$description')");
+                       if ($result!==false) {
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('create',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete();
+                                       //delete_entity($guid);
+                               }
+                       }
+               }
        }
 
+       return false;
+}
+
+/**
+ * THIS FUNCTION IS DEPRECATED.
+ *
+ * Delete a object's extra data.
+ *
+ * @param int $guid
+ */
+function delete_object_entity($guid) {
+       system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
+
+       return 1; // Always return that we have deleted one row in order to not break existing code.
+}
+
+/**
+ * Searches for an object based on a complete or partial title or description using full text searching.
+ *
+ * IMPORTANT NOTE: With MySQL's default setup:
+ * 1) $criteria must be 4 or more characters long
+ * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED!
+ *
+ * @param string $criteria The partial or full name or username.
+ * @param int $limit Limit of the search.
+ * @param int $offset Offset.
+ * @param string $order_by The order.
+ * @param boolean $count Whether to return the count of results or just the results.
+ */
+function search_for_object($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) {
+       global $CONFIG;
+
+       $criteria = sanitise_string($criteria);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $order_by = sanitise_string($order_by);
+       $container_guid = (int)$container_guid;
+
+       $access = get_access_sql_suffix("e");
+
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+
+       if ($count) {
+               $query = "SELECT count(e.guid) as total ";
+       } else {
+               $query = "SELECT e.* ";
+       }
+       $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where match(o.title,o.description) against ('$criteria') and $access";
+
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+       return false;
+}
+
+/**
+ * Get the sites this object is part of
+ *
+ * @param int $object_guid The object's GUID
+ * @param int $limit Number of results to return
+ * @param int $offset Any indexing offset
+ * @return false|array On success, an array of ElggSites
+ */
+function get_object_sites($object_guid, $limit = 10, $offset = 0) {
+       $object_guid = (int)$object_guid;
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+
+       return get_entities_from_relationship("member_of_site", $object_guid, false, "site", "", 0, "time_created desc", $limit, $offset);
+}
+
 /**
  * Runs unit tests for ElggObject
  */
 register_plugin_hook('unit_test', 'system', 'objects_test');
+
 function objects_test($hook, $type, $value, $params) {
        global $CONFIG;
        $value[] = "{$CONFIG->path}engine/tests/objects/objects.php";
        return $value;
-}
+}
\ No newline at end of file
index 4917120fd0d9f14e5980c188a01c3eaa8100223d..16d5b4671de1b621163ad6cebacd7e8f6bad1639 100644 (file)
 <?php
+/**
+ * OpenDD PHP Library.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @version 0.4
+ * @link http://elgg.org/
+ */
+
+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 {
        /**
-        * OpenDD PHP Library.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
-        * @version 0.4
-        * @link http://elgg.org/
+        * ODD Version
+        *
+        * @var string
         */
-       
-       include_once("xml.php");
-       
+       private $ODDSupportedVersion = "1.0";
+
        /**
-        * @class ODDDocument ODD Document container.
-        * This class is used during import and export to construct.
-        * @author Curverider Ltd
+        * Elements of the document.
         */
-       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";     
+       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);
                        }
-                               
-                       return $xml;
+               } else {
+                       $this->elements = array();
                }
-               
-               // 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
+        * Return the version of ODD being used.
+        *
+        * @return string
         */
-       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);
+       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;
                }
-               
-               /**
-                * 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";  
+       }
+
+       public function addElements(array $elements) {
+               foreach ($elements as $element) {
+                       $this->addElement($element);
                }
-               
        }
-       
+
+       public function getElements() {
+               return $this->elements;
+       }
+
        /**
-        * ODD Entity class.
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
+        * Set an optional wrapper factory to optionally embed the ODD document in another format.
         */
-       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"; }
+       public function setWrapperFactory(ODDWrapperFactory $factory) {
+               $this->wrapperfactory = $factory;
        }
-       
+
        /**
-        * ODD Metadata class.
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
+        * Magic function to generate valid ODD XML for this item.
         */
-       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);
+       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";
                }
-               
-               protected function getTagName() { return "metadata"; }
+
+               return $xml;
        }
-       
-       /**
-        * ODD Relationship class.
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
+
+       // 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
         */
-       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"; }
+
+       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 {
        /**
-        * Attempt to construct an ODD object out of a XmlElement or sub-elements.
-        * 
-        * @param XmlElement $element The element(s)
-        * @return mixed An ODD object if the element can be handled, or false.
+        * Attributes.
         */
-       function ODD_factory(XmlElement $element)
-       {
-               $name = $element->name; 
-               $odd = false;
-               
-               switch ($name)
-               {
-                       case 'entity' : $odd = new ODDEntity("","",""); break;
-                       case 'metadata' : $odd = new ODDMetaData("","","",""); break;
-                       case 'relationship' : $odd = new ODDRelationship("","",""); break;
-               }
-               
-               // Now populate values
-               if ($odd)
-               {
-                       // Attributes
-                       foreach ($element->attributes as $k => $v)
-                               $odd->setAttribute($k,$v);
-                               
-                       // Body
-                       $body = $element->content;
-                       $a = stripos($body, "<![CDATA");
-                       $b = strripos($body, "]]>");
-                       if (($body) && ($a!==false) && ($b!==false))
-                               $body = substr($body, $a+8, $b-($a+8));
-                       
-                       $odd->setBody($body);
+       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 $odd;
+
+               return NULL;
+       }
+
+       public function setBody($value) {
+               $this->body = $value;
        }
-       
+
+       public function getBody() {
+               return $this->body;
+       }
+
        /**
-        * Import an ODD document.
-        * 
-        * @param string $xml The XML ODD.
-        * @return ODDDocument
+        * Set the published time.
+        *
+        * @param int $time Unix timestamp
         */
-       function ODD_Import($xml)
-       {               
-               // Parse XML to an array
-               $elements = xml_2_object($xml);
-               
-               // Sanity check 1, was this actually XML?
-               if ((!$elements) || (!$elements->children))
-                       return false;
-
-               // Create ODDDocument
-               $document = new ODDDocument();
-               
-               // Itterate through array of elements and construct ODD document
-               $cnt = 0;
-
-               foreach ($elements->children as $child) 
-               {
-                       $odd = ODD_factory($child);
-                       
-                       if ($odd) { 
-                               $document->addElement($odd);
-                               $cnt++;
-                       }
-               }
-               
-               // Check that we actually found something
-               if ($cnt == 0)
-                       return false;
-               
-               return $document;
+       public function setPublished($time) {
+               $this->attributes['published'] = date("r", $time);
        }
-       
+
        /**
-        * Export an ODD Document.
+        * Return the published time as a unix timestamp.
         *
-        * @param ODDDocument $document The Document.
-        * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats.
+        * @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
         */
-       function ODD_Export(ODDDocument $document)
-       {
-               return "$document";
+       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);
        }
-       
-?>
\ No newline at end of file
+
+       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"; }
+}
+
+/**
+ * Attempt to construct an ODD object out of a XmlElement or sub-elements.
+ *
+ * @param XmlElement $element The element(s)
+ * @return mixed An ODD object if the element can be handled, or false.
+ */
+function ODD_factory(XmlElement $element) {
+       $name = $element->name;
+       $odd = false;
+
+       switch ($name) {
+               case 'entity' :
+                       $odd = new ODDEntity("","","");
+                       break;
+               case 'metadata' :
+                       $odd = new ODDMetaData("","","","");
+                       break;
+               case 'relationship' :
+                       $odd = new ODDRelationship("","","");
+                       break;
+       }
+
+       // Now populate values
+       if ($odd) {
+               // Attributes
+               foreach ($element->attributes as $k => $v) {
+                       $odd->setAttribute($k,$v);
+               }
+
+               // Body
+               $body = $element->content;
+               $a = stripos($body, "<![CDATA");
+               $b = strripos($body, "]]>");
+               if (($body) && ($a!==false) && ($b!==false)) {
+                       $body = substr($body, $a+8, $b-($a+8));
+               }
+
+               $odd->setBody($body);
+       }
+
+       return $odd;
+}
+
+/**
+ * Import an ODD document.
+ *
+ * @param string $xml The XML ODD.
+ * @return ODDDocument
+ */
+function ODD_Import($xml) {
+       // Parse XML to an array
+       $elements = xml_2_object($xml);
+
+       // Sanity check 1, was this actually XML?
+       if ((!$elements) || (!$elements->children)) {
+               return false;
+       }
+
+       // Create ODDDocument
+       $document = new ODDDocument();
+
+       // Itterate through array of elements and construct ODD document
+       $cnt = 0;
+
+       foreach ($elements->children as $child) {
+               $odd = ODD_factory($child);
+
+               if ($odd) {
+                       $document->addElement($odd);
+                       $cnt++;
+               }
+       }
+
+       // Check that we actually found something
+       if ($cnt == 0) {
+               return false;
+       }
+
+       return $document;
+}
+
+/**
+ * Export an ODD Document.
+ *
+ * @param ODDDocument $document The Document.
+ * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats.
+ */
+function ODD_Export(ODDDocument $document) {
+       return "$document";
+}
\ No newline at end of file
index e602590b35596436792916ac55ed715bc98d0804..528be81de2bc6d5ee40ee245ca763b002af7ce06 100644 (file)
 <?php
+/**
+ * Elgg page handler functions
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Elgg page handler functions
-        * 
-        * @package Elgg
-        * @subpackage Core
+/**
+ * Turns the current page over to the page handler, allowing registered handlers to take over
+ *
+ * @param string $handler The name of the handler type (eg 'blog')
+ * @param array $page The parameters to the page, as an array (exploded by '/' slashes)
+ * @return true|false Depending on whether a registered page handler was found
+ */
+function page_handler($handler, $page) {
+       global $CONFIG;
 
-        * @author Curverider Ltd
+       set_context($handler);
 
-        * @link http://elgg.org/
-        */
-
-       /**
-        * Turns the current page over to the page handler, allowing registered handlers to take over
-        *
-        * @param string $handler The name of the handler type (eg 'blog')
-        * @param array $page The parameters to the page, as an array (exploded by '/' slashes)
-        * @return true|false Depending on whether a registered page handler was found
-        */
-       function page_handler($handler, $page) {
-               
-               global $CONFIG;
-               
-               set_context($handler);
-               
-               $query = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], '?')+1);//parse_url($_SERVER['REQUEST_URI']);
-               if (isset($query)) {
-                       parse_str($query, $query_arr);
-                       if (is_array($query_arr)) {
-                               foreach($query_arr as $name => $val) {
-                                       set_input($name, $val);
-                               }
-                       }
-               } 
-               $page = explode('/',$page);
-               
-               if (!isset($CONFIG->pagehandler) || empty($handler)) {
-                       $result = false;
-               } else if (isset($CONFIG->pagehandler[$handler]) && is_callable($CONFIG->pagehandler[$handler])) {
-                       $function = $CONFIG->pagehandler[$handler];
-                       $result = $function($page, $handler);
-                       if ($result !== false) {
-                               $result = true;
+       //parse_url($_SERVER['REQUEST_URI']);
+       $query = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], '?') + 1);
+       if (isset($query)) {
+               parse_str($query, $query_arr);
+               if (is_array($query_arr)) {
+                       foreach($query_arr as $name => $val) {
+                               set_input($name, $val);
                        }
-               } else {
-                       $result = false;
                }
-               
-               if (!$result) {
-                       $result = default_page_handler($page, $handler);
+       }
+       $page = explode('/',$page);
+
+       if (!isset($CONFIG->pagehandler) || empty($handler)) {
+               $result = false;
+       } else if (isset($CONFIG->pagehandler[$handler]) && is_callable($CONFIG->pagehandler[$handler])) {
+               $function = $CONFIG->pagehandler[$handler];
+               $result = $function($page, $handler);
+               if ($result !== false) {
+                       $result = true;
                }
-               if ($result !== false) $result = true;          
-               
-               return $result;
-               
+       } else {
+               $result = false;
        }
-       
-       /**
-        * Registers a page handler for a particular identifier
-        * 
-        * eg, you can register a function called 'blog_page_handler' for handler type 'blog'
-        * 
-        * Now for all URLs of type http://yoururl/blog/*, the blog_page_handler function will be called.
-        * The part of the URL marked with * above will be exploded on '/' characters and passed as an
-        * array to that function, eg:
-        * 
-        * For the URL http://yoururl/blog/username/friends/:
-        * blog_page_handler('blog', array('username','friends')); 
-        *
-        * @param string $handler The page type to handle
-        * @param string $function Your function name
-        * @return true|false Depending on success
-        */
-       function register_page_handler($handler, $function) {
-               
-               global $CONFIG;
-               if (!isset($CONFIG->pagehandler))
-                       $CONFIG->pagehandler = array();
-               if (is_callable($function)) {
-                       $CONFIG->pagehandler[$handler] = $function;
-                       return true;
-               } 
-               return false;
-               
+
+       if (!$result) {
+               $result = default_page_handler($page, $handler);
+       }
+       if ($result !== false) {
+               $result = true;
        }
-       
-       /**
-        * A default page handler that attempts to load the actual file at a given page handler location
-        *
-        * @param array $page The page URL elements
-        * @param string $handler The base handler
-        * @return true|false Depending on success
-        */
-       function default_page_handler($page, $handler) {
-               
-               global $CONFIG;
-               $script = "";
-               
-               $page = implode('/',$page);
-               if (($questionmark = strripos($page, '?')))
-                       $page = substr($page, 0, $questionmark);
 
-               $script = str_replace("..","",$script);
-               $callpath = $CONFIG->path . $handler . "/" . $page;
-               if (!file_exists($callpath) || is_dir($callpath) || substr_count($callpath,'.php') == 0) {
-                               if (substr($callpath,strlen($callpath) - 1, 1) != "/")
-                                       $callpath .= "/";
-                               $callpath .= "index.php";
-                               if (!include($callpath))
-                                       return false; 
-               } else {
-                        include($callpath);
-               }
-               
+       return $result;
+}
+
+/**
+ * Registers a page handler for a particular identifier
+ *
+ * eg, you can register a function called 'blog_page_handler' for handler type 'blog'
+ *
+ * Now for all URLs of type http://yoururl/blog/*, the blog_page_handler function will be called.
+ * The part of the URL marked with * above will be exploded on '/' characters and passed as an
+ * array to that function, eg:
+ *
+ * For the URL http://yoururl/blog/username/friends/:
+ * blog_page_handler('blog', array('username','friends'));
+ *
+ * @param string $handler The page type to handle
+ * @param string $function Your function name
+ * @return true|false Depending on success
+ */
+function register_page_handler($handler, $function) {
+       global $CONFIG;
+       if (!isset($CONFIG->pagehandler)) {
+               $CONFIG->pagehandler = array();
+       }
+       if (is_callable($function)) {
+               $CONFIG->pagehandler[$handler] = $function;
                return true;
-               
        }
 
-?>
\ No newline at end of file
+       return false;
+}
+
+/**
+ * A default page handler that attempts to load the actual file at a given page handler location
+ *
+ * @param array $page The page URL elements
+ * @param string $handler The base handler
+ * @return true|false Depending on success
+ */
+function default_page_handler($page, $handler) {
+       global $CONFIG;
+       $script = "";
+
+       $page = implode('/',$page);
+       if (($questionmark = strripos($page, '?'))) {
+               $page = substr($page, 0, $questionmark);
+       }
+       $script = str_replace("..","",$script);
+       $callpath = $CONFIG->path . $handler . "/" . $page;
+       if (!file_exists($callpath) || is_dir($callpath) || substr_count($callpath,'.php') == 0) {
+                       if (substr($callpath,strlen($callpath) - 1, 1) != "/") {
+                               $callpath .= "/";
+                       }
+                       $callpath .= "index.php";
+                       if (!include($callpath)) {
+                               return false;
+                       }
+       } else {
+               include($callpath);
+       }
+
+       return true;
+}
\ No newline at end of file
index cc3e2e8a3a708d57ee224862dd1dae8b8024858a..825b41d37df839d22a3332207e8002a3ae4556ab 100644 (file)
 <?php
+/**
+ * Elgg page owner library
+ * Contains functions for managing page ownership
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-    /**
-        * Elgg page owner library
-        * Contains functions for managing page ownership
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd
-
-        * @link http://elgg.org/
-        */
-
-    /**
-     * Gets the page owner for the current page.
-     * @uses $CONFIG
-     * @return int|false The current page owner guid (0 if none).
-     */
-
-        function page_owner() {
-
-            global $CONFIG;
-            
-            $returnval = NULL;
-            
-            $setpageowner = set_page_owner();
-            if ($setpageowner !== false) {
-               return $setpageowner;
-            }
-            
-               if ((!isset($returnval)) && ($username = get_input("username"))) {
-                       if (substr_count($username,'group:')) {
-                       preg_match('/group\:([0-9]+)/i',$username,$matches);
-                       $guid = $matches[1];
-                       if ($entity = get_entity($guid)) {
-                               $returnval = $entity->getGUID();
-                       }
-                   }
-                   if ((!isset($returnval)) && ($user = get_user_by_username($username))) {
-                       $returnval = $user->getGUID();
-                   }
-               }
-               
-               
-               if ((!isset($returnval)) && ($owner = get_input("owner_guid"))) {
-                   if ($user = get_entity($owner)) {
-                       $returnval = $user->getGUID();
-                   }
-               }
-               
-               
-            if ((!isset($returnval)) && (!empty($CONFIG->page_owner_handlers) && is_array($CONFIG->page_owner_handlers))) {
-                foreach($CONFIG->page_owner_handlers as $handler) {
-                    if ((!isset($returnval)) && ($guid = $handler())) {
-                        $returnval = $guid;
-                    }
-                }
-            }
-            
-            if (isset($returnval)) {
-               
-               // Check if this is obtainable, forwarding if not.
-               /*
-                * If the owner entity has been set, but is inaccessible then we forward to the dashboard. This
-                * catches a bunch of WSoDs. It doesn't have much of a performance hit since 99.999% of the time the next thing
-                * a page does after calling this function is to retrieve the owner entity - which is of course cashed.
-                */
-               $owner_entity = get_entity($returnval);
-               if (!$owner_entity) {
-                       
-                       // Log an error
-                       error_log(sprintf(elgg_echo('pageownerunavailable'), $returnval));
-                       
-                       // Forward
-                       forward(); 
-               }
-               
-               return $returnval;
-            }
-            
-            return 0;
-            
-        }
-        
-       /**
-     * Gets the page owner for the current page.
-     * @uses $CONFIG
-     * @return ElggUser|false The current page owner (false if none).
-     */
-               function page_owner_entity() {
-
-            global $CONFIG;
-               $page_owner = page_owner();
-               if ($page_owner > 0)
-                       return get_entity($page_owner);
-                       
-                       return false;
-            //return new ElggDummy();
-        }
-        
-    /**
-     * Adds a page owner handler - a function that will
-     * return the page owner if required
-     * (Such functions are required to return false if they don't know)
-     * @uses $CONFIG
-     * @param string $functionname The name of the function to call
-     * @return mixed The guid of the owner or false
-     */
-
-        function add_page_owner_handler($functionname) {
-            
-            global $CONFIG;
-            if (empty($CONFIG->page_owner_handlers)) {
-                $CONFIG->page_owner_handlers = array();
-            }
-            if (is_callable($functionname)) {
-                $CONFIG->page_owner_handlers[] = $functionname;
-            }
-            
-        }
-        
-       /**
-        * Allows a page to manually set a page owner
-        *
-        * @param int $entitytoset The GUID of the page owner
-        * @return int|false Either the page owner we've just set, or false if unset
-        */
-        function set_page_owner($entitytoset = -1) {
-               
-               static $entity;
-               
-               if (!isset($entity)) $entity = false;
-               
-               if ($entitytoset > -1) {
-                       $entity = $entitytoset;
-               }
-               
-               return $entity;
-               
-        }
-        
-       /**
-        * Sets the functional context of a page
-        *
-        * @param string $context The context of the page
-        * @return string|false Either the context string, or false on failure
-        */
-        function set_context($context) {
-               
-               global $CONFIG;
-               if (!empty($context)) {
-                       $context = trim($context);
-                       $context = strtolower($context);
-                       $CONFIG->context = $context;
-                       return $context;
-               } else {
-                       return false;
-               }
-                       
-        }
-        
-       /**
-        * Returns the functional context of a page
-        *
-        * @return string The context, or 'main' if no context has been provided
-        */
-        function get_context() {
-               
-               global $CONFIG;
-               if (isset($CONFIG->context) && !empty($CONFIG->context)) {
-                       return $CONFIG->context;
-               }
-               if ($context = get_plugin_name(true)) {
-                       return $context;
-               }
-               return "main";
-               
-        }
-        
-        if (defined('context')) {
-               global $CONFIG;
-               $CONFIG->context = context;
-        }
-        
-?>
\ No newline at end of file
+/**
+ * Gets the page owner for the current page.
+ * @uses $CONFIG
+ * @return int|false The current page owner guid (0 if none).
+ */
+
+function page_owner() {
+       global $CONFIG;
+
+       $returnval = NULL;
+
+       $setpageowner = set_page_owner();
+       if ($setpageowner !== false) {
+               return $setpageowner;
+       }
+
+       if ((!isset($returnval)) && ($username = get_input("username"))) {
+               if (substr_count($username,'group:')) {
+                       preg_match('/group\:([0-9]+)/i',$username,$matches);
+                       $guid = $matches[1];
+                       if ($entity = get_entity($guid)) {
+                               $returnval = $entity->getGUID();
+                       }
+               }
+               if ((!isset($returnval)) && ($user = get_user_by_username($username))) {
+                       $returnval = $user->getGUID();
+               }
+       }
+
+
+       if ((!isset($returnval)) && ($owner = get_input("owner_guid"))) {
+               if ($user = get_entity($owner)) {
+                       $returnval = $user->getGUID();
+               }
+       }
+
+
+       if ((!isset($returnval)) && (!empty($CONFIG->page_owner_handlers) && is_array($CONFIG->page_owner_handlers))) {
+               foreach($CONFIG->page_owner_handlers as $handler) {
+                       if ((!isset($returnval)) && ($guid = $handler())) {
+                               $returnval = $guid;
+                       }
+               }
+       }
+
+       if (isset($returnval)) {
+               // Check if this is obtainable, forwarding if not.
+               /*
+                * If the owner entity has been set, but is inaccessible then we forward to the dashboard. This
+                * catches a bunch of WSoDs. It doesn't have much of a performance hit since 99.999% of the time the next thing
+                * a page does after calling this function is to retrieve the owner entity - which is of course cashed.
+                */
+               $owner_entity = get_entity($returnval);
+               if (!$owner_entity) {
+
+                       // Log an error
+                       error_log(sprintf(elgg_echo('pageownerunavailable'), $returnval));
+
+                       // Forward
+                       forward();
+               }
+
+               return $returnval;
+       }
+
+       return 0;
+}
+
+/**
+ * Gets the page owner for the current page.
+ * @uses $CONFIG
+ * @return ElggUser|false The current page owner (false if none).
+ */
+function page_owner_entity() {
+       global $CONFIG;
+       $page_owner = page_owner();
+       if ($page_owner > 0) {
+               return get_entity($page_owner);
+       }
+
+       return false;
+}
+
+/**
+ * Adds a page owner handler - a function that will
+ * return the page owner if required
+ * (Such functions are required to return false if they don't know)
+ * @uses $CONFIG
+ * @param string $functionname The name of the function to call
+ * @return mixed The guid of the owner or false
+ */
+
+function add_page_owner_handler($functionname) {
+       global $CONFIG;
+       if (empty($CONFIG->page_owner_handlers)) {
+               $CONFIG->page_owner_handlers = array();
+       }
+       if (is_callable($functionname)) {
+               $CONFIG->page_owner_handlers[] = $functionname;
+       }
+}
+
+/**
+ * Allows a page to manually set a page owner
+ *
+ * @param int $entitytoset The GUID of the page owner
+ * @return int|false Either the page owner we've just set, or false if unset
+ */
+function set_page_owner($entitytoset = -1) {
+       static $entity;
+
+       if (!isset($entity)) {
+               $entity = false;
+       }
+
+       if ($entitytoset > -1) {
+               $entity = $entitytoset;
+       }
+
+       return $entity;
+
+}
+
+/**
+ * Sets the functional context of a page
+ *
+ * @param string $context The context of the page
+ * @return string|false Either the context string, or false on failure
+ */
+function set_context($context) {
+       global $CONFIG;
+       if (!empty($context)) {
+               $context = trim($context);
+               $context = strtolower($context);
+               $CONFIG->context = $context;
+               return $context;
+       } else {
+               return false;
+       }
+}
+
+/**
+ * Returns the functional context of a page
+ *
+ * @return string The context, or 'main' if no context has been provided
+ */
+function get_context() {
+       global $CONFIG;
+       if (isset($CONFIG->context) && !empty($CONFIG->context)) {
+               return $CONFIG->context;
+       }
+       if ($context = get_plugin_name(true)) {
+               return $context;
+       }
+       return "main";
+}
+
+if (defined('context')) {
+       global $CONFIG;
+       $CONFIG->context = context;
+}
\ No newline at end of file
index efebb45ecb3414d9cf50c045f07c975313b27c11..91bf63f7c49e87a971ef289c3a57054c7547503d 100644 (file)
@@ -1,95 +1,82 @@
 <?php
+/**
+ * Elgg PAM library
+ * Contains functions for managing authentication using various arbitrary methods
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Elgg PAM library
-        * Contains functions for managing authentication using various arbitrary methods
-        * 
-        * @package Elgg
-        * @subpackage Core
+$_PAM_HANDLERS = array();
+$_PAM_HANDLERS_MSG = array();
 
-        * @author Curverider Ltd
+/**
+ * Register a PAM handler.
+ *
+ * @param string $handler The handler function in the format
+ *             pam_handler($credentials = NULL);
+ * @param string $importance The importance - "sufficient" or "required"
+ */
+function register_pam_handler($handler, $importance = "sufficient") {
+       global $_PAM_HANDLERS;
 
-        * @link http://elgg.org/
-        */
+       if (is_callable($handler)) {
+               $_PAM_HANDLERS[$handler] = new stdClass;
 
-       $_PAM_HANDLERS = array();
-       $_PAM_HANDLERS_MSG = array();
-       
-       
-       /**
-        * Register a PAM handler.
-        * 
-        * @param string $handler The handler function in the format 
-        *              pam_handler($credentials = NULL);
-        * @param string $importance The importance - "sufficient" or "required"
-        */
-       function register_pam_handler($handler, $importance = "sufficient")
-       {
-               global $_PAM_HANDLERS;
-               
-               if (is_callable($handler))
-               {
-                       $_PAM_HANDLERS[$handler] = new stdClass;
-                       
-                       $_PAM_HANDLERS[$handler]->handler = $handler;
-                       $_PAM_HANDLERS[$handler]->importance = strtolower($importance);
-                       
-                       return true;
-               }
-               
-               return false;
+               $_PAM_HANDLERS[$handler]->handler = $handler;
+               $_PAM_HANDLERS[$handler]->importance = strtolower($importance);
+
+               return true;
        }
-       
-       /**
-        * Attempt to authenticate.
-        * This function will go through all registered PAM handlers to see if a user can be authorised.
-        *
-        * If $credentials are provided the PAM handler should authenticate using the provided credentials, if
-        * not then credentials should be prompted for or otherwise retrieved (eg from the HTTP header or $_SESSION).
-        * 
-        * @param mixed $credentials Mixed PAM handler specific credentials (eg username,password or hmac etc)
-        * @return bool true if authenticated, false if not.
-        */
-       function pam_authenticate($credentials = NULL)
-       {
-               global $_PAM_HANDLERS, $_PAM_HANDLERS_MSG;
-               
-               $authenticated = false;
-               
-               foreach ($_PAM_HANDLERS as $k => $v)
-               {
-                       $handler = $v->handler;
-                       $importance = $v->importance;
-               
-                       try {
-                               // Execute the handler 
-                               if ($handler($credentials))
-                               {
-                                       // Explicitly returned true
-                                       $_PAM_HANDLERS_MSG[$k] = "Authenticated!";
 
-                                       $authenticated = true;
-                               }
-                               else
-                               {
-                                       $_PAM_HANDLERS_MSG[$k] = "Not Authenticated.";
-                               
-                                       // If this is required then abort.
-                                       if ($importance == 'required')
-                                               return false;
-                               }
-                       } 
-                       catch (Exception $e)
-                       {               
-                               $_PAM_HANDLERS_MSG[$k] = "$e";
-                               
+       return false;
+}
+
+/**
+ * Attempt to authenticate.
+ * This function will go through all registered PAM handlers to see if a user can be authorised.
+ *
+ * If $credentials are provided the PAM handler should authenticate using the provided credentials, if
+ * not then credentials should be prompted for or otherwise retrieved (eg from the HTTP header or $_SESSION).
+ *
+ * @param mixed $credentials Mixed PAM handler specific credentials (eg username,password or hmac etc)
+ * @return bool true if authenticated, false if not.
+ */
+function pam_authenticate($credentials = NULL) {
+       global $_PAM_HANDLERS, $_PAM_HANDLERS_MSG;
+
+       $authenticated = false;
+
+       foreach ($_PAM_HANDLERS as $k => $v) {
+               $handler = $v->handler;
+               $importance = $v->importance;
+
+               try {
+                       // Execute the handler
+                       if ($handler($credentials)) {
+                               // Explicitly returned true
+                               $_PAM_HANDLERS_MSG[$k] = "Authenticated!";
+
+                               $authenticated = true;
+                       } else {
+                               $_PAM_HANDLERS_MSG[$k] = "Not Authenticated.";
+
                                // If this is required then abort.
-                               if ($importance == 'required')
+                               if ($importance == 'required') {
                                        return false;
-                       }       
+                               }
+                       }
+               } catch (Exception $e) {
+                       $_PAM_HANDLERS_MSG[$k] = "$e";
+
+                       // If this is required then abort.
+                       if ($importance == 'required') {
+                               return false;
+                       }
                }
-               
-               return $authenticated;
        }
-       
-?>
\ No newline at end of file
+
+       return $authenticated;
+}
\ No newline at end of file
index af42b9a87dc6988dfe842d4fec06b833b7fb50f5..b318806a703bbaa000f0060e0ef8a9fc94f5da68 100644 (file)
@@ -1,47 +1,45 @@
 <?php
-       /**
       * This module pings us on the first install.
-        * 
       * @package Elgg
       * @subpackage Core
       * @author Curverider Ltdsend_api_get_call
       * @link http://elgg.org/
       */
+/**
+ * This module pings us on the first install.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltdsend_api_get_call
+ * @link http://elgg.org/
+ */
 
-       /**
-        * The api for the pinger.
-        * TODO: Have this configurable and/or updatable
-        */
-       $NOTIFICATION_SERVER = "http://ping.elgg.org/pg/api/rest/php/";
-       
-       
-       /**
-        * Run once and only once.
-        * 
-        * @param ElggSite $site The site who's information to use
-        */
-       function ping_home(ElggSite $site)
-       {
-               global $NOTIFICATION_SERVER, $CONFIG;
-       
-               // Get version information
-               $version = get_version();
-               $release = get_version(true);
-               
-               // Get export
-               $export = export($site->guid);
-               
-               return send_api_post_call($NOTIFICATION_SERVER,
-                       array(
-                               'method' => 'elgg.system.ping',
-                       
-                               'url'     => $site->url,
-                               'version' => $version,
-                               'release' => $release,
-                       ),
-                       array(),
-                       $export,
-                       'text/xml'
-               );
-       }
-?>
\ No newline at end of file
+/**
+ * The api for the pinger.
+ * TODO: Have this configurable and/or updatable
+ */
+$NOTIFICATION_SERVER = "http://ping.elgg.org/pg/api/rest/php/";
+
+
+/**
+ * Run once and only once.
+ *
+ * @param ElggSite $site The site who's information to use
+ */
+function ping_home(ElggSite $site) {
+       global $NOTIFICATION_SERVER, $CONFIG;
+
+       // Get version information
+       $version = get_version();
+       $release = get_version(true);
+
+       // Get export
+       $export = export($site->guid);
+
+       return send_api_post_call($NOTIFICATION_SERVER,
+               array(
+                       'method' => 'elgg.system.ping',
+
+                       'url'     => $site->url,
+                       'version' => $version,
+                       'release' => $release,
+               ),
+               array(),
+               $export,
+               'text/xml'
+       );
+}
\ No newline at end of file
index 1fcd2d1381a10da4146c3e8386b51e1f02002818..d03f604420913dff5165d745343fc1b7ee841abe 100644 (file)
 <?php
+/**
+ * Elgg plugins library
+ * Contains functions for managing plugins
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-               /**
-                * Elgg plugins library
-                * Contains functions for managing plugins
-                * 
-                * @package Elgg
-                * @subpackage Core
-
-                * @author Curverider Ltd
-
-                * @link http://elgg.org/
-                */
-
-               
-               /// Cache enabled plugins per page
-               $ENABLED_PLUGINS_CACHE = NULL;
-
-               /**
-                * PluginException
-                *  
-                * A plugin Exception, thrown when an Exception occurs relating to the plugin mechanism. Subclass for specific plugin Exceptions.
-                * 
-                * @package Elgg
-                * @subpackage Exceptions
-                */
-               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);
+
+/// Cache enabled plugins per page
+$ENABLED_PLUGINS_CACHE = NULL;
+
+/**
+ * PluginException
+ *
+ * A plugin Exception, thrown when an Exception occurs relating to the plugin mechanism. Subclass for specific plugin Exceptions.
+ *
+ * @package Elgg
+ * @subpackage Exceptions
+ */
+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.
+               $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;
                        }
-                       
-                       /**
-                        * 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];
+
+                       $this->attributes[$name] = $value;
+               } else {
+                       return set_private_setting($this->guid, $name, $value);
+               }
+
+               return true;
+       }
+}
+
+/**
+ * Returns a list of plugins to load, in the order that they should be loaded.
+ *
+ * @return array List of plugins
+ */
+function get_plugin_list() {
+       global $CONFIG;
+
+       if (!empty($CONFIG->pluginlistcache)) {
+               return $CONFIG->pluginlistcache;
+       }
+
+       if ($site = get_entity($CONFIG->site_guid)) {
+               $pluginorder = $site->pluginorder;
+               if (!empty($pluginorder)) {
+                       $plugins = unserialize($pluginorder);
+
+                       $CONFIG->pluginlistcache = $plugins;
+                       return $plugins;
+               } else {
+                       $plugins = array();
+
+                       if ($handle = opendir($CONFIG->pluginspath)) {
+                               while ($mod = readdir($handle)) {
+                                       if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) {
+                                               $plugins[] = $mod;
+                                       }
                                }
-                               
-                               // 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;
+                       sort($plugins);
+
+                       $CONFIG->pluginlistcache = $plugins;
+                       return $plugins;
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Regenerates the list of known plugins and saves it to the current site
+ *
+ * Important: You should regenerate simplecache and the viewpath cache after executing this function
+ * otherwise you may experience view display artifacts. Do this with the following code:
+ *
+ *             elgg_view_regenerate_simplecache();
+ *             elgg_filepath_cache_reset();
+ *
+ * @param array $pluginorder Optionally, a list of existing plugins and their orders
+ * @return array The new list of plugins and their orders
+ */
+function regenerate_plugin_list($pluginorder = false) {
+       global $CONFIG;
+
+       $CONFIG->pluginlistcache = null;
+
+       if ($site = get_entity($CONFIG->site_guid)) {
+               if (empty($pluginorder)) {
+                       $pluginorder = $site->pluginorder;
+                       $pluginorder = unserialize($pluginorder);
+               } else {
+                       ksort($pluginorder);
+               }
+
+               if (empty($pluginorder)) {
+                       $pluginorder = array();
+               }
+
+               $max = 0;
+               if (sizeof($pluginorder)) {
+                       foreach($pluginorder as $key => $plugin) {
+                               if (is_dir($CONFIG->pluginspath . "/" . $plugin)) {
+                                       if ($key > $max)
+                                               $max = $key;
+                               } else {
+                                       unset($pluginorder[$key]);
                                }
-                               else 
-                                       return set_private_setting($this->guid, $name, $value);
-                       
-                               return true;
                        }
                }
-               
-               /**
-                * Returns a list of plugins to load, in the order that they should be loaded.
-                *
-                * @return array List of plugins
-                */
-               function get_plugin_list() {
-
-                       global $CONFIG;
-                       
-                       if (!empty($CONFIG->pluginlistcache))
-                               return $CONFIG->pluginlistcache;
-                       
-                       if ($site = get_entity($CONFIG->site_guid)) {
-                               
-                               $pluginorder = $site->pluginorder;
-                               if (!empty($pluginorder)) {
-                                       
-                                       $plugins = unserialize($pluginorder);
-                                       
-                                       $CONFIG->pluginlistcache = $plugins;
-                                       return $plugins;
-                                       
-                               } else {
-                                       
-                                       $plugins = array();
-                                               
-                                       if ($handle = opendir($CONFIG->pluginspath)) {
-                                               while ($mod = readdir($handle)) {
-                                                       if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) {
-                                                               $plugins[] = $mod;
-                                                       }
-                                               }
+               // Add new plugins to the end
+               if ($handle = opendir($CONFIG->pluginspath)) {
+                       while ($mod = readdir($handle)) {
+                               if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) {
+                                       if (!in_array($mod, $pluginorder)) {
+                                               $max = $max + 10;
+                                               $pluginorder[$max] = $mod;
                                        }
-                                               
-                                       sort($plugins);
-                                       
-                                       $CONFIG->pluginlistcache = $plugins;
-                                       return $plugins;
-                                       
                                }
-                               
                        }
-                       
-                       return false;
-                       
                }
-               
-               /**
-                * Regenerates the list of known plugins and saves it to the current site
-                * 
-                * Important: You should regenerate simplecache and the viewpath cache after executing this function
-                * otherwise you may experience view display artifacts. Do this with the following code:
-                * 
-                *              elgg_view_regenerate_simplecache();
-                *              elgg_filepath_cache_reset();
-                *
-                * @param array $pluginorder Optionally, a list of existing plugins and their orders
-                * @return array The new list of plugins and their orders
-                */
-               function regenerate_plugin_list($pluginorder = false) {
-                       
-                       global $CONFIG;
-                       
-                       $CONFIG->pluginlistcache = null;
-                       
-                       if ($site = get_entity($CONFIG->site_guid)) {
-                               
-                               if (empty($pluginorder)) {
-                                       $pluginorder = $site->pluginorder;
-                                       $pluginorder = unserialize($pluginorder);
-                               } else {
-                                       ksort($pluginorder);
-                               }
 
-                               if (empty($pluginorder)) {
-                                       $pluginorder = array();
-                               }
-                               
-                               $max = 0;
-                               if (sizeof($pluginorder))
-                                       foreach($pluginorder as $key => $plugin) {
-                                               if (is_dir($CONFIG->pluginspath . "/" . $plugin)) { 
-                                                       if ($key > $max)
-                                                               $max = $key;
-                                               } else {
-                                                       unset($pluginorder[$key]);
-                                               }
-                                       }
-                                       
-                               // Add new plugins to the end
-                               if ($handle = opendir($CONFIG->pluginspath)) {
-                                       while ($mod = readdir($handle)) {
-                                               if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) {
-                                                       if (!in_array($mod, $pluginorder)) {
-                                                               $max = $max + 10;
-                                                               $pluginorder[$max] = $mod;
-                                                       }
-                                               }
-                                       }
-                               }
-                               
-                               ksort($pluginorder);
-                               
-                               // Now reorder the keys ..
-                               $key = 10;
-                               $plugins = array();
-                               if (sizeof($pluginorder))
-                                       foreach($pluginorder as $plugin) {
-                                               $plugins[$key] = $plugin;
-                                               $key = $key + 10;
-                                       }
-                               
-                               $plugins = serialize($plugins);
-                               
-                               $site->pluginorder = $plugins;
-                               
-                               // Regenerate caches
-                               elgg_view_regenerate_simplecache();
-                               elgg_filepath_cache_reset();
-                               
-                               return $plugins;
-                                       
+               ksort($pluginorder);
+
+               // Now reorder the keys ..
+               $key = 10;
+               $plugins = array();
+               if (sizeof($pluginorder)) {
+                       foreach($pluginorder as $plugin) {
+                               $plugins[$key] = $plugin;
+                               $key = $key + 10;
                        }
-                       
-                       return false;
-                       
                }
-               
-
-               /**
-                * For now, loads plugins directly
-                *
-                * @todo Add proper plugin handler that launches plugins in an admin-defined order and activates them on admin request
-                * @package Elgg
-                * @subpackage Core
-                */
-               function load_plugins() {
-                       
-                       global $CONFIG;
-                       
-                       if (!empty($CONFIG->pluginspath)) {
-                               
-                               // See if we have cached values for things
-                               $cached_view_paths = elgg_filepath_cache_load();
-                               if ($cached_view_paths) $CONFIG->views = unserialize($cached_view_paths);
-                               
-                               // temporary disable all plugins if there is a file called 'disabled' in the plugin dir
-                               if (file_exists($CONFIG->pluginspath . "disabled"))
-                                       return;
-                               
-                               $plugins = get_plugin_list();
-                               
-                               if (sizeof($plugins))
-                               {
-                                       foreach($plugins as $mod) {
-                                               if (is_plugin_enabled($mod)) {
-                                                       if (file_exists($CONFIG->pluginspath . $mod)) {
-                                                               if (!include($CONFIG->pluginspath . $mod . "/start.php"))
-                                                                       throw new PluginException(sprintf(elgg_echo('PluginException:MisconfiguredPlugin'), $mod));
-                                                                       
-                                                               if (!$cached_view_paths)
-                                                               {
-                                                                       if (is_dir($CONFIG->pluginspath . $mod . "/views")) {
-                                                                               if ($handle = opendir($CONFIG->pluginspath . $mod . "/views")) {
-                                                                                       while ($viewtype = readdir($handle)) {
-                                                                                               if (!in_array($viewtype,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . $mod . "/views/" . $viewtype)) {
-                                                                                                       autoregister_views("",$CONFIG->pluginspath . $mod . "/views/" . $viewtype,$CONFIG->pluginspath . $mod . "/views/", $viewtype);
-                                                                                               }
-                                                                                       }
+
+               $plugins = serialize($plugins);
+
+               $site->pluginorder = $plugins;
+
+               // Regenerate caches
+               elgg_view_regenerate_simplecache();
+               elgg_filepath_cache_reset();
+
+               return $plugins;
+
+       }
+
+       return false;
+}
+
+
+/**
+ * For now, loads plugins directly
+ *
+ * @todo Add proper plugin handler that launches plugins in an admin-defined order and activates them on admin request
+ * @package Elgg
+ * @subpackage Core
+ */
+function load_plugins() {
+       global $CONFIG;
+
+       if (!empty($CONFIG->pluginspath)) {
+               // See if we have cached values for things
+               $cached_view_paths = elgg_filepath_cache_load();
+               if ($cached_view_paths) {
+                       $CONFIG->views = unserialize($cached_view_paths);
+               }
+
+               // temporary disable all plugins if there is a file called 'disabled' in the plugin dir
+               if (file_exists($CONFIG->pluginspath . "disabled")) {
+                       return;
+               }
+
+               $plugins = get_plugin_list();
+
+               if (sizeof($plugins)) {
+                       foreach($plugins as $mod) {
+                               if (is_plugin_enabled($mod)) {
+                                       if (file_exists($CONFIG->pluginspath . $mod)) {
+                                               if (!include($CONFIG->pluginspath . $mod . "/start.php")) {
+                                                       throw new PluginException(sprintf(elgg_echo('PluginException:MisconfiguredPlugin'), $mod));
+                                               }
+
+                                               if (!$cached_view_paths) {
+                                                       if (is_dir($CONFIG->pluginspath . $mod . "/views")) {
+                                                               if ($handle = opendir($CONFIG->pluginspath . $mod . "/views")) {
+                                                                       while ($viewtype = readdir($handle)) {
+                                                                               if (!in_array($viewtype,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . $mod . "/views/" . $viewtype)) {
+                                                                                       autoregister_views("",$CONFIG->pluginspath . $mod . "/views/" . $viewtype,$CONFIG->pluginspath . $mod . "/views/", $viewtype);
                                                                                }
                                                                        }
                                                                }
-                                                               
-                                                               if (is_dir($CONFIG->pluginspath . $mod . "/languages")) {
-                                                                       register_translations($CONFIG->pluginspath . $mod . "/languages/");
-                                                               }
                                                        }
                                                }
-                                       }
-                               }
 
-                               // Cache results
-                               if (!$cached_view_paths)
-                                       elgg_filepath_cache_save(serialize($CONFIG->views));
-                       }
-                       
-               }
-               
-               /**
-                * Get the name of the most recent plugin to be called in the call stack (or the plugin that owns the current page, if any).
-                * 
-                * i.e., if the last plugin was in /mod/foobar/, get_plugin_name would return foo_bar.
-                *
-                * @param boolean $mainfilename If set to true, this will instead determine the context from the main script filename called by the browser. Default = false. 
-                * @return string|false Plugin name, or false if no plugin name was called
-                */
-               function get_plugin_name($mainfilename = false) {
-                       if (!$mainfilename) {
-                               if ($backtrace = debug_backtrace()) { 
-                                       foreach($backtrace as $step) {
-                                               $file = $step['file'];
-                                               $file = str_replace("\\","/",$file);
-                                               $file = str_replace("//","/",$file);
-                                               if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\/start\.php$/",$file,$matches)) {
-                                                       return $matches[1];
+                                               if (is_dir($CONFIG->pluginspath . $mod . "/languages")) {
+                                                       register_translations($CONFIG->pluginspath . $mod . "/languages/");
                                                }
                                        }
                                }
-                       } else {
-                               //if (substr_count($file,'handlers/pagehandler')) {
-                               if (preg_match("/pg\/([a-zA-Z0-9\-\_]*)\//",$_SERVER['REQUEST_URI'],$matches)) {
-                                       return $matches[1];
-                               } else {
-                                       $file = $_SERVER["SCRIPT_NAME"];
-                                       $file = str_replace("\\","/",$file);
-                                       $file = str_replace("//","/",$file);
-                                       if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\//",$file,$matches)) {
-                                               return $matches[1];
-                                       }
-                               }
-                       }
-                       return false;
-               }
-               
-               /**
-                * Load and parse a plugin manifest from a plugin XML file.
-                * 
-                * Example file:
-                * 
-                * <plugin_manifest>
-                *      <field key="author" value="Curverider Ltd" />
-                *  <field key="version" value="1.0" />
-                *      <field key="description" value="My plugin description, keep it short" />
-                *  <field key="website" value="http://www.elgg.org/" />
-                *  <field key="copyright" value="(C) Curverider 2008-2009" />
-                *  <field key="licence" value="GNU Public License version 2" />
-                * </plugin_manifest>
-                *
-                * @param string $plugin Plugin name.
-                * @return array of values
-                */
-               function load_plugin_manifest($plugin)
-               {
-                       global $CONFIG;
-                       
-                       $xml = xml_2_object(file_get_contents($CONFIG->pluginspath . $plugin. "/manifest.xml"));
-                       
-                       if ($xml)
-                       {
-                               $elements = array();
-                               
-                               foreach ($xml->children as $element)
-                               {
-                                       $key = $element->attributes['key'];
-                                       $value = $element->attributes['value'];
-                                       
-                                       $elements[$key] = $value;
-                               }
-                               
-                               return $elements;
-                       }
-                       
-                       return false;
-               }
-               
-               /**
-                * This function checks a plugin manifest 'elgg_version' value against the current install
-                * returning TRUE if the elgg_version is <= the current install's version.
-                * @param $manifest_elgg_version_string The build version (eg 2009010201). 
-                * @return bool
-                */
-               function check_plugin_compatibility($manifest_elgg_version_string)
-               {
-                       $version = get_version();
-                       
-                       if (strpos($manifest_elgg_version_string, '.')===false)
-                       {
-                               // Using version
-                               $req_version = (int)$manifest_elgg_version_string;
-                               
-                               return ($version >= $req_version);
                        }
-                       
-                       return false;
                }
-               
-               /**
-                * Shorthand function for finding the plugin settings.
-                * 
-                * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you
-                *                                                              are calling from.
-                */
-               function find_plugin_settings($plugin_name = "")
-               {
-                       $plugins = get_entities('object', 'plugin', 0, "", 9999);
-                       $plugin_name = sanitise_string($plugin_name);
-                       if (!$plugin_name)
-                               $plugin_name = get_plugin_name();
-       
-                       if ($plugins)
-                       {
-                               foreach ($plugins as $plugin)                   
-                                       if (strcmp($plugin->title, $plugin_name)==0)
-                                               return $plugin;
-                       }
-                       
-                       return false;
+
+               // Cache results
+               if (!$cached_view_paths) {
+                       elgg_filepath_cache_save(serialize($CONFIG->views));
                }
-               
-               /**
-                * Find the plugin settings for a user.
-                *
-                * @param string $plugin_name Plugin name.
-                * @param int $user_guid The guid who's settings to retrieve.
-                * @return array of settings in an associative array minus prefix.
-                */
-               function find_plugin_usersettings($plugin_name = "", $user_guid = 0)
-               {
-                       $plugin_name = sanitise_string($plugin_name);
-                       $user_guid = (int)$user_guid;
-                       
-                       if (!$plugin_name)
-                               $plugin_name = get_plugin_name();
-                               
-                       if ($user_guid == 0) $user_guid = get_loggedin_userid();
-                       
-                       // Get metadata for user
-                       $all_metadata = get_all_private_settings($user_guid); //get_metadata_for_entity($user_guid);
-                       if ($all_metadata)
-                       {
-                               $prefix = "plugin:settings:$plugin_name:";
-                               $return = new stdClass;
-                               
-                               foreach ($all_metadata as $key => $meta)
-                               {
-                                       $name = substr($key, strlen($prefix));
-                                       $value = $meta;
-                                       
-                                       if (strpos($key, $prefix) === 0)
-                                               $return->$name = $value;
-                               }
+       }
+}
 
-                               return $return;                 
+/**
+ * Get the name of the most recent plugin to be called in the call stack (or the plugin that owns the current page, if any).
+ *
+ * i.e., if the last plugin was in /mod/foobar/, get_plugin_name would return foo_bar.
+ *
+ * @param boolean $mainfilename If set to true, this will instead determine the context from the main script filename called by the browser. Default = false.
+ * @return string|false Plugin name, or false if no plugin name was called
+ */
+function get_plugin_name($mainfilename = false) {
+       if (!$mainfilename) {
+               if ($backtrace = debug_backtrace()) {
+                       foreach($backtrace as $step) {
+                               $file = $step['file'];
+                               $file = str_replace("\\","/",$file);
+                               $file = str_replace("//","/",$file);
+                               if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\/start\.php$/",$file,$matches)) {
+                                       return $matches[1];
+                               }
                        }
-                       
-                       return false;
                }
-               
-               /**
-                * Set a user specific setting for a plugin.
-                *
-                * @param string $name The name - note, can't be "title".
-                * @param mixed $value The value.
-                * @param int $user_guid Optional user.
-                * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
-                */
-               function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_name = "")
-               {
-                       $plugin_name = sanitise_string($plugin_name);
-                       $user_guid = (int)$user_guid;
-                       $name = sanitise_string($name);
-                       
-                       if (!$plugin_name)
-                               $plugin_name = get_plugin_name();
-                                                       
-                       $user = get_entity($user_guid);
-                       if (!$user) $user = get_loggedin_user();
-                       
-                       if (($user) && ($user instanceof ElggUser))
-                       {
-                               $prefix = "plugin:settings:$plugin_name:$name";
-                               //$user->$prefix = $value;
-                               //$user->save();
-                               
-                               // Hook to validate setting
-                               $value = trigger_plugin_hook('plugin:usersetting', 'user', array(
-                                       'user' => $user,
-                                       'plugin' => $plugin_name,
-                                       'name' => $name,
-                                       'value' => $value
-                               ), $value);
-                                       
-                               return set_private_setting($user->guid, $prefix, $value);
+       } else {
+               //if (substr_count($file,'handlers/pagehandler')) {
+               if (preg_match("/pg\/([a-zA-Z0-9\-\_]*)\//",$_SERVER['REQUEST_URI'],$matches)) {
+                       return $matches[1];
+               } else {
+                       $file = $_SERVER["SCRIPT_NAME"];
+                       $file = str_replace("\\","/",$file);
+                       $file = str_replace("//","/",$file);
+                       if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\//",$file,$matches)) {
+                               return $matches[1];
                        }
-                       
-                       return false;
                }
-               
-               /**
-                * Get a user specific setting for a plugin.
-                *
-                * @param string $name The name.
-                * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
-                */
-               function get_plugin_usersetting($name, $user_guid = 0, $plugin_name = "")
-               {
-                       $plugin_name = sanitise_string($plugin_name);
-                       $user_guid = (int)$user_guid;
-                       $name = sanitise_string($name);
-                       
-                       if (!$plugin_name)
-                               $plugin_name = get_plugin_name();
-                               
-                       $user = get_entity($user_guid);
-                       if (!$user) $user = get_loggedin_user();
-                       
-                       if (($user) && ($user instanceof ElggUser))
-                       {
-                               $prefix = "plugin:settings:$plugin_name:$name";
-                               return get_private_setting($user->guid, $prefix); //$user->$prefix;
-                       }
-                       
-                       return false;
+       }
+       return false;
+}
+
+/**
+ * Load and parse a plugin manifest from a plugin XML file.
+ *
+ * Example file:
+ *
+ * <plugin_manifest>
+ *     <field key="author" value="Curverider Ltd" />
+ *  <field key="version" value="1.0" />
+ *     <field key="description" value="My plugin description, keep it short" />
+ *  <field key="website" value="http://www.elgg.org/" />
+ *  <field key="copyright" value="(C) Curverider 2008-2009" />
+ *  <field key="licence" value="GNU Public License version 2" />
+ * </plugin_manifest>
+ *
+ * @param string $plugin Plugin name.
+ * @return array of values
+ */
+function load_plugin_manifest($plugin) {
+       global $CONFIG;
+
+       $xml = xml_2_object(file_get_contents($CONFIG->pluginspath . $plugin. "/manifest.xml"));
+
+       if ($xml) {
+               $elements = array();
+
+               foreach ($xml->children as $element) {
+                       $key = $element->attributes['key'];
+                       $value = $element->attributes['value'];
+
+                       $elements[$key] = $value;
                }
-                       
-               /**
-                * Set a setting for a plugin.
-                *
-                * @param string $name The name - note, can't be "title".
-                * @param mixed $value The value.
-                * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
-                */
-               function set_plugin_setting($name, $value, $plugin_name = "")
-               {       
-                       if (!$plugin_name) $plugin_name = get_plugin_name();    
-                       $plugin = find_plugin_settings($plugin_name);
-                       
-                       if (!$plugin) 
-                               $plugin = new ElggPlugin();
-                               
-                       if ($name!='title') 
-                       {
-                               // Hook to validate setting
-                               $value = trigger_plugin_hook('plugin:setting', 'plugin', array(
-                                       'plugin' => $plugin_name,
-                                       'name' => $name,
-                                       'value' => $value
-                               ), $value);
-                               
-                               $plugin->title = $plugin_name;
-                               $plugin->access_id = ACCESS_PUBLIC;
-                               $plugin->save();
-                               $plugin->$name = $value;
-                               
-                               return $plugin->getGUID();
+
+               return $elements;
+       }
+
+       return false;
+}
+
+/**
+ * This function checks a plugin manifest 'elgg_version' value against the current install
+ * returning TRUE if the elgg_version is <= the current install's version.
+ * @param $manifest_elgg_version_string The build version (eg 2009010201).
+ * @return bool
+ */
+function check_plugin_compatibility($manifest_elgg_version_string) {
+       $version = get_version();
+
+       if (strpos($manifest_elgg_version_string, '.') === false) {
+               // Using version
+               $req_version = (int)$manifest_elgg_version_string;
+
+               return ($version >= $req_version);
+       }
+
+       return false;
+}
+
+/**
+ * Shorthand function for finding the plugin settings.
+ *
+ * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you
+ *                                                             are calling from.
+ */
+function find_plugin_settings($plugin_name = "") {
+       $plugins = get_entities('object', 'plugin', 0, "", 9999);
+       $plugin_name = sanitise_string($plugin_name);
+       if (!$plugin_name) {
+               $plugin_name = get_plugin_name();
+       }
+
+       if ($plugins) {
+               foreach ($plugins as $plugin) {
+                       if (strcmp($plugin->title, $plugin_name)==0) {
+                               return $plugin;
                        }
-                       
-                       return false;
-               }
-               
-               /**
-                * Get setting for a plugin.
-                *
-                * @param string $name The name.
-                * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
-                */
-               function get_plugin_setting($name, $plugin_name = "")
-               {
-                       $plugin = find_plugin_settings($plugin_name);
-               
-                       if ($plugin)
-                               return $plugin->$name;
-                       
-                       return false;
-               }
-               
-               /**
-                * Clear a plugin setting.
-                *
-                * @param string $name The name.
-                * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
-                */
-               function clear_plugin_setting($name, $plugin_name = "")
-               {
-                       $plugin = find_plugin_settings($plugin_name);
-                       
-                       if ($plugin)
-                               return remove_all_private_settings($plugin->guid); //$plugin->clearMetaData($name);
-                       
-                       return false;
                }
-               
-               /**
-                * Return an array of installed plugins.
-                */
-               function get_installed_plugins()
-               {
-                       global $CONFIG;
-                       
-                       $installed_plugins = array();
-                       
-                       if (!empty($CONFIG->pluginspath)) {
-                               
-                               $plugins = get_plugin_list();
-                               
-                               foreach($plugins as $mod) {
-                                       $installed_plugins[$mod] = array();
-                                       $installed_plugins[$mod]['active'] = is_plugin_enabled($mod);
-                                       $installed_plugins[$mod]['manifest'] = load_plugin_manifest($mod);
-                               }
-                               
+       }
+
+       return false;
+}
+
+/**
+ * Find the plugin settings for a user.
+ *
+ * @param string $plugin_name Plugin name.
+ * @param int $user_guid The guid who's settings to retrieve.
+ * @return array of settings in an associative array minus prefix.
+ */
+function find_plugin_usersettings($plugin_name = "", $user_guid = 0) {
+       $plugin_name = sanitise_string($plugin_name);
+       $user_guid = (int)$user_guid;
+
+       if (!$plugin_name) {
+               $plugin_name = get_plugin_name();
+       }
+
+       if ($user_guid == 0) {
+               $user_guid = get_loggedin_userid();
+       }
+
+       // Get metadata for user
+       $all_metadata = get_all_private_settings($user_guid); //get_metadata_for_entity($user_guid);
+       if ($all_metadata) {
+               $prefix = "plugin:settings:$plugin_name:";
+               $return = new stdClass;
+
+               foreach ($all_metadata as $key => $meta) {
+                       $name = substr($key, strlen($prefix));
+                       $value = $meta;
+
+                       if (strpos($key, $prefix) === 0) {
+                               $return->$name = $value;
                        }
-                       
-                       return $installed_plugins;
                }
-               
-               /**
-                * Enable a plugin for a site (default current site)
-                * 
-                * Important: You should regenerate simplecache and the viewpath cache after executing this function
-                * otherwise you may experience view display artifacts. Do this with the following code:
-                * 
-                *              elgg_view_regenerate_simplecache();
-                *              elgg_filepath_cache_reset();
-                *
-                * @param string $plugin The plugin name.
-                * @param int $site_guid The site id, if not specified then this is detected.
-                */
-               function enable_plugin($plugin, $site_guid = 0)
-               {
-                       global $CONFIG, $ENABLED_PLUGINS_CACHE;
-                       
-                       $plugin = sanitise_string($plugin);
-                       $site_guid = (int) $site_guid;
-                       if ($site_guid == 0)
-                               $site_guid = $CONFIG->site_guid;
-                               
-                       $site = get_entity($site_guid);
-                       if (!($site instanceof ElggSite))
-                               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite"));
-                               
-                       $enabled = $site->getMetaData('enabled_plugins');
-                       $new_enabled = array();
-                       if ($enabled)
-                       {
-                               if (!is_array($enabled))
-                                       $new_enabled[] = $enabled;
-                               else
-                                       $new_enabled = $enabled;
-                       }
-                       $new_enabled[] = $plugin;
-                       $new_enabled = array_unique($new_enabled);
-                       
-                       $return = $site->setMetaData('enabled_plugins', $new_enabled);
-                       $ENABLED_PLUGINS_CACHE = $new_enabled;
-                       
-                       return $return; 
+
+               return $return;
+       }
+
+       return false;
+}
+
+/**
+ * Set a user specific setting for a plugin.
+ *
+ * @param string $name The name - note, can't be "title".
+ * @param mixed $value The value.
+ * @param int $user_guid Optional user.
+ * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
+ */
+function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_name = "") {
+       $plugin_name = sanitise_string($plugin_name);
+       $user_guid = (int)$user_guid;
+       $name = sanitise_string($name);
+
+       if (!$plugin_name) {
+               $plugin_name = get_plugin_name();
+       }
+
+       $user = get_entity($user_guid);
+       if (!$user) {
+               $user = get_loggedin_user();
+       }
+
+       if (($user) && ($user instanceof ElggUser)) {
+               $prefix = "plugin:settings:$plugin_name:$name";
+               //$user->$prefix = $value;
+               //$user->save();
+
+               // Hook to validate setting
+               $value = trigger_plugin_hook('plugin:usersetting', 'user', array(
+                       'user' => $user,
+                       'plugin' => $plugin_name,
+                       'name' => $name,
+                       'value' => $value
+               ), $value);
+
+               return set_private_setting($user->guid, $prefix, $value);
+       }
+
+       return false;
+}
+
+/**
+ * Get a user specific setting for a plugin.
+ *
+ * @param string $name The name.
+ * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
+ */
+function get_plugin_usersetting($name, $user_guid = 0, $plugin_name = "") {
+       $plugin_name = sanitise_string($plugin_name);
+       $user_guid = (int)$user_guid;
+       $name = sanitise_string($name);
+
+       if (!$plugin_name) {
+               $plugin_name = get_plugin_name();
+       }
+
+       $user = get_entity($user_guid);
+       if (!$user) {
+               $user = get_loggedin_user();
+       }
+
+       if (($user) && ($user instanceof ElggUser)) {
+               $prefix = "plugin:settings:$plugin_name:$name";
+               return get_private_setting($user->guid, $prefix); //$user->$prefix;
+       }
+
+       return false;
+}
+
+/**
+ * Set a setting for a plugin.
+ *
+ * @param string $name The name - note, can't be "title".
+ * @param mixed $value The value.
+ * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
+ */
+function set_plugin_setting($name, $value, $plugin_name = "") {
+       if (!$plugin_name) {
+               $plugin_name = get_plugin_name();
+       }
+       $plugin = find_plugin_settings($plugin_name);
+
+       if (!$plugin) {
+               $plugin = new ElggPlugin();
+       }
+
+       if ($name!='title') {
+               // Hook to validate setting
+               $value = trigger_plugin_hook('plugin:setting', 'plugin', array(
+                       'plugin' => $plugin_name,
+                       'name' => $name,
+                       'value' => $value
+               ), $value);
+
+               $plugin->title = $plugin_name;
+               $plugin->access_id = ACCESS_PUBLIC;
+               $plugin->save();
+               $plugin->$name = $value;
+
+               return $plugin->getGUID();
+       }
+
+       return false;
+}
+
+/**
+ * Get setting for a plugin.
+ *
+ * @param string $name The name.
+ * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
+ */
+function get_plugin_setting($name, $plugin_name = "") {
+       $plugin = find_plugin_settings($plugin_name);
+
+       if ($plugin) {
+               return $plugin->$name;
+       }
+
+       return false;
+}
+
+/**
+ * Clear a plugin setting.
+ *
+ * @param string $name The name.
+ * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from.
+ */
+function clear_plugin_setting($name, $plugin_name = "") {
+       $plugin = find_plugin_settings($plugin_name);
+
+       if ($plugin) {
+               //$plugin->clearMetaData($name);
+               return remove_all_private_settings($plugin->guid);
+       }
+
+       return false;
+}
+
+/**
+ * Return an array of installed plugins.
+ */
+function get_installed_plugins() {
+       global $CONFIG;
+
+       $installed_plugins = array();
+
+       if (!empty($CONFIG->pluginspath)) {
+               $plugins = get_plugin_list();
+
+               foreach($plugins as $mod) {
+                       $installed_plugins[$mod] = array();
+                       $installed_plugins[$mod]['active'] = is_plugin_enabled($mod);
+                       $installed_plugins[$mod]['manifest'] = load_plugin_manifest($mod);
                }
-               
-               /**
-                * Disable a plugin for a site (default current site)
-                * 
-                * Important: You should regenerate simplecache and the viewpath cache after executing this function
-                * otherwise you may experience view display artifacts. Do this with the following code:
-                * 
-                *              elgg_view_regenerate_simplecache();
-                *              elgg_filepath_cache_reset();
-                * 
-                * @param string $plugin The plugin name.
-                * @param int $site_guid The site id, if not specified then this is detected.
-                */
-               function disable_plugin($plugin, $site_guid = 0)
-               {
-                       global $CONFIG, $ENABLED_PLUGINS_CACHE;
-                       
-                       $plugin = sanitise_string($plugin);
-                       $site_guid = (int) $site_guid;
-                       if ($site_guid == 0)
-                               $site_guid = $CONFIG->site_guid;
-                               
-                       $site = get_entity($site_guid);
-                       if (!($site instanceof ElggSite))
-                               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite"));
-                               
-                       $enabled = $site->getMetaData('enabled_plugins');
-                       $new_enabled = array();
-               
-                       foreach ($enabled as $plug)
-                               if ($plugin != $plug)
-                                       $new_enabled[] = $plug;
-                                       
-                       $return = $site->setMetaData('enabled_plugins', $new_enabled);
-                       $ENABLED_PLUGINS_CACHE = $new_enabled;
-                                       
-                       return $return;
+       }
+
+       return $installed_plugins;
+}
+
+/**
+ * Enable a plugin for a site (default current site)
+ *
+ * Important: You should regenerate simplecache and the viewpath cache after executing this function
+ * otherwise you may experience view display artifacts. Do this with the following code:
+ *
+ *             elgg_view_regenerate_simplecache();
+ *             elgg_filepath_cache_reset();
+ *
+ * @param string $plugin The plugin name.
+ * @param int $site_guid The site id, if not specified then this is detected.
+ */
+function enable_plugin($plugin, $site_guid = 0) {
+       global $CONFIG, $ENABLED_PLUGINS_CACHE;
+
+       $plugin = sanitise_string($plugin);
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $site = get_entity($site_guid);
+       if (!($site instanceof ElggSite)) {
+               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite"));
+       }
+
+       $enabled = $site->getMetaData('enabled_plugins');
+       $new_enabled = array();
+       if ($enabled) {
+               if (!is_array($enabled)) {
+                       $new_enabled[] = $enabled;
+               } else {
+                       $new_enabled = $enabled;
                }
-               
-               /**
-                * Return whether a plugin is enabled or not.
-                *
-                * @param string $plugin The plugin name.
-                * @param int $site_guid The site id, if not specified then this is detected.
-                * @return bool
-                */
-               function is_plugin_enabled($plugin, $site_guid = 0)
-               {
-                       global $CONFIG, $ENABLED_PLUGINS_CACHE;
-                       
-                       if (!file_exists($CONFIG->pluginspath . $plugin)) return false;
-                       
-                       $site_guid = (int) $site_guid;
-                       if ($site_guid == 0)
-                               $site_guid = $CONFIG->site_guid;
-                               
-                               
-                       if (!$ENABLED_PLUGINS_CACHE) {
-                               $site = get_entity($site_guid);
-                               if (!($site instanceof ElggSite))
-                                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite"));
-                       
-                               $ENABLED_PLUGINS_CACHE = $site->enabled_plugins;
-                       }
-                               
-                       foreach ($ENABLED_PLUGINS_CACHE as $e)
-                               if ($e == $plugin) return true;
-                               
-                       return false;
+       }
+       $new_enabled[] = $plugin;
+       $new_enabled = array_unique($new_enabled);
+
+       $return = $site->setMetaData('enabled_plugins', $new_enabled);
+       $ENABLED_PLUGINS_CACHE = $new_enabled;
+
+       return $return;
+}
+
+/**
+ * Disable a plugin for a site (default current site)
+ *
+ * Important: You should regenerate simplecache and the viewpath cache after executing this function
+ * otherwise you may experience view display artifacts. Do this with the following code:
+ *
+ *             elgg_view_regenerate_simplecache();
+ *             elgg_filepath_cache_reset();
+ *
+ * @param string $plugin The plugin name.
+ * @param int $site_guid The site id, if not specified then this is detected.
+ */
+function disable_plugin($plugin, $site_guid = 0) {
+       global $CONFIG, $ENABLED_PLUGINS_CACHE;
+
+       $plugin = sanitise_string($plugin);
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $site = get_entity($site_guid);
+       if (!($site instanceof ElggSite)) {
+               throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite"));
+       }
+
+       $enabled = $site->getMetaData('enabled_plugins');
+       $new_enabled = array();
+
+       foreach ($enabled as $plug) {
+               if ($plugin != $plug) {
+                       $new_enabled[] = $plug;
                }
-               
-               /**
-                * Run once and only once.
-                */
-               function plugin_run_once()
-               {
-                       // Register a class
-                       add_subtype("object", "plugin", "ElggPlugin");  
+       }
+
+       $return = $site->setMetaData('enabled_plugins', $new_enabled);
+       $ENABLED_PLUGINS_CACHE = $new_enabled;
+
+       return $return;
+}
+
+/**
+ * Return whether a plugin is enabled or not.
+ *
+ * @param string $plugin The plugin name.
+ * @param int $site_guid The site id, if not specified then this is detected.
+ * @return bool
+ */
+function is_plugin_enabled($plugin, $site_guid = 0) {
+       global $CONFIG, $ENABLED_PLUGINS_CACHE;
+
+       if (!file_exists($CONFIG->pluginspath . $plugin)) {
+               return false;
+       }
+
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+
+       if (!$ENABLED_PLUGINS_CACHE) {
+               $site = get_entity($site_guid);
+               if (!($site instanceof ElggSite)) {
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite"));
                }
-               
-               /** 
-                * Initialise the file modules. 
-                * Listens to system boot and registers any appropriate file types and classes 
-                */
-               function plugin_init()
-               {
-                       // Now run this stuff, but only once
-                       run_function_once("plugin_run_once");
-                       
-                       // Register some actions
-                       register_action("plugins/settings/save", false, "", true);
-                       register_action("plugins/usersettings/save");
-                       
-                       register_action('admin/plugins/enable', false, "", true); // Enable
-                       register_action('admin/plugins/disable', false, "", true); // Disable
-                       register_action('admin/plugins/enableall', false, "", true); // Enable all
-                       register_action('admin/plugins/disableall', false, "", true); // Disable all
-                       
-                       register_action('admin/plugins/reorder', false, "", true); // Reorder
-                       
+
+               $ENABLED_PLUGINS_CACHE = $site->enabled_plugins;
+       }
+
+       foreach ($ENABLED_PLUGINS_CACHE as $e) {
+               if ($e == $plugin) {
+                       return true;
                }
-               
-               // Register a startup event
-               register_elgg_event_handler('init','system','plugin_init');     
-?>
\ No newline at end of file
+       }
+
+       return false;
+}
+
+/**
+ * Run once and only once.
+ */
+function plugin_run_once() {
+       // Register a class
+       add_subtype("object", "plugin", "ElggPlugin");
+}
+
+/**
+ * Initialise the file modules.
+ * Listens to system boot and registers any appropriate file types and classes
+ */
+function plugin_init() {
+       // Now run this stuff, but only once
+       run_function_once("plugin_run_once");
+
+       // Register some actions
+       register_action("plugins/settings/save", false, "", true);
+       register_action("plugins/usersettings/save");
+
+       register_action('admin/plugins/enable', false, "", true); // Enable
+       register_action('admin/plugins/disable', false, "", true); // Disable
+       register_action('admin/plugins/enableall', false, "", true); // Enable all
+       register_action('admin/plugins/disableall', false, "", true); // Disable all
+
+       register_action('admin/plugins/reorder', false, "", true); // Reorder
+}
+
+// Register a startup event
+register_elgg_event_handler('init','system','plugin_init');
\ No newline at end of file
index 75b9eddeb7605a6599f21894b3645700f758c1ac..619a2d2889cf4e6a4ba5a185361d4ab568b5037d 100644 (file)
@@ -2,7 +2,7 @@
        /**
         * Elgg database query
         * Contains a wrapper for performing database queries in a structured way.
-        * 
+        *
         * @package Elgg
         * @subpackage Core
         * @author Curverider Ltd
         * @author Curverider Ltd
         * @see Query
         */
-       abstract class QueryComponent 
+       abstract class QueryComponent
        {
                /**
                 * Associative array of fields and values
-                */ 
+                */
                private $fields;
 
                function __construct()
                {
-                       $this->fields = array(); 
+                       $this->fields = array();
                }
-               
+
                /**
                 * Class member get overloading
                 *
@@ -37,7 +37,7 @@
                function __get($name) {
                        return $this->fields[$name];
                }
-               
+
                /**
                 * Class member set overloading
                 *
                 */
                function __set($name, $value) {
                        $this->fields[$name] = $value;
-                       
+
                        return true;
-               }       
+               }
        }
-       
+
        /**
         * @class SelectFieldQueryComponent Class representing a select field.
         * This class represents a select field component.
         * @author Curverider Ltd
         * @see Query
         */
-       class SelectFieldQueryComponent extends QueryComponent 
+       class SelectFieldQueryComponent extends QueryComponent
        {
                /**
                 * Construct a select field component
-                * 
+                *
                 * @param string $table The table containing the field.
                 * @param string $field The field or "*"
                 */
-               function __construct($table, $field) 
+               function __construct($table, $field)
                {
                        global $CONFIG;
-                       
+
                        $this->table = $CONFIG->dbprefix . sanitise_string($table);
                        $this->field = sanitise_string($field);
                }
-               
-               function __toString() 
+
+               function __toString()
                {
                        return "{$this->table}.{$this->field}";
                }
        }
-       
+
        /**
         * @class LimitOffsetQueryComponent
         * Limit and offset clauses of a query.
@@ -90,7 +90,7 @@
        {
                /**
                 * Specify a limit and an offset.
-                * 
+                *
                 * @param int $limit The limit.
                 * @param int $offset The offset.
                 */
                        $this->limit = (int)$limit;
                        $this->offset = (int)$offset;
                }
-               
+
                function __toString()
                {
                        return "limit {$this->offset}, {$this->limit}";
                }
        }
-       
+
        /**
         * @class OrderQueryComponent
         * Order the query results.
                function __construct($table, $field, $order = "asc")
                {
                        global $CONFIG;
-                       
+
                        $this->table = $CONFIG->dbprefix . sanitise_string($table);
                        $this->field = sanitise_string($field);
                        $this->order = sanitise_string($order);
                }
-               
+
                function __toString()
                {
                        return "order by {$this->table}.{$this->field} {$this->order}";
                }
        }
-       
+
        /**
         * @class TableQueryComponent
         * List of tables to select from or insert into.
                function __construct($table)
                {
                        global $CONFIG;
-                       
+
                        $this->table = $CONFIG->dbprefix . sanitise_string($table);
                }
-               
+
                function __toString()
                {
                        return $this->table;
                }
        }
-       
+
        /**
         * @class AccessControlQueryComponent
         * Access control component.
        {
                /**
                 * Construct the ACL.
-                * 
+                *
                 * @param string $acl_table The table where the access control field is.
                 * @param string $acl_field The field containing the access control.
                 * @param string $object_owner_table The table containing the owner information for the stuff you're retrieving.
                function __construct($acl_table = "entities", $acl_field = "access_id", $object_owner_table = "entities", $object_owner_id_field = "owner_guid")
                {
                        global $CONFIG;
-                       
+
                        $this->acl_table = $CONFIG->dbprefix . sanitise_string($acl_table);
                        $this->acl_field = sanitise_string($acl_field);
                        $this->object_owner_table = $CONFIG->dbprefix . sanitise_string($object_owner_table);
                        $this->object_owner_id_field = sanitise_string($object_owner_id_field);
                }
-               
+
                function __toString()
                {
                        //$access = get_access_list();
                        // $object_owner_id_field = "owner_guid"
                        // TODO: recode get_access_sql_suffix to make it possible to specify alternate field names
                        return "and ".get_access_sql_suffix($this->acl_table); // Add access controls
-                       
+
                        //return "and ({$this->acl_table}.{$this->acl_field} in {$access} or ({$this->acl_table}.{$this->acl_field} = 0 and {$this->object_owner_table}.{$this->object_owner_id_field} = {$_SESSION['id']}))";
                }
        }
-       
+
        /**
         * @class JoinQueryComponent Join query.
         * Represents a join query.
                 * Construct a join query.
                 * @param string $table Table one to join...
                 * @param string $field Field 1 with...
-                * @param string $table2 Table 2 ... 
+                * @param string $table2 Table 2 ...
                 * @param string $field2 Field...
                 * @param string $operator Using this operator
                 */
-               function __construct($table1, $field1, $table2, $field2, $operator = "=") 
+               function __construct($table1, $field1, $table2, $field2, $operator = "=")
                {
                        global $CONFIG;
-                       
+
                        $this->table1 = $CONFIG->dbprefix . sanitise_string($table1);
                        $this->field1 = sanitise_string($field1);
                        $this->table2 = $CONFIG->dbprefix . sanitise_string($table2);
                        $this->field2 = sanitise_string($field2);
                        $this->operator = sanitise_string($operator);
                }
-               
-               function __toString() 
+
+               function __toString()
                {
                        return "join {$this->table2} on {$this->$table}.{$this->$field} {$this->$operator} {$this->$table2}.{$this->$field2}";
                }
        }
-       
+
        /**
         * @class SetQueryComponent Set query.
         * Represents an update set query.
                function __construct($table, $field, $value)
                {
                        global $CONFIG;
-                       
-                       $this->table = $CONFIG->dbprefix . sanitise_string($table);
-                       $this->field = sanitise_string($field);
-                       if (is_numeric($value))
-                               $this->value = (int)$value;
-                       else
-                               $this->value = "'".sanitise_string($value)."'";
+
+                       $this->table = $CONFIG->dbprefix . sanitise_string($table);
+                       $this->field = sanitise_string($field);
+                       if (is_numeric($value))
+                               $this->value = (int)$value;
+                       else
+                               $this->value = "'".sanitise_string($value)."'";
                }
-               
-               function __toString() 
+
+               function __toString()
                {
                        return "{$this->table}.{$this->field}={$this->value}";
                }
        }
-       
+
        /**
         * @class WhereQueryComponent
         * A component of a where query.
        {
                /**
                 * A where query.
-                * 
+                *
                 * @param string $left_table The table on the left of the operator
                 * @param string $left_field The left field
                 * @param string $operator The operator eg "=" or "<"
                function __construct($left_table, $left_field, $operator, $right_table, $right_field, $link_operator = "and")
                {
                        global $CONFIG;
-                       
+
                        $this->link_operator = sanitise_string($link_operator);
-                       $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table);
-                       $this->left_field = sanitise_string($left_field);
-                       $this->operator = sanitise_string($operator);
-                       $this->right_table = $CONFIG->dbprefix . sanitise_string($right_table);
-                       $this->right_field = sanitise_string($right_field);
+                       $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table);
+                       $this->left_field = sanitise_string($left_field);
+                       $this->operator = sanitise_string($operator);
+                       $this->right_table = $CONFIG->dbprefix . sanitise_string($right_table);
+                       $this->right_field = sanitise_string($right_field);
                }
-               
+
                /**
                 * Return the SQL without the link operator.
                 */
                {
                        return "{$this->left_table }.{$this->left_field} {$this->operator} {$this->right_table}.{$this->right_field}";
                }
-               
-               function __toString() 
+
+               function __toString()
                {
                        return "{$this->link_operator} " . $this->toStringNoLink();
                }
        }
-       
+
        /**
         * @class WhereStaticQueryComponent
         * A component of a where query where there is no right hand table, rather a static value.
        {
                /**
                 * A where query.
-                * 
+                *
                 * @param string $left_table The table on the left of the operator
                 * @param string $left_field The left field
                 * @param string $operator The operator eg "=" or "<"
                function __construct($left_table, $left_field, $operator, $value, $link_operator = "and")
                {
                        global $CONFIG;
-                       
+
                        $this->link_operator = sanitise_string($link_operator);
-                       $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table);
-                       $this->left_field = sanitise_string($left_field);
-                       $this->operator = sanitise_string($operator);
-                       if (is_numeric($value))
-                               $this->value = (int)$value;
-                       else
-                               $this->value = "'".sanitise_string($value)."'";
+                       $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table);
+                       $this->left_field = sanitise_string($left_field);
+                       $this->operator = sanitise_string($operator);
+                       if (is_numeric($value))
+                               $this->value = (int)$value;
+                       else
+                               $this->value = "'".sanitise_string($value)."'";
                }
-               
+
                /**
                 * Return the SQL without the link operator.
                 */
                        return "{$this->left_table }.{$this->left_field} {$this->operator} {$this->value}";
                }
        }
-       
+
        /**
         * @class WhereSetQueryComponent
         * A where query that may contain other where queries (in brackets).
                /**
                 * Construct a subset of wheres.
                 *
-                * @param array $wheres An array of WhereQueryComponent 
+                * @param array $wheres An array of WhereQueryComponent
                 * @param string $link_operator How this where clause links with the previous clause, eg. "and" "or"
                 */
                function __construct(array $wheres, $link_operator = "and")
                        $this->link_operator = sanitise_string($link_operator);
                        $this->wheres = $wheres;
                }
-               
+
                public function toStringNoLink()
                {
                        $cnt = 0;
                        foreach ($this->wheres as $where) {
                                if (!($where instanceof WhereQueryComponent))
                                        throw new DatabaseException(elgg_echo('DatabaseException:WhereSetNonQuery'));
-                       
+
                                if (!$cnt)
                                        $string.= $where->toStringNoLink();
                                else
                                        $string.=" $where ";
-                               
-                               $cnt ++;                        
+
+                               $cnt ++;
                        }
                        $string .= ")";
-                       
+
                        return $string;
                }
        }
-       
+
        /**
         * @class QueryTypeQueryComponent
         * What type of query is this?
         * @author Curverider Ltd
         * @see Query
         */
-       abstract class QueryTypeQueryComponent extends QueryComponent 
+       abstract class QueryTypeQueryComponent extends QueryComponent
        {
                function __toString()
                {
-                       return $this->query_type; 
+                       return $this->query_type;
                }
        }
-       
+
        /**
         * @class SelectQueryTypeQueryComponent
         * A select query.
         * @author Curverider Ltd
         * @see Query
         */
-       class SelectQueryTypeQueryComponent extends QueryTypeQueryComponent 
+       class SelectQueryTypeQueryComponent extends QueryTypeQueryComponent
        {
-               function __construct() 
+               function __construct()
                {
-                       $this->query_type = "SELECT";   
+                       $this->query_type = "SELECT";
                }
        }
-       
+
        /**
         * @class InsertQueryTypeQueryComponent
         * An insert query.
         * @author Curverider Ltd
         * @see Query
         */
-       class InsertQueryTypeQueryComponent extends QueryTypeQueryComponent 
+       class InsertQueryTypeQueryComponent extends QueryTypeQueryComponent
        {
-               function __construct() 
+               function __construct()
                {
-                       $this->query_type = "INSERT INTO";      
+                       $this->query_type = "INSERT INTO";
                }
        }
-       
+
        /**
         * @class DeleteQueryTypeQueryComponent
         * A delete query.
         * @author Curverider Ltd
         * @see Query
         */
-       class DeleteQueryTypeQueryComponent extends QueryTypeQueryComponent 
+       class DeleteQueryTypeQueryComponent extends QueryTypeQueryComponent
        {
-               function __construct() 
+               function __construct()
                {
-                       $this->query_type = "DELETE FROM";      
+                       $this->query_type = "DELETE FROM";
                }
        }
-       
+
        /**
         * @class UpdateQueryTypeQueryComponent
         * An update query.
         * @author Curverider Ltd
         * @see Query
         */
-       class UpdateQueryTypeQueryComponent extends QueryTypeQueryComponent 
+       class UpdateQueryTypeQueryComponent extends QueryTypeQueryComponent
        {
-               function __construct() 
+               function __construct()
                {
-                       $this->query_type = "UPDATE";   
+                       $this->query_type = "UPDATE";
                }
        }
-       
+
        /**
         * @class Query Provides a framework to construct complex queries in a safer environment.
-        * 
+        *
         * The usage of this class depends on the type of query you are executing, but the basic idea is to
         * construct a query out of pluggable classes.
-        * 
-        * Once constructed SQL can be generated using the toString method, this should happen automatically 
+        *
+        * Once constructed SQL can be generated using the toString method, this should happen automatically
         * if you pass the Query object to get_data or similar.
-        * 
-        * To construct a query, create a new Query() object and begin populating it with the various classes 
+        *
+        * To construct a query, create a new Query() object and begin populating it with the various classes
         * that define the various aspects of the query.
-        * 
+        *
         * Notes:
-        *      - You do not have to specify things in any particular order, provided you specify all required 
+        *      - You do not have to specify things in any particular order, provided you specify all required
         *        components.
         *  - With database tables you do not have to specify your db prefix, this will be added automatically.
-        *  - When constructing your query keep an eye on the error log - any problems will get spit out here. 
-        *        Note also that __toString won't let you throw Exceptions (!!!) so these are caught and echoed to 
+        *  - When constructing your query keep an eye on the error log - any problems will get spit out here.
+        *        Note also that __toString won't let you throw Exceptions (!!!) so these are caught and echoed to
         *    the log instead.
-        * 
-        * Here is an example of a select query which requests some data out of the entities table with an 
+        *
+        * Here is an example of a select query which requests some data out of the entities table with an
         * order and limit that uses a subset where and some normal where queries:
-        * 
+        *
         * <blockquote>
         *              // Construct the query
         *              $query = new Query();
-        *              
+        *
         *              // Say which table we're interested in
         *              $query->addTable(new TableQueryComponent("entities"));
-        * 
+        *
         *              // What fields are we interested in
         *              $query->addSelectField(new SelectFieldQueryComponent("entities","*"));
-        * 
+        *
         *              // Add access control (Default access control uses default fields on entities table.
         *              // Note that it will error without something specified here!
         *              $query->setAccessControl(new AccessControlQueryComponent());
-        * 
+        *
         *              // Set a limit and offset, may be omitted.
         *              $query->setLimitAndOffset(new LimitOffsetQueryComponent(10,0));
-        * 
+        *
         *              // Specify the order, may be omitted
         *              $query->setOrder(new OrderQueryComponent("entities", "subtype", "desc"));
-        * 
+        *
         *              // Construct a where query
-        *              // 
+        *              //
         *              // This demonstrates a WhereSet which lets you have sub wheres, a
         *              // WhereStatic which lets you compare a table field against a value and a
         *              // Where which lets you compare a table/field with another table/field.
         *                              )
         *                      )
         *              );
-        * 
+        *
         *              get_data($query);
         * </blockquote>
-        * 
+        *
         * @author Curverider Ltd
         */
        class Query
        {
-               
+
                /// The limit of the query
-               private $limit_and_offset; 
-               
+               private $limit_and_offset;
+
                /// Fields to return on a query
                private $fields;
-               
+
                /// Tables to use in a from query
                private $tables;
-               
+
                /// Join tables
                private $joins;
-               
-               /// Set values 
+
+               /// Set values
                private $sets;
-               
+
                /// Where query
                private $where;
-               
+
                /// Order by
                private $order;
-               
+
                /// The query type
                private $query_type;
-               
+
                /// ACL
                private $access_control;
-               
+
                /**
                 * Construct query & initialise variables
                 */
-               function __construct() 
+               function __construct()
                {
                        $this->fields = array();
                        $this->tables = array();
                        $this->joins = array();
                        $this->where = array();
                        $this->sets = array();
-                       
+
                        $this->setQueryType(new SelectQueryTypeQueryComponent());
                }
-               
+
                /**
                 * Add limits and offsets to the query.
-                * 
+                *
                 * @param LimitOffsetQueryComponent $component The limit and offset.
                 */
                public function setLimitAndOffset(LimitOffsetQueryComponent $component) { $this->limit_and_offset = $component; }
-               
+
                /**
                 * Reset and set the field to the select statement.
-                * 
+                *
                 * @param SelectFieldQueryComponent $component Table and field component.
                 */
-               public function setSelectField(SelectFieldQueryComponent $component) 
+               public function setSelectField(SelectFieldQueryComponent $component)
                {
                        $this->fields = array();
                        return $this->addSelectField($component);
                }
-               
+
                /**
                 * Add a select field.
-                * 
+                *
                 * @param SelectFieldQueryComponent $component Add a component.
                 */
                public function addSelectField(SelectFieldQueryComponent $component) { $this->fields[] = $component; }
-               
+
                /**
                 * Add a join to the component.
-                * 
+                *
                 * @param JoinQueryComponent $component The join.
                 */
                public function addJoin(JoinQueryComponent $component) { $this->joins[] = $component; }
-               
+
                /**
                 * Set a field value in an update or insert statement.
-                * 
+                *
                 * @param SetQueryComponent $component Fields to set.
                 */
                public function addSet(SetQueryComponent $component) { $this->sets[] = $component; }
-               
+
                /**
                 * Set the query type, i.e. "select", "update", "insert" & "delete".
-                * 
+                *
                 * @param QueryTypeQueryComponent $component The query type.
                 */
                public function setQueryType(QueryTypeQueryComponent $component) { $this->query_type = $component; }
-               
+
                /**
                 * Attach an order component.
-                * 
+                *
                 * @param OrderQueryComponent $component The order component.
                 */
                public function setOrder(OrderQueryComponent $component) { $this->order = $component; }
-               
+
                /**
                 * Add a table to the query.
-                * 
+                *
                 * @param TableQueryComponent $component Table to add.
                 */
                public function addTable(TableQueryComponent $component) { $this->tables[] = $component; }
-               
+
                /**
                 * Add a where clause to the query.
-                * 
+                *
                 * @param WhereQueryComponent $component The where component
                 */
                public function addWhere(WhereQueryComponent $component) { $this->where[] = $component; }
-               
+
                /**
                 * Set access control.
-                * 
+                *
                 * @param AccessControlQueryComponent $component Access control.
                 */
                public function setAccessControl(AccessControlQueryComponent $component) { $this->access_control = $component; }
-               
+
                public function __toString()
                {
                        global $CONFIG;
-                       
+
                        $sql = "";
-                       
+
                        try
-                       { 
+                       {
                                // Query prefix & fields
                                if (!empty($this->query_type))
                                {
                                        $sql .= "{$this->query_type} ";
-                                       
+
                                        if (!empty($this->fields))
                                        {
                                                $fields = "";
-                                               
+
                                                foreach ($this->fields as $field)
-                                                       $fields .= "$field";    
-                                               
+                                                       $fields .= "$field";
+
                                                $sql .= " $fields from ";
                                        }
                                        else
                                }
                                else
                                        throw new DatabaseException(elgg_echo('DatabaseException:UnspecifiedQueryType'));
-                                               
+
                                // Tables
-                               if (!empty($this->tables)) 
+                               if (!empty($this->tables))
                                {
-                                       foreach($this->tables as $table) 
+                                       foreach($this->tables as $table)
                                                $sql .= "$table, ";
-                                               
+
                                        $sql = trim($sql, ", ");
                                }
                                else
                                        throw new DatabaseException(elgg_echo('DatabaseException:NoTablesSpecified'));
-                               
+
                                // Joins on select queries
-                               if ($this->query_type->query_type == 'select') 
+                               if ($this->query_type->query_type == 'select')
                                {
-                                       if (!empty($this->joins)) 
-                                       {       
-                                               foreach($this->joins as $join) 
+                                       if (!empty($this->joins))
+                                       {
+                                               foreach($this->joins as $join)
                                                        $sql .= "$join ";
                                        }
                                }
-                               
+
                                // Setting values
                                if (
-                                       ($this->query_type->query_type == 'update') || 
+                                       ($this->query_type->query_type == 'update') ||
                                        ($this->query_type->query_type == 'insert')
-                               ) 
+                               )
                                {
                                        $sql .= "set ";
-                                       
+
                                        foreach ($this->sets as $set)
                                                $sql .= "$set, ";
-                                               
+
                                        $sql = trim($sql, ", ") . " ";
                                }
-                               
+
                                // Where
                                if (!empty($this->where))
                                {
                                        $sql .= " where 1 ";
-                                       
+
                                        foreach ($this->where as $where)
                                                $sql .= "$where ";
                                }
-       
+
                                // Access control
-                               if (!empty($this->access_control)) 
+                               if (!empty($this->access_control))
                                {
-                               
+
                                        // Catch missing Where
                                        if (empty($this->where))
                                                $sql .= " where 1 ";
-                                       
+
                                        $sql .= "{$this->access_control} ";
-                               } 
+                               }
                                else
                                        throw new DatabaseException(elgg_echo('DatabaseException:NoACL'));
-                                       
+
                                // Order by
                                if (!empty($this->order))
                                        $sql .= "{$this->order} ";
-                                       
+
                                // Limits
                                if (!empty($this->limit_and_offset))
                                        $sql .= "{$this->limit_and_offset} ";
-                               
-                               
-                               
+
+
+
                        } catch (Exception $e) {
                                trigger_error($e, E_USER_WARNING);
                        }
-                       
-                                       
+
+
                        return $sql;
                }
-               
+
        }
-       
+
        /**
         * @class SimpleQuery A wrapper for Query which provides simple interface for common functions.
-        * 
-        * This class provides simple interface functions for constructing a (reasonably) standard database 
+        *
+        * This class provides simple interface functions for constructing a (reasonably) standard database
         * query.
-        * 
+        *
         * The constructor for this class sets a number of defaults, for example sets default access controls
         * and a limit and offset - to change this then set it manually.
-        * 
+        *
         * @author Curverider Ltd
         * @see Query
         */
        class SimpleQuery extends Query
        {
-               function __construct() 
+               function __construct()
                {
                        parent::__construct();
-                       
+
                        // Set a default query type (select)
                        $this->simpleQueryType();
-                       
+
                        // Set a default access control
                        $this->simpleAccessControl();
-                       
+
                        // Set default limit and offset
                        $this->simpleLimitAndOffset();
                }
-               
+
                /**
                 * Set the query type.
-                * 
+                *
                 * @param string $type The type of search - available are "select", "update", "delete", "insert".
                 */
                public function simpleQueryType($type = "select")
                {
                        $type = strtolower(sanitise_string($type));
-                       
+
                        switch ($type)
                        {
                                case "insert" :
-                                       return $this->setQueryType(InsertQueryTypeQueryComponent()); 
+                                       return $this->setQueryType(InsertQueryTypeQueryComponent());
                                break;
-                               case "delete" : 
+                               case "delete" :
                                        return $this->setQueryType(DeleteQueryTypeQueryComponent());
                                break;
                                case "update" :
-                                        return $this->setQueryType(UpdateQueryTypeQueryComponent());
+                                       return $this->setQueryType(UpdateQueryTypeQueryComponent());
                                break;
                                default: return $this->setQueryType(SelectQueryTypeQueryComponent());
                        }
 
                /**
                 * Set a field to query in a select statement.
-                * 
+                *
                 * @param string $table Table to query.
                 * @param string $field Field in that table.
                 */
                public function simpleSelectField($table, $field) { return $this->setSelectField(new SelectFieldQueryComponent($table, $field)); }
-               
+
                /**
                 * Add a select field to query in a select statement.
-                * 
+                *
                 * @param string $table Table to query.
-                * @param string $field Field in that table. 
+                * @param string $field Field in that table.
                 */
                public function simpleAddSelectField($table, $field) { return $this->addSelectField(new SelectFieldQueryComponent($table, $field)); }
-               
+
                /**
                 * Add a set value to an update query.
-                * 
+                *
                 * @param string $table The table to update.
                 * @param string $field The field in the table.
                 * @param mixed $value The value to set it to.
                 */
                public function simpleSet($table, $field, $value) { return $this->addSet(new SetQueryComponent($table, $field, $value)); }
-               
+
                /**
                 * Add a join to the table.
-                * 
+                *
                 * @param string $table Table one to join...
                 * @param string $field Field 1 with...
-                * @param string $table2 Table 2 ... 
+                * @param string $table2 Table 2 ...
                 * @param string $field2 Field...
-                * @param string $operator Using this operator 
+                * @param string $operator Using this operator
                 */
                public function simpleJoin($table1, $field1, $table2, $field2, $operator = "=") { return $this->addJoin(new JoinQueryComponent($table1, $field1, $table2, $field2, $operator)); }
-               
+
                /**
                 * Add a table to the query.
-                * 
+                *
                 * @param string $table The table.
                 */
                public function simpleTable($table) { return $this->addTable(new TableQueryComponent($table)); }
 
                /**
                 * Compare one table/field to another table/field.
-                * 
+                *
                 * @param string $left_table The table on the left of the operator
                 * @param string $left_field The left field
                 * @param string $operator The operator eg "=" or "<"
                 * @param string $link_operator How this where clause links with the previous clause, eg. "and" "or"
                 */
                public function simpleWhereOnTable($left_table, $left_field, $operator, $right_table, $right_field, $link_operator = "and") { return $this->addWhere(new WhereQueryComponent($left_table, $left_field, $operator, $right_table, $right_field, $link_operator)); }
-               
+
                /**
                 * Compare one table/field to a value.
-                * 
+                *
                 * @param string $left_table The table on the left of the operator
                 * @param string $left_field The left field
                 * @param string $operator The operator eg "=" or "<"
                 * @param string $link_operator How this where clause links with the previous clause, eg. "and" "or"
                 */
                public function simpleWhereOnValue($left_table, $left_field, $operator, $value, $link_operator = "and") { return $this->addWhere(new WhereStaticQueryComponent($left_table, $left_field, $operator, $value, $link_operator)); }
-               
+
                /**
                 * Set access control.
-                * 
+                *
                 * @param string $acl_table The table where the access control field is.
                 * @param string $acl_field The field containing the access control.
                 * @param string $object_owner_id_field The field in $object_owner_table containing the owner information.
 
                /**
                 * Set the limit and offset.
-                * 
+                *
                 * @param int $limit The limit.
                 * @param int $offset The offset.
                 */
                public function simpleLimitAndOffset($limit = 25, $offset = 0) { return $this->setLimitAndOffset(new LimitOffsetQueryComponent($limit, $offset)); }
-               
+
                /**
                 * Set the order query.
-                * 
+                *
                 * @param string $table The table to query
                 * @param string $field The field to query
                 * @param string $order Order the query
                 */
-               public function simpleOrder($table, $field, $order = "desc") 
+               public function simpleOrder($table, $field, $order = "desc")
                {
                        $table = sanitise_string($table);
                        $field = sanitise_string($field);
                        $order = strtolower(sanitise_string($order));
-                        
+
                        return $this->setOrder(new OrderQueryComponent($table, $field, $order)); break;
                }
        }
-?>
\ No newline at end of file
index 27a9917bad8b2aa8af4e2c6fa4fa3a4115370e26..22d3c1faa7e551764074fd181fa1ba68a05facf6 100644 (file)
 <?php
+/**
+ * Elgg relationships.
+ * Stub containing relationship functions, making import and export easier.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @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
+       {
        /**
-        * Elgg relationships.
-        * Stub containing relationship functions, making import and export easier.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd <info@elgg.com>
-        * @link http://elgg.org/
+        * This contains the site's main properties (id, etc)
+        * @var array
         */
+       protected $attributes;
 
        /**
-        * Relationship class.
-        * 
-        * @author Curverider Ltd
-        * @package Elgg
-        * @subpackage Core
+        * Construct a new site object, optionally from a given id value or row.
+        *
+        * @param mixed $id
         */
-       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
-                */
-               protected 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
-                */
-               protected function __set($name, $value) {
-                       $this->attributes[$name] = $value;
-                       return true;
-               }
+       function __construct($id = null) {
+               $this->attributes = array();
 
-               /**
-                * Save the relationship
-                *
-                * @return int the relationship id
-                */
-               public function save()
-               {
-                       if ($this->id > 0)
-                       {
-                               delete_relationship($this->id);
+               if (!empty($id)) {
+                       if ($id instanceof stdClass) {
+                               $relationship = $id; // Create from db row
+                       } else {
+                               $relationship = get_relationship($id);
                        }
 
-                       $this->id = add_entity_relationship($this->guid_one, $this->relationship, $this->guid_two);
-                       if (!$this->id) throw new IOException(sprintf(elgg_new('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;
+                       if ($relationship) {
+                               $objarray = (array) $relationship;
+                               foreach($objarray as $key => $value) {
+                                       $this->attributes[$key] = $value;
                                }
                        }
                }
-               
-               // 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);
-               } 
-       }
-       
-       
+       }
+
        /**
-        * Convert a database row to a new ElggRelationship
+        * Class member get overloading
         *
-        * @param stdClass $row
-        * @return stdClass or ElggMetadata
+        * @param string $name
+        * @return mixed
         */
-       function row_to_elggrelationship($row) 
-       {
-               if (!($row instanceof stdClass))
-                       return $row;
-                       
-               return new ElggRelationship($row);
+       protected function __get($name) {
+               if (isset($this->attributes[$name])) {
+                       return $this->attributes[$name];
+               }
+
+               return null;
        }
-       
+
        /**
-        * Return a relationship.
+        * Class member set overloading
         *
-        * @param int $id
+        * @param string $name
+        * @param mixed $value
+        * @return mixed
         */
-       function get_relationship($id)
-       {
-               global $CONFIG;
-               
-               $id = (int)$id;
-               
-               return row_to_elggrelationship(get_data_row("SELECT * from {$CONFIG->dbprefix}entity_relationships where id=$id"));
+       protected function __set($name, $value) {
+               $this->attributes[$name] = $value;
+               return true;
        }
-       
+
        /**
-        * Delete a specific relationship.
+        * Save the relationship
         *
-        * @param int $id
+        * @return int the relationship id
         */
-       function delete_relationship($id)
-       {
-               global $CONFIG;
-               
-               $id = (int)$id;
-               
-               $result = delete_data("delete from {$CONFIG->dbprefix}entity_relationships where id=$id");
-               
-               return $result;
-       }
-       
+       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_new('IOException:UnableToSaveNew'), get_class()));
+               }
+
+               return $this->id;
+       }
+
        /**
-        * Define an arbitrary relationship between two entities.
-        * This relationship could be a friendship, a group membership or a site membership.
-        * 
-        * This function lets you make the statement "$guid_one has $relationship with $guid_two".
-        * 
-        * @param int $guid_one
-        * @param string $relationship 
-        * @param int $guid_two
+        * Delete a given relationship.
         */
-       function add_entity_relationship($guid_one, $relationship, $guid_two)
-       {
-               global $CONFIG;
-               
-               $guid_one = (int)$guid_one;
-               $relationship = sanitise_string($relationship);
-               $guid_two = (int)$guid_two;
-                       
-               // Check for duplicates
-               if (check_entity_relationship($guid_one, $relationship, $guid_two))
-                       return false;
-               
-               $result = insert_data("INSERT into {$CONFIG->dbprefix}entity_relationships (guid_one, relationship, guid_two) values ($guid_one, '$relationship', $guid_two)");
-               
-               if ($result!==false) {
-                       $obj = get_relationship($result);
-                       if (trigger_elgg_event('create', $relationship, $obj)) {
-                               return true;
-                       } else {
-                               delete_relationship($result);
-                       }
-               }
-                               
-               return false;
+       public function delete() {
+               return delete_relationship($this->id);
        }
-       
+
        /**
-        * Determine whether or not a relationship between two entities exists and returns the relationship object if it does
+        * Get a URL for this relationship.
         *
-        * @param int $guid_one The GUID of the entity "owning" the relationship
-        * @param string $relationship The type of relationship
-        * @param int $guid_two The GUID of the entity the relationship is with
-        * @return object|false Depending on success
+        * @return string
         */
-       function check_entity_relationship($guid_one, $relationship, $guid_two)
-       {
-               global $CONFIG;
-               
-               $guid_one = (int)$guid_one;
-               $relationship = sanitise_string($relationship);
-               $guid_two = (int)$guid_two;
-                       
-               if ($row = get_data_row("SELECT * FROM {$CONFIG->dbprefix}entity_relationships WHERE guid_one=$guid_one AND relationship='$relationship' AND guid_two=$guid_two limit 1")) {
-                       return $row;
-               }
-               return false;
+       public function getURL() {
+               return get_relationship_url($this->id);
        }
 
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
+
        /**
-        * Remove an arbitrary relationship between two entities.
-        * 
-        * @param int $guid_one
-        * @param string $relationship 
-        * @param int $guid_two
+        * Return an array of fields which can be exported.
         */
-       function remove_entity_relationship($guid_one, $relationship, $guid_two)
-       {
-               global $CONFIG;
-               
-               $guid_one = (int)$guid_one;
-               $relationship = sanitise_string($relationship);
-               $guid_two = (int)$guid_two;
-               
-               $obj = check_entity_relationship($guid_one, $relationship, $guid_two);
-               if ($obj == false) return false;
-               
-               if (trigger_elgg_event('delete', $relationship, $obj)) {
-                       return delete_data("DELETE from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid_one and relationship='$relationship' and guid_two=$guid_two");
-               } else {
-                       return false;
-               }
+       public function getExportableValues() {
+               return array(
+                       'id',
+                       'guid_one',
+                       'relationship',
+                       'guid_two'
+               );
        }
 
        /**
-        * Removes all arbitrary relationships originating from a particular entity
+        * Export this relationship
         *
-        * @param int $guid_one The GUID of the entity 
-        * @param string $relationship The name of the relationship (optionally)
-        * @param true|false $inverse Whether we're deleting inverse relationships (default false)
-        * @param string $type The type of entity to limit this relationship delete to (defaults to all)
-        * @return true|false Depending on success
+        * @return array
         */
-       function remove_entity_relationships($guid_one, $relationship = "", $inverse = false, $type = '') {
-               
-               global $CONFIG;
-               
-               $guid_one = (int) $guid_one;
-               
-               if (!empty($relationship)) {
-                       $relationship = sanitise_string($relationship);
-                       $where = "and er.relationship='$relationship'";
-               } else {
-                       $where = "";
+       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'));
                }
-               
-               if (!empty($type)) {
-                       $type = sanitise_string($type);
-                       if (!$inverse) {
-                               $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_two ";
-                       } else {
-                               $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_one ";
-                               $where .= " and ";
+
+               $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;
                        }
-                       $where .= " and e.type = '{$type}' ";
-               } else {
-                       $join = "";
-               }
-               
-               if (!$inverse) {
-                       $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_one={$guid_one} {$where}";
-                       return delete_data($sql);
-               } else {
-                       $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_two={$guid_one} {$where}";
-                       return delete_data($sql);
                }
-               
        }
 
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
+
        /**
-        * Get all the relationships for a given guid.
-        * 
-        * @param int $guid
+        * Return an identification for the object for storage in the system log.
+        * This id must be an integer.
+        *
+        * @return int
         */
-       function get_entity_relationships($guid)
-       {
-               global $CONFIG;
-               
-               $guid = (int)$guid;
-               
-               $query = "SELECT * from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid";
-               
-               return get_data($query, "row_to_elggrelationship");
-       }
-       
+       public function getSystemLogID() {
+               return $this->id;
+       }
+
        /**
-        * Return entities matching a given query joining against a relationship.
-        * 
-        * @param string $relationship The relationship eg "friends_of"
-        * @param int $relationship_guid The guid of the entity to use query
-        * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
-        * @param string $type 
-        * @param string $subtype
-        * @param int $owner_guid
-        * @param string $order_by
-        * @param int $limit
-        * @param int $offset
-        * @param boolean $count Set to true if you want to count the number of entities instead (default false)
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @return array|int|false An array of entities, or the number of entities, or false on failure
+        * Return the class name of the object.
         */
-       function get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0)
-       {
-               global $CONFIG;
-               
-               $relationship = sanitise_string($relationship);
-               $relationship_guid = (int)$relationship_guid;
-               $inverse_relationship = (bool)$inverse_relationship;
-               $type = sanitise_string($type);
-               $subtype = get_subtype_id($type, $subtype);
-               $owner_guid = (int)$owner_guid;
-               if ($order_by == "") $order_by = "time_created desc";
-               else $order_by = "time_created, {$order_by}";
-               $order_by = sanitise_string($order_by);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-               
-               //$access = get_access_list();
-               
-               $where = array();
-               
-               if ($relationship!="")
-                       $where[] = "r.relationship='$relationship'";
-               if ($relationship_guid)
-                       $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'");
-               if ($type != "")
-                       $where[] = "e.type='$type'";
-               if ($subtype)
-                       $where[] = "e.subtype=$subtype";
-               if ($owner_guid != "")
-                       $where[] = "e.container_guid='$owner_guid'";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               
-               // Select what we're joining based on the options
-               $joinon = "e.guid = r.guid_one";
-               if (!$inverse_relationship)
-                       $joinon = "e.guid = r.guid_two";        
-                       
-               if ($count) {
-                       $query = "SELECT count(distinct e.guid) as total ";
-               } else {
-                       $query = "SELECT distinct e.* ";
-               }
-               $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon where ";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
-                       }
-               }
-               return false;
-               
+       public function getClassName() {
+               return get_class($this);
        }
 
        /**
-        * Returns a viewable list of entities by relationship
-        *
-        * @see elgg_view_entity_list
-        * 
-        * @param string $relationship The relationship eg "friends_of"
-        * @param int $relationship_guid The guid of the entity to use query
-        * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
-        * @param string $type The type of entity (eg 'object')
-        * @param string $subtype The entity subtype
-        * @param int $owner_guid The owner (default: all)
-        * @param int $limit The number of entities to display on a page
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow gallery view 
-        * @param true|false $pagination Whether to display pagination (default: true)
-        * @return string The viewable list of entities
+        * 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.
         */
-       function list_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) {
-               
-               $limit = (int) $limit;
-               $offset = (int) get_input('offset');
-               $count = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset, true);
-               $entities = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset);
+       public function getObjectOwnerGUID() {
+               return $this->owner_guid;
+       }
 
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-               
+       /**
+        * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc
+        */
+       public function getType() {
+               return 'relationship';
        }
 
        /**
-        * Gets the number of entities by a the number of entities related to them in a particular way.
-        * This is a good way to get out the users with the most friends, or the groups with the most members.
-        *
-        * @param string $relationship The relationship eg "friends_of"
-        * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true)
-        * @param string $type The type of entity (default: all)
-        * @param string $subtype The entity subtype (default: all)
-        * @param int $owner_guid The owner of the entities (default: none)
-        * @param int $limit
-        * @param int $offset
-        * @param boolean $count Set to true if you want to count the number of entities instead (default false)
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @return array|int|false An array of entities, or the number of entities, or false on failure
+        * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.
         */
-       
-       function get_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0) {
-               
-               global $CONFIG;
-               
-               $relationship = sanitise_string($relationship);
-               $inverse_relationship = (bool)$inverse_relationship;
-               $type = sanitise_string($type);
-               if ($subtype AND !$subtype = get_subtype_id($type, $subtype))
-                       return false;
-               $owner_guid = (int)$owner_guid;
-               $order_by = sanitise_string($order_by);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-               
-               //$access = get_access_list();
-               
-               $where = array();
-               
-               if ($relationship!="")
-                       $where[] = "r.relationship='$relationship'";
-               if ($inverse_relationship) {
-                       $on = 'e.guid = r.guid_two';
-               } else {
-                       $on = 'e.guid = r.guid_one';
+       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;
                }
-               if ($type != "")
-                       $where[] = "e.type='$type'";
-               if ($subtype)
-                       $where[] = "e.subtype=$subtype";
-               if ($owner_guid != "")
-                       $where[] = "e.container_guid='$owner_guid'";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               
-               if ($count) {
-                       $query = "SELECT count(distinct e.guid) as total ";
-               } else {
-                       $query = "SELECT e.*, count(e.guid) as total ";
+       }
+
+       function offsetGet($key) {
+               if ( array_key_exists($key, $this->attributes) ) {
+                       return $this->attributes[$key];
                }
-               
-               $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} where ";
-               
-               if (!empty($where))
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               
-               if (!$count) {
-                       $query .= " group by e.guid ";
-                       $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
+       }
+
+       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);
+       }
+}
+
+
+/**
+ * Convert a database row to a new ElggRelationship
+ *
+ * @param stdClass $row
+ * @return stdClass or ElggMetadata
+ */
+function row_to_elggrelationship($row) {
+       if (!($row instanceof stdClass)) {
+               return $row;
+       }
+
+       return new ElggRelationship($row);
+}
+
+/**
+ * Return a relationship.
+ *
+ * @param int $id
+ */
+function get_relationship($id) {
+       global $CONFIG;
+
+       $id = (int)$id;
+
+       return row_to_elggrelationship(get_data_row("SELECT * from {$CONFIG->dbprefix}entity_relationships where id=$id"));
+}
+
+/**
+ * Delete a specific relationship.
+ *
+ * @param int $id
+ */
+function delete_relationship($id) {
+       global $CONFIG;
+
+       $id = (int)$id;
+
+       $result = delete_data("delete from {$CONFIG->dbprefix}entity_relationships where id=$id");
+
+       return $result;
+}
+
+/**
+ * Define an arbitrary relationship between two entities.
+ * This relationship could be a friendship, a group membership or a site membership.
+ *
+ * This function lets you make the statement "$guid_one has $relationship with $guid_two".
+ *
+ * @param int $guid_one
+ * @param string $relationship
+ * @param int $guid_two
+ */
+function add_entity_relationship($guid_one, $relationship, $guid_two) {
+       global $CONFIG;
+
+       $guid_one = (int)$guid_one;
+       $relationship = sanitise_string($relationship);
+       $guid_two = (int)$guid_two;
+
+       // Check for duplicates
+       if (check_entity_relationship($guid_one, $relationship, $guid_two)) {
+               return false;
+       }
+
+       $result = insert_data("INSERT into {$CONFIG->dbprefix}entity_relationships (guid_one, relationship, guid_two) values ($guid_one, '$relationship', $guid_two)");
+
+       if ($result!==false) {
+               $obj = get_relationship($result);
+               if (trigger_elgg_event('create', $relationship, $obj)) {
+                       return true;
                } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
-                       }
+                       delete_relationship($result);
                }
-               
+       }
+
+       return false;
+}
+
+/**
+ * Determine whether or not a relationship between two entities exists and returns the relationship object if it does
+ *
+ * @param int $guid_one The GUID of the entity "owning" the relationship
+ * @param string $relationship The type of relationship
+ * @param int $guid_two The GUID of the entity the relationship is with
+ * @return object|false Depending on success
+ */
+function check_entity_relationship($guid_one, $relationship, $guid_two) {
+       global $CONFIG;
+
+       $guid_one = (int)$guid_one;
+       $relationship = sanitise_string($relationship);
+       $guid_two = (int)$guid_two;
+
+       if ($row = get_data_row("SELECT * FROM {$CONFIG->dbprefix}entity_relationships WHERE guid_one=$guid_one AND relationship='$relationship' AND guid_two=$guid_two limit 1")) {
+               return $row;
+       }
+
+       return false;
+}
+
+/**
+ * Remove an arbitrary relationship between two entities.
+ *
+ * @param int $guid_one
+ * @param string $relationship
+ * @param int $guid_two
+ */
+function remove_entity_relationship($guid_one, $relationship, $guid_two) {
+       global $CONFIG;
+
+       $guid_one = (int)$guid_one;
+       $relationship = sanitise_string($relationship);
+       $guid_two = (int)$guid_two;
+
+       $obj = check_entity_relationship($guid_one, $relationship, $guid_two);
+       if ($obj == false) {
                return false;
-                       
        }
-       
-       /**
-        * Displays a human-readable list of entities
-        * 
-        * @param string $relationship The relationship eg "friends_of"
-        * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true)
-        * @param string $type The type of entity (eg 'object')
-        * @param string $subtype The entity subtype
-        * @param int $owner_guid The owner (default: all)
-        * @param int $limit The number of entities to display on a page
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow gallery view 
-        * @param true|false $pagination Whether to display pagination (default: true)
-        * @return string The viewable list of entities
-        */
-       
-       function list_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) {
-               
-               $limit = (int) $limit;
-               $offset = (int) get_input('offset');
-               $count = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,0,0,true);
-               $entities = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,$limit,$offset);
-
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-               
-       }
-       
-       /**
-        * Gets the number of entities by a the number of entities related to them in a particular way also constrained by
-        * metadata
-        *
-        * @param string $relationship The relationship eg "friends_of"
-        * @param int $relationship_guid The guid of the entity to use query
-        * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true)
-        * @param String $meta_name The metadata name
-        * @param String $meta_value The metadata value
-        * @param string $type The type of entity (default: all)
-        * @param string $subtype The entity subtype (default: all)
-        * @param int $owner_guid The owner of the entities (default: none)
-        * @param int $limit
-        * @param int $offset
-        * @param boolean $count Set to true if you want to count the number of entities instead (default false)
-        * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
-        * @return array|int|false An array of entities, or the number of entities, or false on failure
-        */
-       function get_entities_from_relationships_and_meta($relationship, $relationship_guid, $inverse_relationship = false, $meta_name = "", $meta_value = "", $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0)
-       {
-               
-               global $CONFIG;
-               
+
+       if (trigger_elgg_event('delete', $relationship, $obj)) {
+               return delete_data("DELETE from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid_one and relationship='$relationship' and guid_two=$guid_two");
+       } else {
+               return false;
+       }
+}
+
+/**
+ * Removes all arbitrary relationships originating from a particular entity
+ *
+ * @param int $guid_one The GUID of the entity
+ * @param string $relationship The name of the relationship (optionally)
+ * @param true|false $inverse Whether we're deleting inverse relationships (default false)
+ * @param string $type The type of entity to limit this relationship delete to (defaults to all)
+ * @return true|false Depending on success
+ */
+function remove_entity_relationships($guid_one, $relationship = "", $inverse = false, $type = '') {
+       global $CONFIG;
+
+       $guid_one = (int) $guid_one;
+
+       if (!empty($relationship)) {
                $relationship = sanitise_string($relationship);
-               $inverse_relationship = (bool)$inverse_relationship;
-               $relationship_guid = (int)$relationship_guid;
+               $where = "and er.relationship='$relationship'";
+       } else {
+               $where = "";
+       }
+
+       if (!empty($type)) {
                $type = sanitise_string($type);
-               if ($subtype AND !$subtype = get_subtype_id($type, $subtype))
-                       return false;
-               $owner_guid = (int)$owner_guid;
-               $order_by = sanitise_string($order_by);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $site_guid = (int) $site_guid;
-               if ($site_guid == 0)
-                       $site_guid = $CONFIG->site_guid;
-                       
-               $meta_n = get_metastring_id($meta_name);
-               $meta_v = get_metastring_id($meta_value);
-               
-               //$access = get_access_list();
-               
-               $where = array();
-               
-               if ($relationship!="")
-                       $where[] = "r.relationship='$relationship'";
-                       
-               $on = "e.guid = r.guid_one";
-               if (!$inverse_relationship)
-                       $on = "e.guid = r.guid_two";
-                       
-               if ($type != "")
-                       $where[] = "e.type='$type'";
-               if ($subtype)
-                       $where[] = "e.subtype=$subtype";
-               if ($owner_guid != "")
-                       $where[] = "e.container_guid='$owner_guid'";
-               if ($site_guid > 0)
-                       $where[] = "e.site_guid = {$site_guid}";
-               if ($relationship_guid)
-                       $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'");
-               
-                       
-               $metajoin = "";
-               if (($meta_name!=="") || ($meta_value!=="")) {
-                       $metajoin = " JOIN {$CONFIG->dbprefix}metadata m on e.guid=m.entity_guid";
-                       
-                       if ($meta_name!=="")
-                               $where[] = "m.name_id='$meta_n'";
-                       if ($meta_value!=="")
-                               $where[] = "m.value_id='$meta_v'";
-               }
-                       
-               if ($count) {
-                       $query = "SELECT count(distinct e.guid) as total ";
+               if (!$inverse) {
+                       $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_two ";
                } else {
-                       $query = "SELECT distinct e.*, count(e.guid) as total ";
+                       $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_one ";
+                       $where .= " and ";
                }
-               
-               $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} {$metajoin} where ";
-               
-               if (!empty($where))
-               foreach ($where as $w)
+               $where .= " and e.type = '{$type}' ";
+       } else {
+               $join = "";
+       }
+
+       if (!$inverse) {
+               $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_one={$guid_one} {$where}";
+               return delete_data($sql);
+       } else {
+               $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_two={$guid_one} {$where}";
+               return delete_data($sql);
+       }
+}
+
+/**
+ * Get all the relationships for a given guid.
+ *
+ * @param int $guid
+ */
+function get_entity_relationships($guid) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+
+       $query = "SELECT * from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid";
+
+       return get_data($query, "row_to_elggrelationship");
+}
+
+/**
+ * Return entities matching a given query joining against a relationship.
+ *
+ * @param string $relationship The relationship eg "friends_of"
+ * @param int $relationship_guid The guid of the entity to use query
+ * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
+ * @param string $type
+ * @param string $subtype
+ * @param int $owner_guid
+ * @param string $order_by
+ * @param int $limit
+ * @param int $offset
+ * @param boolean $count Set to true if you want to count the number of entities instead (default false)
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @return array|int|false An array of entities, or the number of entities, or false on failure
+ */
+function get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) {
+       global $CONFIG;
+
+       $relationship = sanitise_string($relationship);
+       $relationship_guid = (int)$relationship_guid;
+       $inverse_relationship = (bool)$inverse_relationship;
+       $type = sanitise_string($type);
+       $subtype = get_subtype_id($type, $subtype);
+       $owner_guid = (int)$owner_guid;
+       if ($order_by == "") {
+               $order_by = "time_created desc";
+       } else {
+               $order_by = "time_created, {$order_by}";
+       }
+       $order_by = sanitise_string($order_by);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       //$access = get_access_list();
+
+       $where = array();
+
+       if ($relationship!="") {
+               $where[] = "r.relationship='$relationship'";
+       }
+
+       if ($relationship_guid) {
+               $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'");
+       }
+
+       if ($type != "") {
+               $where[] = "e.type='$type'";
+       }
+
+       if ($subtype) {
+               $where[] = "e.subtype=$subtype";
+       }
+
+       if ($owner_guid != "") {
+               $where[] = "e.container_guid='$owner_guid'";
+       }
+
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       // Select what we're joining based on the options
+       $joinon = "e.guid = r.guid_one";
+       if (!$inverse_relationship) {
+               $joinon = "e.guid = r.guid_two";
+       }
+
+       if ($count) {
+               $query = "SELECT count(distinct e.guid) as total ";
+       } else {
+               $query = "SELECT distinct e.* ";
+       }
+       $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon where ";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+       $query .= get_access_sql_suffix("e"); // Add access controls
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Returns a viewable list of entities by relationship
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param string $relationship The relationship eg "friends_of"
+ * @param int $relationship_guid The guid of the entity to use query
+ * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of"
+ * @param string $type The type of entity (eg 'object')
+ * @param string $subtype The entity subtype
+ * @param int $owner_guid The owner (default: all)
+ * @param int $limit The number of entities to display on a page
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow gallery view
+ * @param true|false $pagination Whether to display pagination (default: true)
+ * @return string The viewable list of entities
+ */
+function list_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) {
+       $limit = (int) $limit;
+       $offset = (int) get_input('offset');
+       $count = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset, true);
+       $entities = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Gets the number of entities by a the number of entities related to them in a particular way.
+ * This is a good way to get out the users with the most friends, or the groups with the most members.
+ *
+ * @param string $relationship The relationship eg "friends_of"
+ * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true)
+ * @param string $type The type of entity (default: all)
+ * @param string $subtype The entity subtype (default: all)
+ * @param int $owner_guid The owner of the entities (default: none)
+ * @param int $limit
+ * @param int $offset
+ * @param boolean $count Set to true if you want to count the number of entities instead (default false)
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @return array|int|false An array of entities, or the number of entities, or false on failure
+ */
+
+function get_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0) {
+       global $CONFIG;
+
+       $relationship = sanitise_string($relationship);
+       $inverse_relationship = (bool)$inverse_relationship;
+       $type = sanitise_string($type);
+       if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) {
+               return false;
+       }
+       $owner_guid = (int)$owner_guid;
+       $order_by = sanitise_string($order_by);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       //$access = get_access_list();
+
+       $where = array();
+
+       if ($relationship!="") {
+               $where[] = "r.relationship='$relationship'";
+       }
+
+       if ($inverse_relationship) {
+               $on = 'e.guid = r.guid_two';
+       } else {
+               $on = 'e.guid = r.guid_one';
+       }
+       if ($type != "") {
+               $where[] = "e.type='$type'";
+       }
+
+       if ($subtype) {
+               $where[] = "e.subtype=$subtype";
+       }
+
+       if ($owner_guid != "") {
+               $where[] = "e.container_guid='$owner_guid'";
+       }
+
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+
+       if ($count) {
+               $query = "SELECT count(distinct e.guid) as total ";
+       } else {
+               $query = "SELECT e.*, count(e.guid) as total ";
+       }
+
+       $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} where ";
+
+       if (!empty($where)) {
+               foreach ($where as $w) {
                        $query .= " $w and ";
-               $query .= get_access_sql_suffix("e"); // Add access controls
-               if (($meta_name!=="") || ($meta_value!=="")) $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls
-               
-               if (!$count) {
-                       $query .= " group by e.guid ";
-                       $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit
-                       
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
-                       }
                }
-               
+       }
+       $query .= get_access_sql_suffix("e"); // Add access controls
+
+       if (!$count) {
+               $query .= " group by e.guid ";
+               $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Displays a human-readable list of entities
+ *
+ * @param string $relationship The relationship eg "friends_of"
+ * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true)
+ * @param string $type The type of entity (eg 'object')
+ * @param string $subtype The entity subtype
+ * @param int $owner_guid The owner (default: all)
+ * @param int $limit The number of entities to display on a page
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow gallery view
+ * @param true|false $pagination Whether to display pagination (default: true)
+ * @return string The viewable list of entities
+ */
+
+function list_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) {
+       $limit = (int) $limit;
+       $offset = (int) get_input('offset');
+       $count = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,0,0,true);
+       $entities = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,$limit,$offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Gets the number of entities by a the number of entities related to them in a particular way also constrained by
+ * metadata
+ *
+ * @param string $relationship The relationship eg "friends_of"
+ * @param int $relationship_guid The guid of the entity to use query
+ * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true)
+ * @param String $meta_name The metadata name
+ * @param String $meta_value The metadata value
+ * @param string $type The type of entity (default: all)
+ * @param string $subtype The entity subtype (default: all)
+ * @param int $owner_guid The owner of the entities (default: none)
+ * @param int $limit
+ * @param int $offset
+ * @param boolean $count Set to true if you want to count the number of entities instead (default false)
+ * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
+ * @return array|int|false An array of entities, or the number of entities, or false on failure
+ */
+function get_entities_from_relationships_and_meta($relationship, $relationship_guid, $inverse_relationship = false, $meta_name = "", $meta_value = "", $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0) {
+       global $CONFIG;
+
+       $relationship = sanitise_string($relationship);
+       $inverse_relationship = (bool)$inverse_relationship;
+       $relationship_guid = (int)$relationship_guid;
+       $type = sanitise_string($type);
+       if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) {
                return false;
        }
-       
-       /**
-        * Sets the URL handler for a particular relationship type
-        *
-        * @param string $function_name The function to register
-        * @param string $relationship_type The relationship type.
-        * @return true|false Depending on success
-        */
-       function register_relationship_url_handler($function_name, $relationship_type = "all") {
-               global $CONFIG;
-               
-               if (!is_callable($function_name)) return false;
-               
-               if (!isset($CONFIG->relationship_url_handler)) {
-                       $CONFIG->relationship_url_handler = array();
+
+       $owner_guid = (int)$owner_guid;
+       $order_by = sanitise_string($order_by);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $site_guid = (int) $site_guid;
+       if ($site_guid == 0) {
+               $site_guid = $CONFIG->site_guid;
+       }
+
+       $meta_n = get_metastring_id($meta_name);
+       $meta_v = get_metastring_id($meta_value);
+
+       //$access = get_access_list();
+
+       $where = array();
+
+       if ($relationship!="") {
+               $where[] = "r.relationship='$relationship'";
+       }
+
+       $on = "e.guid = r.guid_one";
+       if (!$inverse_relationship) {
+               $on = "e.guid = r.guid_two";
+       }
+
+       if ($type != "") {
+               $where[] = "e.type='$type'";
+       }
+       if ($subtype) {
+               $where[] = "e.subtype=$subtype";
+       }
+       if ($owner_guid != "") {
+               $where[] = "e.container_guid='$owner_guid'";
+       }
+       if ($site_guid > 0) {
+               $where[] = "e.site_guid = {$site_guid}";
+       }
+       if ($relationship_guid) {
+               $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'");
+       }
+
+
+       $metajoin = "";
+       if (($meta_name!=="") || ($meta_value!=="")) {
+               $metajoin = " JOIN {$CONFIG->dbprefix}metadata m on e.guid=m.entity_guid";
+
+               if ($meta_name!=="") {
+                       $where[] = "m.name_id='$meta_n'";
+               }
+               if ($meta_value!=="") {
+                       $where[] = "m.value_id='$meta_v'";
                }
-               
-               $CONFIG->relationship_url_handler[$relationship_type] = $function_name;
-               
-               return true;
-               
        }
-       
-       /**
-        * Get the url for a given relationship.
-        *
-        * @param unknown_type $id
-        * @return unknown
-        */
-       function get_relationship_url($id)
-       {
-               global $CONFIG;
-               
-               $id = (int)$id;
-               
-               if ($relationship = get_relationship($id))
-               {
-                       $view = elgg_get_viewtype(); 
-                               
-                       $guid = $relationship->guid_one;
-                       $type = $relationship->relationship;
-                       
-                       $url = "";
-                       
-                       $function = "";
-                       if (isset($CONFIG->relationship_url_handler[$type]))
-                               $function = $CONFIG->relationship_url_handler[$type];
-                       if (isset($CONFIG->relationship_url_handler['all']))
-                               $function = $CONFIG->relationship_url_handler['all'];
-                               
-                       if (is_callable($function)) {
-                               $url = $function($relationship);
-                       }
-                       
-                       if ($url == "") {
-                               
-                               $nameid = $relationship->id;
-                               
-                               $url = $CONFIG->wwwroot  . "export/$view/$guid/relationship/$nameid/";
-                       } 
-                       
-                       return $url;
-                       
+
+       if ($count) {
+               $query = "SELECT count(distinct e.guid) as total ";
+       } else {
+               $query = "SELECT distinct e.*, count(e.guid) as total ";
+       }
+
+       $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} {$metajoin} where ";
+
+       if (!empty($where)) {
+               foreach ($where as $w) {
+                       $query .= " $w and ";
                }
-               
+       }
+       $query .= get_access_sql_suffix("e"); // Add access controls
+       if (($meta_name!=="") || ($meta_value!=="")) {
+               $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls
+       }
+
+       if (!$count) {
+               $query .= " group by e.guid ";
+               $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit
+
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Sets the URL handler for a particular relationship type
+ *
+ * @param string $function_name The function to register
+ * @param string $relationship_type The relationship type.
+ * @return true|false Depending on success
+ */
+function register_relationship_url_handler($function_name, $relationship_type = "all") {
+       global $CONFIG;
+
+       if (!is_callable($function_name)) {
                return false;
        }
-       
-       /**** HELPER FUNCTIONS FOR RELATIONSHIPS OF TYPE 'ATTACHED' ****/
-       
-        /**
-     * Function to determine if the object trying to attach to other, has already done so
-     * @param int $guid_one This is the target object
-     * @param int $guid_two This is the object trying to attach to $guid_one
-     * @return true | false
-     **/
-     
-     function already_attached($guid_one, $guid_two){
-    
-         if($attached = check_entity_relationship($guid_one, "attached", $guid_two)){
-             return true;
-         }else{
-             return false;
-         }
-     }
-     
-     /**
-     * Function to get all objects attached to a particular object
-     * @param int $guid
-     * @param string $type - the type of object to return e.g. 'file', 'friend_of' etc
-     * @return an array of objects
-    **/
-         
-        function get_attachments($guid, $type=""){
-            
-            $attached = get_entities_from_relationship("attached", $guid, $inverse_relationship = false, $type, $subtype = "", $owner_guid = 0, $order_by = "time_created desc", $limit = 10, $offset = 0, $count = false, $site_guid = 0);
-            return $attached;
-           
-        }
-        
-     /**
-     * Function to remove a particular attachment between two objects
-     * @param int $guid_one This is the target object
-     * @param int $guid_two This is the object to remove from $guid_one
-     * @return a view 
-    **/
-         
-        function remove_attachment($guid_one, $guid_two){
-            
-            if(already_attached($guid_one, $guid_two))
-                remove_entity_relationship($guid_one, "attached", $guid_two);
-           
-        }
-        
-        
-     
-     /**
-     * Function to start the process of attaching one object to another
-     * @param int $guid_one This is the target object
-     * @param int $guid_two This is the object trying to attach to $guid_one
-     * @return a view 
-    **/
-         
-        function make_attachment($guid_one, $guid_two){
-            
-            if(!(already_attached($guid_one, $guid_two)))
-                if(add_entity_relationship($guid_one, "attached", $guid_two))
-                    return true;
-           
-        }
-       
-       /**
-        *  Handler called by trigger_plugin_hook on the "import" event.
-        */
-       function import_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params)
-       {
-               $element = $params['element'];
-               
-               $tmp = NULL;
-               
-               if ($element instanceof ODDRelationship)
-               {
-                       $tmp = new ElggRelationship();
-                       $tmp->import($element);
-                       
-                       return $tmp;
+
+       if (!isset($CONFIG->relationship_url_handler)) {
+               $CONFIG->relationship_url_handler = array();
+       }
+
+       $CONFIG->relationship_url_handler[$relationship_type] = $function_name;
+
+       return true;
+}
+
+/**
+ * Get the url for a given relationship.
+ *
+ * @param unknown_type $id
+ * @return unknown
+ */
+function get_relationship_url($id) {
+       global $CONFIG;
+
+       $id = (int)$id;
+
+       if ($relationship = get_relationship($id)) {
+               $view = elgg_get_viewtype();
+
+               $guid = $relationship->guid_one;
+               $type = $relationship->relationship;
+
+               $url = "";
+
+               $function = "";
+               if (isset($CONFIG->relationship_url_handler[$type])) {
+                       $function = $CONFIG->relationship_url_handler[$type];
+               }
+               if (isset($CONFIG->relationship_url_handler['all'])) {
+                       $function = $CONFIG->relationship_url_handler['all'];
+               }
+
+               if (is_callable($function)) {
+                       $url = $function($relationship);
                }
+
+               if ($url == "") {
+                       $nameid = $relationship->id;
+
+                       $url = $CONFIG->wwwroot  . "export/$view/$guid/relationship/$nameid/";
+               }
+
+               return $url;
        }
-       
-       /**
-        *  Handler called by trigger_plugin_hook on the "export" event.
-        */
-       function export_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params)
-       {
-               global $CONFIG;
-               
-               // Sanity check values
-               if ((!is_array($params)) && (!isset($params['guid'])))
-                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport'));
-                       
-               if (!is_array($returnvalue))
-                       throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue'));
-                       
-               $guid = (int)$params['guid'];
-               
-               $result = get_entity_relationships($guid);
-               
-               if ($result)
-               {
-                       foreach ($result as $r)
-                               $returnvalue[] = $r->export();
+
+       return false;
+}
+
+/**** HELPER FUNCTIONS FOR RELATIONSHIPS OF TYPE 'ATTACHED' ****/
+
+/**
+ * Function to determine if the object trying to attach to other, has already done so
+ * @param int $guid_one This is the target object
+ * @param int $guid_two This is the object trying to attach to $guid_one
+ * @return true | false
+ **/
+
+function already_attached($guid_one, $guid_two){
+       if ($attached = check_entity_relationship($guid_one, "attached", $guid_two)){
+               return true;
+       } else {
+               return false;
+       }
+}
+
+/**
+ * Function to get all objects attached to a particular object
+ * @param int $guid
+ * @param string $type - the type of object to return e.g. 'file', 'friend_of' etc
+ * @return an array of objects
+**/
+
+function get_attachments($guid, $type=""){
+       $attached = get_entities_from_relationship("attached", $guid, $inverse_relationship = false, $type, $subtype = "", $owner_guid = 0, $order_by = "time_created desc", $limit = 10, $offset = 0, $count = false, $site_guid = 0);
+       return $attached;
+}
+
+/**
+ * Function to remove a particular attachment between two objects
+ * @param int $guid_one This is the target object
+ * @param int $guid_two This is the object to remove from $guid_one
+ * @return a view
+**/
+
+function remove_attachment($guid_one, $guid_two){
+       if(already_attached($guid_one, $guid_two)) {
+               remove_entity_relationship($guid_one, "attached", $guid_two);
+       }
+}
+
+/**
+ * Function to start the process of attaching one object to another
+ * @param int $guid_one This is the target object
+ * @param int $guid_two This is the object trying to attach to $guid_one
+ * @return a view
+**/
+
+function make_attachment($guid_one, $guid_two){
+       if (!(already_attached($guid_one, $guid_two))) {
+               if (add_entity_relationship($guid_one, "attached", $guid_two)) {
+                       return true;
                }
-               
-               return $returnvalue;
-       }
-
-    /**
-     * An event listener which will notify users based on certain events.
-     *
-     * @param unknown_type $event
-     * @param unknown_type $object_type
-     * @param unknown_type $object
-     */
-       function relationship_notification_hook($event, $object_type, $object)
-       {
-               global $CONFIG;
-               
-               if (
-                       ($object instanceof ElggRelationship) &&
-                       ($event == 'create') &&
-                       ($object_type == 'friend')
-               )
-               {
-                       $user_one = get_entity($object->guid_one);
-                       $user_two = get_entity($object->guid_two);
-                       
-                       // Notify target user
-                       return notify_user($object->guid_two, $object->guid_one, sprintf(elgg_echo('friend:newfriend:subject'), $user_one->name), 
-                               sprintf(elgg_echo("friend:newfriend:body"), $user_one->name, $CONFIG->site->url . "pg/profile/" . $user_one->username)
-                       ); 
+       }
+}
+
+/**
+ *  Handler called by trigger_plugin_hook on the "import" event.
+ */
+function import_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params) {
+       $element = $params['element'];
+
+       $tmp = NULL;
+
+       if ($element instanceof ODDRelationship) {
+               $tmp = new ElggRelationship();
+               $tmp->import($element);
+
+               return $tmp;
+       }
+}
+
+/**
+ *  Handler called by trigger_plugin_hook on the "export" event.
+ */
+function export_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params) {
+       global $CONFIG;
+
+       // Sanity check values
+       if ((!is_array($params)) && (!isset($params['guid']))) {
+               throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport'));
+       }
+
+       if (!is_array($returnvalue)) {
+               throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue'));
+       }
+
+       $guid = (int)$params['guid'];
+
+       $result = get_entity_relationships($guid);
+
+       if ($result) {
+               foreach ($result as $r) {
+                       $returnvalue[] = $r->export();
                }
        }
-       
-       /** Register the import hook */
-       register_plugin_hook("import", "all", "import_relationship_plugin_hook", 3);
-       
-       /** Register the hook, ensuring entities are serialised first */
-       register_plugin_hook("export", "all", "export_relationship_plugin_hook", 3);
-       
-       /** Register event to listen to some events **/
-       register_elgg_event_handler('create','friend','relationship_notification_hook');
-?>
\ No newline at end of file
+
+       return $returnvalue;
+}
+
+/**
+ * An event listener which will notify users based on certain events.
+ *
+ * @param unknown_type $event
+ * @param unknown_type $object_type
+ * @param unknown_type $object
+ */
+function relationship_notification_hook($event, $object_type, $object) {
+       global $CONFIG;
+
+       if (
+               ($object instanceof ElggRelationship) &&
+               ($event == 'create') &&
+               ($object_type == 'friend')
+       )
+       {
+               $user_one = get_entity($object->guid_one);
+               $user_two = get_entity($object->guid_two);
+
+               // Notify target user
+               return notify_user($object->guid_two, $object->guid_one, sprintf(elgg_echo('friend:newfriend:subject'), $user_one->name),
+                       sprintf(elgg_echo("friend:newfriend:body"), $user_one->name, $CONFIG->site->url . "pg/profile/" . $user_one->username)
+               );
+       }
+}
+
+/** Register the import hook */
+register_plugin_hook("import", "all", "import_relationship_plugin_hook", 3);
+
+/** Register the hook, ensuring entities are serialised first */
+register_plugin_hook("export", "all", "export_relationship_plugin_hook", 3);
+
+/** Register event to listen to some events **/
+register_elgg_event_handler('create','friend','relationship_notification_hook');
\ No newline at end of file
index 510ec7b8ceb1ceb4102b9358b580d0cec9d18532..799af013cbafae33c7062507fb3614a7a6266661 100644 (file)
 <?php
+/**
+ * Elgg river 2.0.
+ * Functions for listening for and generating the river separately from the system log.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Elgg river 2.0.
-        * Functions for listening for and generating the river separately from the system log.
-        * 
-        * @package Elgg
-        * @subpackage Core
+/**
+ * Adds an item to the river.
+ *
+ * @param string $view The view that will handle the river item (must exist)
+ * @param string $action_type An arbitrary one-word string to define the action (eg 'comment', 'create')
+ * @param int $subject_guid The GUID of the entity doing the action
+ * @param int $object_guid The GUID of the entity being acted upon
+ * @param int $access_id The access ID of the river item (default: same as the object)
+ * @param int $posted The UNIX epoch timestamp of the river item (default: now)
+ * @return true|false Depending on success
+ */
+function add_to_river($view,$action_type,$subject_guid,$object_guid,$access_id = "",$posted = 0, $annotation_id = 0) {
+       // Sanitise variables
+       if (!elgg_view_exists($view)) {
+               return false;
+       }
+       if (!($subject = get_entity($subject_guid))) {
+               return false;
+       }
+       if (!($object = get_entity($object_guid))) {
+               return false;
+       }
+       if (empty($action_type)) {
+               return false;
+       }
+       if ($posted == 0) {
+               $posted = time();
+       }
+       if ($access_id === "") {
+               $access_id = $object->access_id;
+       }
+       $annotation_id = (int)$annotation_id;
+       $type = $object->getType();
+       $subtype = $object->getSubtype();
+       $action_type = sanitise_string($action_type);
 
-        * @author Curverider Ltd
+       // Load config
+       global $CONFIG;
 
-        * @link http://elgg.org/
-        */
+       // Attempt to save river item; return success status
+       return insert_data("insert into {$CONFIG->dbprefix}river " .
+               " set type = '{$type}', " .
+               " subtype = '{$subtype}', " .
+               " action_type = '{$action_type}', " .
+               " access_id = {$access_id}, " .
+               " view = '{$view}', " .
+               " subject_guid = {$subject_guid}, " .
+               " object_guid = {$object_guid}, " .
+               " posted = {$posted}, " .
+               " annotation_id = {$annotation_id} ");
+}
 
-       /**
-        * Adds an item to the river.
-        *
-        * @param string $view The view that will handle the river item (must exist)
-        * @param string $action_type An arbitrary one-word string to define the action (eg 'comment', 'create')
-        * @param int $subject_guid The GUID of the entity doing the action
-        * @param int $object_guid The GUID of the entity being acted upon
-        * @param int $access_id The access ID of the river item (default: same as the object) 
-        * @param int $posted The UNIX epoch timestamp of the river item (default: now)
-        * @return true|false Depending on success
-        */
-               function add_to_river($view,$action_type,$subject_guid,$object_guid,$access_id = "",$posted = 0, $annotation_id = 0)
-               {
-                                                               
-                       // Sanitise variables
-                               if (!elgg_view_exists($view)) return false;
-                               if (!($subject = get_entity($subject_guid))) return false;
-                               if (!($object = get_entity($object_guid))) return false;
-                               if (empty($action_type)) return false;
-                               if ($posted == 0) $posted = time();
-                               if ($access_id === "") $access_id = $object->access_id;
-                               $annotation_id = (int)$annotation_id;
-                               $type = $object->getType();
-                               $subtype = $object->getSubtype();
-                               $action_type = sanitise_string($action_type);
-                               
-                       // Load config
-                               global $CONFIG;
-                               
-                       // Attempt to save river item; return success status
-                               return insert_data("insert into {$CONFIG->dbprefix}river " .
-                                                                               " set type = '{$type}', " .
-                                                                               " subtype = '{$subtype}', " .
-                                                                               " action_type = '{$action_type}', " .
-                                                                               " access_id = {$access_id}, " .
-                                                                               " view = '{$view}', " .
-                                                                               " subject_guid = {$subject_guid}, " .
-                                                                               " object_guid = {$object_guid}, " .
-                                                                               " posted = {$posted}, " .
-                                                                               " annotation_id = {$annotation_id} ");
-                                                               
-               }
-               
-       /**
-        * Removes all items relating to a particular acting entity from the river
-        *
-        * @param int $subject_guid The GUID of the entity
-        * @return true|false Depending on success
-        */
-               function remove_from_river_by_subject(
-                                                                       $subject_guid
-                                                                                       ) {
-                       
-                       // Sanitise
-                               $subject_guid = (int) $subject_guid;
-                               
-                       // Load config
-                               global $CONFIG;
-                               
-                       // Remove
-                               return delete_data("delete from {$CONFIG->dbprefix}river where subject_guid = {$subject_guid}");
-                                                                                               
+/**
+ * Removes all items relating to a particular acting entity from the river
+ *
+ * @param int $subject_guid The GUID of the entity
+ * @return true|false Depending on success
+ */
+function remove_from_river_by_subject($subject_guid) {
+       // Sanitise
+       $subject_guid = (int) $subject_guid;
+
+       // Load config
+       global $CONFIG;
+
+       // Remove
+       return delete_data("delete from {$CONFIG->dbprefix}river where subject_guid = {$subject_guid}");
+}
+
+/**
+ * Removes all items relating to a particular entity being acted upon from the river
+ *
+ * @param int $object_guid The GUID of the entity
+ * @return true|false Depending on success
+ */
+function remove_from_river_by_object($object_guid) {
+       // Sanitise
+       $object_guid = (int) $object_guid;
+
+       // Load config
+       global $CONFIG;
+
+       // Remove
+       return delete_data("delete from {$CONFIG->dbprefix}river where object_guid = {$object_guid}");
+}
+
+/**
+ * Sets the access ID on river items for a particular object
+ *
+ * @param int $object_guid The GUID of the entity
+ * @param int $access_id The access ID
+ * @return true|false Depending on success
+ */
+function update_river_access_by_object($object_guid, $access_id) {
+       // Sanitise
+       $object_guid = (int) $object_guid;
+       $access_id = (int) $access_id;
+
+       // Load config
+       global $CONFIG;
+
+       // Remove
+       return update_data("update {$CONFIG->dbprefix}river set access_id = {$access_id} where object_guid = {$object_guid}");
+}
+
+/**
+ * Retrieves items from the river. All parameters are optional.
+ *
+ * @param int|array $subject_guid Acting entity to restrict to. Default: all
+ * @param int|array $object_guid Entity being acted on to restrict to. Default: all
+ * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank
+ * @param string $type The type of entity to restrict to. Default: all
+ * @param string $subtype The subtype of entity to restrict to. Default: all
+ * @param string $action_type The type of river action to restrict to. Default: all
+ * @param int $limit The number of items to retrieve. Default: 20
+ * @param int $offset The page offset. Default: 0
+ * @param int $posted_min The minimum time period to look at. Default: none
+ * @param int $posted_max The maximum time period to look at. Default: none
+ * @return array|false Depending on success
+ */
+function get_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '', $type = '',
+       $subtype = '', $action_type = '', $limit = 20, $offset = 0, $posted_min = 0, $posted_max = 0) {
+
+       // Get config
+       global $CONFIG;
+
+       // Sanitise variables
+       if (!is_array($subject_guid)) {
+               $subject_guid = (int) $subject_guid;
+       } else {
+               foreach($subject_guid as $key => $temp) {
+                       $subject_guid[$key] = (int) $temp;
                }
-               
-       /**
-        * Removes all items relating to a particular entity being acted upon from the river
-        *
-        * @param int $object_guid The GUID of the entity
-        * @return true|false Depending on success
-        */
-               function remove_from_river_by_object(
-                                                                       $object_guid
-                                                                                       ) {
-                       
-                       // Sanitise
-                               $object_guid = (int) $object_guid;
-                               
-                       // Load config
-                               global $CONFIG;
-                               
-                       // Remove
-                               return delete_data("delete from {$CONFIG->dbprefix}river where object_guid = {$object_guid}");
-                                                                                               
+       }
+       if (!is_array($object_guid)) {
+               $object_guid = (int) $object_guid;
+       } else {
+               foreach($object_guid as $key => $temp) {
+                       $object_guid[$key] = (int) $temp;
                }
+       }
+       if (!empty($type)) {
+               $type = sanitise_string($type);
+       }
+       if (!empty($subtype)) {
+               $subtype = sanitise_string($subtype);
+       }
+       if (!empty($action_type)) {
+               $action_type = sanitise_string($action_type);
+       }
+       $limit = (int) $limit;
+       $offset = (int) $offset;
+       $posted_min = (int) $posted_min;
+       $posted_max = (int) $posted_max;
+
+       // Construct 'where' clauses for the river
+       $where = array();
+       $where[] = str_replace("and enabled='yes'",'',str_replace('owner_guid','subject_guid',get_access_sql_suffix()));
 
-       /**
-        * Sets the access ID on river items for a particular object
-        *
-        * @param int $object_guid The GUID of the entity
-        * @param int $access_id The access ID
-        * @return true|false Depending on success
-        */
-               function update_river_access_by_object(
-                                                                       $object_guid, $access_id
-                                                                                       ) {
-                       
-                       // Sanitise
-                               $object_guid = (int) $object_guid;
-                               $access_id = (int) $access_id;
-                               
-                       // Load config
-                               global $CONFIG;
-                               
-                       // Remove
-                               return update_data("update {$CONFIG->dbprefix}river set access_id = {$access_id} where object_guid = {$object_guid}");
-                                                                                               
+       if (empty($subject_relationship)) {
+               if (!empty($subject_guid)) {
+                       if (!is_array($subject_guid)) {
+                               $where[] = " subject_guid = {$subject_guid} ";
+                       } else {
+                               $where[] = " subject_guid in (" . implode(',',$subject_guid) . ") ";
+                       }
                }
-               
-       /**
-        * Retrieves items from the river. All parameters are optional.
-        *
-        * @param int|array $subject_guid Acting entity to restrict to. Default: all
-        * @param int|array $object_guid Entity being acted on to restrict to. Default: all
-        * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank
-        * @param string $type The type of entity to restrict to. Default: all
-        * @param string $subtype The subtype of entity to restrict to. Default: all
-        * @param string $action_type The type of river action to restrict to. Default: all
-        * @param int $limit The number of items to retrieve. Default: 20
-        * @param int $offset The page offset. Default: 0
-        * @param int $posted_min The minimum time period to look at. Default: none
-        * @param int $posted_max The maximum time period to look at. Default: none
-        * @return array|false Depending on success
-        */
-               function get_river_items(
-                                                       $subject_guid = 0,
-                                                       $object_guid = 0,
-                                                       $subject_relationship = '',
-                                                       $type = '',
-                                                       $subtype = '',
-                                                       $action_type = '',
-                                                       $limit = 20,
-                                                       $offset = 0,
-                                                       $posted_min = 0,
-                                                       $posted_max = 0
-                         ) { 
-                               
-            // Get config
-               global $CONFIG;
-                               
-                       // Sanitise variables
-                               if (!is_array($subject_guid)) {
-                                       $subject_guid = (int) $subject_guid;
-                               } else {
-                                       foreach($subject_guid as $key => $temp) {
-                                               $subject_guid[$key] = (int) $temp;
-                                       }
+       } else {
+               if (!is_array($subject_guid)) {
+                       if ($entities = get_entities_from_relationship($subject_relationship,$subject_guid,false,'','',0,'',9999)) {
+                               $guids = array();
+                               foreach($entities as $entity) {
+                                       $guids[] = (int) $entity->guid;
                                }
-                if (!is_array($object_guid)) {
-                                       $object_guid = (int) $object_guid;
-                               } else {
-                                       foreach($object_guid as $key => $temp) {
-                                               $object_guid[$key] = (int) $temp;
-                                       }
-                               }
-                               if (!empty($type)) $type = sanitise_string($type);
-                               if (!empty($subtype)) $subtype = sanitise_string($subtype);
-                               if (!empty($action_type)) $action_type = sanitise_string($action_type);
-                               $limit = (int) $limit;
-                               $offset = (int) $offset;
-                               $posted_min = (int) $posted_min;
-                               $posted_max = (int) $posted_max;
-                               
-                       // Construct 'where' clauses for the river
-                               $where = array();
-                               $where[] = str_replace("and enabled='yes'",'',str_replace('owner_guid','subject_guid',get_access_sql_suffix()));
-                               
-                               if (empty($subject_relationship)) {
-                                       if (!empty($subject_guid))
-                                               if (!is_array($subject_guid)) {
-                                                       $where[] = " subject_guid = {$subject_guid} ";
-                                               } else {
-                                                       $where[] = " subject_guid in (" . implode(',',$subject_guid) . ") ";
-                                               }
-                               } else {
-                                       if (!is_array($subject_guid))
-                                               if ($entities = get_entities_from_relationship($subject_relationship,$subject_guid,false,'','',0,'',9999)) {
-                                                       $guids = array();
-                                                       foreach($entities as $entity) $guids[] = (int) $entity->guid;
-                                                       // $guids[] = $subject_guid;
-                                                       $where[] = " subject_guid in (" . implode(',',$guids) . ") "; 
-                                               } else {
-                                                       return array();
-                                               }
-                               }
-                               if (!empty($object_guid))
-                       if (!is_array($object_guid)) {
-                                               $where[] = " object_guid = {$object_guid} ";
-                                       } else {
-                                               $where[] = " object_guid in (" . implode(',',$object_guid) . ") ";
-                                       }
-                               if (!empty($type)) $where[] = " type = '{$type}' ";
-                               if (!empty($subtype)) $where[] = " subtype = '{$subtype}' ";
-                               if (!empty($action_type)) $where[] = " action_type = '{$action_type}' ";
-                               if (!empty($posted_min)) $where[] = " posted > {$posted_min} ";
-                               if (!empty($posted_max)) $where[] = " posted < {$posted_max} ";
-                               
-                               $whereclause = implode(' and ', $where);
-                               
-                       // Construct main SQL
-                               $sql = "select id,type,subtype,action_type,access_id,view,subject_guid,object_guid,posted,annotation_id from {$CONFIG->dbprefix}river where {$whereclause} order by posted desc limit {$offset},{$limit}";
-                               
-                       // Get data
-                               return get_data($sql);
-                       
+                               // $guids[] = $subject_guid;
+                               $where[] = " subject_guid in (" . implode(',',$guids) . ") ";
+                       } else {
+                               return array();
+                       }
+               }
+       }
+       if (!empty($object_guid))
+               if (!is_array($object_guid)) {
+                       $where[] = " object_guid = {$object_guid} ";
+               } else {
+                       $where[] = " object_guid in (" . implode(',',$object_guid) . ") ";
                }
-               
-       /**
-        * Returns a human-readable representation of a river item
-        *
-        * @see get_river_items
-        * 
-        * @param stdClass $item A river item object as returned from get_river_items
-        * @return string|false Depending on success
-        */
-               function elgg_view_river_item($item) {
-                       if (isset($item->view)) {
+       if (!empty($type)) {
+               $where[] = " type = '{$type}' ";
+       }
+       if (!empty($subtype)) {
+               $where[] = " subtype = '{$subtype}' ";
+       }
+       if (!empty($action_type)) {
+               $where[] = " action_type = '{$action_type}' ";
+       }
+       if (!empty($posted_min)) {
+               $where[] = " posted > {$posted_min} ";
+       }
+       if (!empty($posted_max)) {
+               $where[] = " posted < {$posted_max} ";
+       }
 
-                               $object = get_entity($item->object_guid);
-                               if (!$object) {
-                                       $body = elgg_view('river/item/noaccess');
-                               } else {
-                                       if (elgg_view_exists($item->view)) {
-                                               $body = elgg_view($item->view,array(
-                                                                                       'item' => $item
-                                                                                ));
-                                       }
-                               }
-                               return elgg_view('river/item/wrapper',array(
-                                                                       'item' => $item,
-                                                                       'body' => $body
-                                                                ));
-                               
+       $whereclause = implode(' and ', $where);
+
+       // Construct main SQL
+       $sql = "select id,type,subtype,action_type,access_id,view,subject_guid,object_guid,posted,annotation_id from {$CONFIG->dbprefix}river where {$whereclause} order by posted desc limit {$offset},{$limit}";
+
+       // Get data
+       return get_data($sql);
+}
+
+/**
+ * Returns a human-readable representation of a river item
+ *
+ * @see get_river_items
+ *
+ * @param stdClass $item A river item object as returned from get_river_items
+ * @return string|false Depending on success
+ */
+function elgg_view_river_item($item) {
+       if (isset($item->view)) {
+               $object = get_entity($item->object_guid);
+               if (!$object) {
+                       $body = elgg_view('river/item/noaccess');
+               } else {
+                       if (elgg_view_exists($item->view)) {
+                               $body = elgg_view($item->view,array(
+                                       'item' => $item
+                               ));
                        }
-                       return false;
                }
-               
-       /**
-        * Returns a human-readable version of the river.
-        *
-        * @param int|array $subject_guid Acting entity to restrict to. Default: all
-        * @param int|array $object_guid Entity being acted on to restrict to. Default: all
-        * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank
-        * @param string $type The type of entity to restrict to. Default: all
-        * @param string $subtype The subtype of entity to restrict to. Default: all
-        * @param string $action_type The type of river action to restrict to. Default: all
-        * @param int $limit The number of items to retrieve. Default: 20
-        * @param int $posted_min The minimum time period to look at. Default: none
-        * @param int $posted_max The maximum time period to look at. Default: none
-        * @return string Human-readable river.
-        */
-               function elgg_view_river_items($subject_guid = 0,
-                                                       $object_guid = 0,
-                                                       $subject_relationship = '',
-                                                       $type = '',
-                                                       $subtype = '',
-                                                       $action_type = '',
-                                                       $limit = 20,
-                                                       $posted_min = 0,
-                                                       $posted_max = 0,
-                                                       $pagination = true) {
-                                                               
-                       // Get input from outside world and sanitise it
-                               $offset = (int) get_input('offset',0);
-                               
-                       // Get river items, if they exist
-                               if ($riveritems = get_river_items($subject_guid,$object_guid,$subject_relationship,$type,$subtype,$action_type,($limit + 1),$offset,$posted_min,$posted_max)) {
+               return elgg_view('river/item/wrapper',array(
+                       'item' => $item,
+                       'body' => $body
+               ));
+       }
+       return false;
+}
 
-                                       return elgg_view('river/item/list',array(
-                                                                                       'limit' => $limit,
-                                                                                       'offset' => $offset,
-                                                                                       'items' => $riveritems,
-                                                                                       'pagination' => $pagination
-                                                                               ));
-                                       
-                               }
-                               
-                       return '';
-                               
-               }
+/**
+ * Returns a human-readable version of the river.
+ *
+ * @param int|array $subject_guid Acting entity to restrict to. Default: all
+ * @param int|array $object_guid Entity being acted on to restrict to. Default: all
+ * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank
+ * @param string $type The type of entity to restrict to. Default: all
+ * @param string $subtype The subtype of entity to restrict to. Default: all
+ * @param string $action_type The type of river action to restrict to. Default: all
+ * @param int $limit The number of items to retrieve. Default: 20
+ * @param int $posted_min The minimum time period to look at. Default: none
+ * @param int $posted_max The maximum time period to look at. Default: none
+ * @return string Human-readable river.
+ */
+function elgg_view_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '',
+       $type = '', $subtype = '', $action_type = '', $limit = 20, $posted_min = 0, $posted_max = 0, $pagination = true) {
+
+       // Get input from outside world and sanitise it
+       $offset = (int) get_input('offset',0);
+
+       // Get river items, if they exist
+       if ($riveritems = get_river_items($subject_guid,$object_guid,$subject_relationship,$type,$subtype,$action_type,($limit + 1),$offset,$posted_min,$posted_max)) {
+
+       return elgg_view('river/item/list',array(
+               'limit' => $limit,
+               'offset' => $offset,
+               'items' => $riveritems,
+               'pagination' => $pagination
+       ));
+
+       }
 
-?>
\ No newline at end of file
+       return '';
+}
\ No newline at end of file
index 222c0b6e9b4ff107545281825c9ebd41020be362..0f6c0a12dd07e1d812ddc21b0065e2b66c2dbb0c 100644 (file)
@@ -1,50 +1,52 @@
 <?php
-       /**
       * Elgg search helper functions.
-        * 
       * @package Elgg
       * @subpackage Core
       * @author Curverider Ltd <info@elgg.com>
       * @link http://elgg.org/
       */
+/**
+ * Elgg search helper functions.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Initialise search helper functions.
-        *
-        */
-       function search_init()
-       {
-               register_page_handler('search','search_page_handler');
+/**
+ * Initialise search helper functions.
+ *
+ */
+function search_init() {
+       register_page_handler('search','search_page_handler');
+}
+
+/**
+ * Page handler for search
+ *
+ * @param array $page Page elements from pain page handler
+ */
+function search_page_handler($page) {
+       global $CONFIG;
+
+       if(!get_input('tag')) {
+               set_input('tag', $page[0]);
        }
-       
-       /**
-        * Page handler for search
-        *
-        * @param array $page Page elements from pain page handler
-        */
-       function search_page_handler($page) 
-       {
-               global $CONFIG;
-               
-               if(!get_input('tag')) {
-                       set_input('tag', $page[0]);     
-               }
 
-               if (isset($page[0])) {
-                       switch ($page[0]) {
-                               case 'user' :
-                               case 'users' : include_once($CONFIG->path . "search/users.php"); break;
-                               
-                               case 'group' :
-                               case 'groups' : include_once($CONFIG->path . "search/groups.php"); break;
-                               
-                               default: include_once($CONFIG->path . "search/index.php");
-                       }
+       if (isset($page[0])) {
+               switch ($page[0]) {
+                       case 'user' :
+                       case 'users' :
+                               include_once($CONFIG->path . "search/users.php");
+                               break;
+
+                       case 'group' :
+                       case 'groups' :
+                               include_once($CONFIG->path . "search/groups.php");
+                               break;
+
+                       default:
+                               include_once($CONFIG->path . "search/index.php");
                }
-               else
-                       include_once($CONFIG->path . "search/index.php");
+       } else {
+               include_once($CONFIG->path . "search/index.php");
        }
+}
 
-       /** Register init system event **/
-       register_elgg_event_handler('init','system','search_init');
-?>
+/** Register init system event **/
+register_elgg_event_handler('init','system','search_init');
\ No newline at end of file
index e12a745c5de64678ee35763cb17f75392bd5e5ea..7a1375d46f7ad8ab1539ddbcc06e6cf711e190a7 100644 (file)
 <?php
+/**
+ * Elgg sites
+ * Functions to manage multiple or single sites in an Elgg install
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @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 {
        /**
-        * Elgg sites
-        * Functions to manage multiple or single sites in an Elgg install
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd <info@elgg.com>
-
-        * @link http://elgg.org/
+        * 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;
+       }
 
        /**
-        * ElggSite
-        * Representation of a "site" in the system.
-        * @author Curverider Ltd <info@elgg.com>
-        * @package Elgg
-        * @subpackage Core
+        * 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.
         */
-       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)); 
+       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)
-                               {                               
-                                        foreach ($guid->attributes as $key => $value)
-                                               $this->attributes[$key] = $value;
+                       }
+
+                       // Is $guid is an ElggSite? Use a copy constructor
+                       else if ($guid instanceof ElggSite) {
+                               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;
-                                               
+                       }
+
+                       // 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));
+                       }
+
+                       // 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'));
+                       }
+
+                       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())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter
-                       
-                       // 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'));
+       }
+
+       /**
+        * 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;
                }
-               
-               /**
-                * Delete this site.
-                */
-               public function delete() 
-               { 
-                       global $CONFIG;
-                       if ($CONFIG->site->getGUID() == $this->guid)
-                               throw new SecurityException('SecurityException:deletedisablecurrentsite');      
-                       
-                       return parent::delete();
+
+               // Check the type
+               if ($this->attributes['type']!='site') {
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
                }
-               
-               /**
-                * 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);
+
+               // 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'] ++;
                }
-               
-               /**
-                * 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',
-                       ));
+
+               // Now put these into the attributes array as core values
+               $objarray = (array) $row;
+               foreach($objarray as $key => $value) {
+                       $this->attributes[$key] = $value;
                }
-               
+
+               return true;
        }
 
        /**
-        * Return the site specific details of a site by a row.
-        * 
-        * @param int $guid
+        * Override the save function.
         */
-       function get_site_entity_as_row($guid)
-       {
-               global $CONFIG;
-               
-               $guid = (int)$guid;
-               
-               /*$row = retrieve_cached_entity_row($guid);
-               if ($row)
-               {
-                       // We have already cached this object, so retrieve its value from the cache
-                       if (isset($CONFIG->debug) && $CONFIG->debug)
-                               error_log("** Retrieving sub part of GUID:$guid from cache");
-                               
-                       return $row;
+       public function save() {
+               // Save generic stuff
+               if (!parent::save()) {
+                       return false;
                }
-               else
-               {*/
-                       // Object not cached, load it.
-                       if (isset($CONFIG->debug) && $CONFIG->debug == true)
-                               error_log("** Sub part of GUID:$guid loaded from DB");
-               
-                       return get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where guid=$guid");
-               //}
+
+               // Now save specific stuff
+               return create_site_entity($this->get('guid'), $this->get('name'), $this->get('description'), $this->get('url'));
        }
-       
+
        /**
-        * Create or update the extras table for a given site.
-        * Call create_entity first.
-        * 
-        * @param int $guid
-        * @param string $name
-        * @param string $description
-        * @param string $url
+        * Delete this site.
         */
-       function create_site_entity($guid, $name, $description, $url)
-       {
+       public function delete() {
                global $CONFIG;
-               
-               $guid = (int)$guid;
-               $name = sanitise_string($name);
-               $description = sanitise_string($description);
-               $url = sanitise_string($url);
-               
-               $row = get_entity_as_row($guid);
-               
-               if ($row)
-               {
-                       // Exists and you have access to it
-                       if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}sites_entity where guid = {$guid}")) {
-                               $result = update_data("UPDATE {$CONFIG->dbprefix}sites_entity set name='$name', description='$description', url='$url' where guid=$guid");
-                               if ($result!=false)
-                               {
-                                       // Update succeeded, continue
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('update',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete();
-                                               //delete_entity($guid);
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               // Update failed, attempt an insert.
-                               $result = insert_data("INSERT into {$CONFIG->dbprefix}sites_entity (guid, name, description, url) values ($guid, '$name','$description','$url')");
-                               if ($result!==false) {
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('create',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete();
-                                               //delete_entity($guid);
-                                       }
-                               }
-                       }
+               if ($CONFIG->site->getGUID() == $this->guid) {
+                       throw new SecurityException('SecurityException:deletedisablecurrentsite');
                }
-               
-               return false;
-       }
-       
-       /**
-        * THIS FUNCTION IS DEPRECATED.
-        * 
-        * Delete a site's extra data.
-        * 
-        * @param int $guid
-        */
-       function delete_site_entity($guid)
-       {
-               system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
-               
-               return 1; // Always return that we have deleted one row in order to not break existing code.
+
+               return parent::delete();
        }
-               
+
        /**
-        * Add a user to a site.
-        * 
-        * @param int $site_guid 
-        * @param int $user_guid
+        * Disable override to add safety rail.
+        *
+        * @param unknown_type $reason
         */
-       function add_site_user($site_guid, $user_guid)
-       {
+       public function disable($reason = "") {
                global $CONFIG;
-               
-               $site_guid = (int)$site_guid;
-               $user_guid = (int)$user_guid;
-               
-               return add_entity_relationship($user_guid, "member_of_site", $site_guid);
-       }
-       
-       /**
-        * Remove a user from a site.
-        * 
-        * @param int $site_guid 
-        * @param int $user_guid
-        */
-       function remove_site_user($site_guid, $user_guid)
-       {
-               $site_guid = (int)$site_guid;
-               $user_guid = (int)$user_guid;
-               
-               return remove_entity_relationship($user_guid, "member_of_site", $site_guid);
+
+               if ($CONFIG->site->getGUID() == $this->guid) {
+                       throw new SecurityException('SecurityException:deletedisablecurrentsite');
+               }
+
+               return parent::disable($reason);
        }
-       
+
        /**
-        * Get the members of a site.
-        * 
-        * @param int $site_guid
-        * @param int $limit 
+        * Return a list of users using this site.
+        *
+        * @param int $limit
         * @param int $offset
+        * @return array of ElggUsers
         */
-       function get_site_members($site_guid, $limit = 10, $offset = 0)
-       {
-               $site_guid = (int)$site_guid;
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               
-               return get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset);
+       public function getMembers($limit = 10, $offset = 0) {
+               get_site_members($this->getGUID(), $limit, $offset);
        }
-       
+
        /**
-        * Display a list of site members
+        * Add a user to the site.
         *
-        * @param int $site_guid The GUID of the site
-        * @param int $limit The number of members to display on a page
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @return string A displayable list of members
-        */
-       function list_site_members($site_guid, $limit = 10, $fullview = true) {
-               
-               $offset = (int) get_input('offset');
-               $limit = (int) $limit;
-               $count = (int) get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset, true);
-               $entities = get_site_members($site_guid, $limit, $offset);
-               
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview);
-               
-       }
-       
-       /**
-        * Add an object to a site.
-        * 
-        * @param int $site_guid 
-        * @param int $object_guid
+        * @param int $user_guid
         */
-       function add_site_object($site_guid, $object_guid)
-       {
-               global $CONFIG;
-               
-               $site_guid = (int)$site_guid;
-               $object_guid = (int)$object_guid;
-               
-               return add_entity_relationship($object_guid, "member_of_site", $site_guid);
+       public function addUser($user_guid) {
+               return add_site_user($this->getGUID(), $user_guid);
        }
-       
+
        /**
-        * Remove an object from a site.
-        * 
-        * @param int $site_guid 
-        * @param int $object_guid
+        * Remove a site user.
+        *
+        * @param int $user_guid
         */
-       function remove_site_object($site_guid, $object_guid)
-       {
-               $site_guid = (int)$site_guid;
-               $object_guid = (int)$object_guid;
-               
-               return remove_entity_relationship($object_guid, "member_of_site", $site_guid);
+       public function removeUser($user_guid) {
+               return remove_site_user($this->getGUID(), $user_guid);
        }
-       
+
        /**
-        * Get the objects belonging to a site.
-        * 
-        * @param int $site_guid
+        * Get an array of member ElggObjects.
+        *
         * @param string $subtype
-        * @param int $limit 
+        * @param int $limit
         * @param int $offset
         */
-       function get_site_objects($site_guid, $subtype = "", $limit = 10, $offset = 0)
-       {
-               $site_guid = (int)$site_guid;
-               $subtype = sanitise_string($subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               
-               return get_entities_from_relationship("member_of_site", $site_guid, true, "object", $subtype, 0, "time_created desc", $limit, $offset);
+       public function getObjects($subtype="", $limit = 10, $offset = 0) {
+               get_site_objects($this->getGUID(), $subtype, $limit, $offset);
        }
-       
+
        /**
-        * Add a collection to a site.
-        * 
-        * @param int $site_guid 
-        * @param int $collection_guid
+        * Add an object to the site.
+        *
+        * @param int $user_id
         */
-       function add_site_collection($site_guid, $collection_guid)
-       {
-               global $CONFIG;
-               
-               $site_guid = (int)$site_guid;
-               $collection_guid = (int)$collection_guid;
-               
-               return add_entity_relationship($collection_guid, "member_of_site", $site_guid);
+       public function addObject($object_guid) {
+               return add_site_object($this->getGUID(), $object_guid);
        }
-       
+
        /**
-        * Remove a collection from a site.
-        * 
-        * @param int $site_guid 
-        * @param int $collection_guid
+        * Remove a site user.
+        *
+        * @param int $user_id
         */
-       function remove_site_collection($site_guid, $collection_guid)
-       {
-               $site_guid = (int)$site_guid;
-               $collection_guid = (int)$collection_guid;
-               
-               return remove_entity_relationship($collection_guid, "member_of_site", $site_guid);
+       public function removeObject($object_guid) {
+               return remove_site_object($this->getGUID(), $object_guid);
        }
-       
+
        /**
-        * Get the collections belonging to a site.
-        * 
-        * @param int $site_guid
-        * @param string $subtype
-        * @param int $limit 
+        * Get the collections associated with a site.
+        *
+        * @param string $type
+        * @param int $limit
         * @param int $offset
+        * @return unknown
         */
-       function get_site_collections($site_guid, $subtype = "", $limit = 10, $offset = 0)
-       {
-               $site_guid = (int)$site_guid;
-               $subtype = sanitise_string($subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               
-               return get_entities_from_relationship("member_of_site", $site_guid, true, "collection", $subtype, 0, "time_created desc", $limit, $offset);
+       public function getCollections($subtype="", $limit = 10, $offset = 0) {
+               get_site_collections($this->getGUID(), $subtype, $limit, $offset);
        }
-       
+
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
+
        /**
-        * Return the site via a url.
+        * Return an array of fields which can be exported.
         */
-       function get_site_by_url($url)
-       {
-               global $CONFIG;
-               
-               $url = sanitise_string($url);
-               
-               $row = get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where url='$url'");
-       
-               if ($row)
-                       return new ElggSite($row); 
-               
-               return false;
+       public function getExportableValues() {
+               return array_merge(parent::getExportableValues(), array(
+                       'name',
+                       'description',
+                       'url',
+               ));
        }
-       
-       /**
-        * Searches for a site based on a complete or partial name or description or url using full text searching.
-        * 
-        * IMPORTANT NOTE: With MySQL's default setup:
-        * 1) $criteria must be 4 or more characters long
-        * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED!
-        *
-        * @param string $criteria The partial or full name or username.
-        * @param int $limit Limit of the search.
-        * @param int $offset Offset.
-        * @param string $order_by The order.
-        * @param boolean $count Whether to return the count of results or just the results. 
-        */
-       function search_for_site($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false)
+}
+
+/**
+ * Return the site specific details of a site by a row.
+ *
+ * @param int $guid
+ */
+function get_site_entity_as_row($guid) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+
+       /*$row = retrieve_cached_entity_row($guid);
+       if ($row)
        {
-               global $CONFIG;
-               
-               $criteria = sanitise_string($criteria);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $order_by = sanitise_string($order_by);
-               
-               $access = get_access_sql_suffix("e");
-               
-               if ($order_by == "") $order_by = "e.time_created desc";
-               
-               if ($count) {
-                       $query = "SELECT count(e.guid) as total ";
-               } else {
-                       $query = "SELECT e.* "; 
-               }
-               $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}sites_entity s on e.guid=s.guid where match(s.name,s.description,s.url) against ('$criteria') and $access";
-               
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
+               // We have already cached this object, so retrieve its value from the cache
+               if (isset($CONFIG->debug) && $CONFIG->debug)
+                       error_log("** Retrieving sub part of GUID:$guid from cache");
+
+               return $row;
+       }
+       else
+       {*/
+       // Object not cached, load it.
+       if (isset($CONFIG->debug) && $CONFIG->debug == true) {
+               error_log("** Sub part of GUID:$guid loaded from DB");
+       }
+
+       return get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where guid=$guid");
+       //}
+}
+
+/**
+ * Create or update the extras table for a given site.
+ * Call create_entity first.
+ *
+ * @param int $guid
+ * @param string $name
+ * @param string $description
+ * @param string $url
+ */
+function create_site_entity($guid, $name, $description, $url) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+       $name = sanitise_string($name);
+       $description = sanitise_string($description);
+       $url = sanitise_string($url);
+
+       $row = get_entity_as_row($guid);
+
+       if ($row) {
+               // Exists and you have access to it
+               if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}sites_entity where guid = {$guid}")) {
+                       $result = update_data("UPDATE {$CONFIG->dbprefix}sites_entity set name='$name', description='$description', url='$url' where guid=$guid");
+                       if ($result!=false) {
+                               // Update succeeded, continue
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('update',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete();
+                                       //delete_entity($guid);
+                               }
+                       }
                } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
+                       // Update failed, attempt an insert.
+                       $result = insert_data("INSERT into {$CONFIG->dbprefix}sites_entity (guid, name, description, url) values ($guid, '$name','$description','$url')");
+                       if ($result!==false) {
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('create',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete();
+                                       //delete_entity($guid);
+                               }
                        }
                }
-               return false;
        }
-       
-       /**
-        * Retrieve a site and return the domain portion of its url.
-        *
-        * @param int $guid
-        */
-       function get_site_domain($guid)
-       {
-               $guid = (int)$guid;
-               
-               $site = get_entity($guid);
-               if ($site instanceof ElggSite) {
-                       $breakdown = parse_url($site->url);
-                       return $breakdown['host'];
+
+       return false;
+}
+
+/**
+ * THIS FUNCTION IS DEPRECATED.
+ *
+ * Delete a site's extra data.
+ *
+ * @param int $guid
+ */
+function delete_site_entity($guid) {
+       system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
+
+       return 1; // Always return that we have deleted one row in order to not break existing code.
+}
+
+/**
+ * Add a user to a site.
+ *
+ * @param int $site_guid
+ * @param int $user_guid
+ */
+function add_site_user($site_guid, $user_guid) {
+       global $CONFIG;
+
+       $site_guid = (int)$site_guid;
+       $user_guid = (int)$user_guid;
+
+       return add_entity_relationship($user_guid, "member_of_site", $site_guid);
+}
+
+/**
+ * Remove a user from a site.
+ *
+ * @param int $site_guid
+ * @param int $user_guid
+ */
+function remove_site_user($site_guid, $user_guid) {
+       $site_guid = (int)$site_guid;
+       $user_guid = (int)$user_guid;
+
+       return remove_entity_relationship($user_guid, "member_of_site", $site_guid);
+}
+
+/**
+ * Get the members of a site.
+ *
+ * @param int $site_guid
+ * @param int $limit
+ * @param int $offset
+ */
+function get_site_members($site_guid, $limit = 10, $offset = 0) {
+       $site_guid = (int)$site_guid;
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+
+       return get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset);
+}
+
+/**
+ * Display a list of site members
+ *
+ * @param int $site_guid The GUID of the site
+ * @param int $limit The number of members to display on a page
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @return string A displayable list of members
+ */
+function list_site_members($site_guid, $limit = 10, $fullview = true) {
+       $offset = (int) get_input('offset');
+       $limit = (int) $limit;
+       $count = (int) get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset, true);
+       $entities = get_site_members($site_guid, $limit, $offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview);
+
+}
+
+/**
+ * Add an object to a site.
+ *
+ * @param int $site_guid
+ * @param int $object_guid
+ */
+function add_site_object($site_guid, $object_guid) {
+       global $CONFIG;
+
+       $site_guid = (int)$site_guid;
+       $object_guid = (int)$object_guid;
+
+       return add_entity_relationship($object_guid, "member_of_site", $site_guid);
+}
+
+/**
+ * Remove an object from a site.
+ *
+ * @param int $site_guid
+ * @param int $object_guid
+ */
+function remove_site_object($site_guid, $object_guid) {
+       $site_guid = (int)$site_guid;
+       $object_guid = (int)$object_guid;
+
+       return remove_entity_relationship($object_guid, "member_of_site", $site_guid);
+}
+
+/**
+ * Get the objects belonging to a site.
+ *
+ * @param int $site_guid
+ * @param string $subtype
+ * @param int $limit
+ * @param int $offset
+ */
+function get_site_objects($site_guid, $subtype = "", $limit = 10, $offset = 0) {
+       $site_guid = (int)$site_guid;
+       $subtype = sanitise_string($subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+
+       return get_entities_from_relationship("member_of_site", $site_guid, true, "object", $subtype, 0, "time_created desc", $limit, $offset);
+}
+
+/**
+ * Add a collection to a site.
+ *
+ * @param int $site_guid
+ * @param int $collection_guid
+ */
+function add_site_collection($site_guid, $collection_guid) {
+       global $CONFIG;
+
+       $site_guid = (int)$site_guid;
+       $collection_guid = (int)$collection_guid;
+
+       return add_entity_relationship($collection_guid, "member_of_site", $site_guid);
+}
+
+/**
+ * Remove a collection from a site.
+ *
+ * @param int $site_guid
+ * @param int $collection_guid
+ */
+function remove_site_collection($site_guid, $collection_guid) {
+       $site_guid = (int)$site_guid;
+       $collection_guid = (int)$collection_guid;
+
+       return remove_entity_relationship($collection_guid, "member_of_site", $site_guid);
+}
+
+/**
+ * Get the collections belonging to a site.
+ *
+ * @param int $site_guid
+ * @param string $subtype
+ * @param int $limit
+ * @param int $offset
+ */
+function get_site_collections($site_guid, $subtype = "", $limit = 10, $offset = 0) {
+       $site_guid = (int)$site_guid;
+       $subtype = sanitise_string($subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+
+       return get_entities_from_relationship("member_of_site", $site_guid, true, "collection", $subtype, 0, "time_created desc", $limit, $offset);
+}
+
+/**
+ * Return the site via a url.
+ */
+function get_site_by_url($url) {
+       global $CONFIG;
+
+       $url = sanitise_string($url);
+
+       $row = get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where url='$url'");
+
+       if ($row) {
+               return new ElggSite($row);
+       }
+
+       return false;
+}
+
+/**
+ * Searches for a site based on a complete or partial name or description or url using full text searching.
+ *
+ * IMPORTANT NOTE: With MySQL's default setup:
+ * 1) $criteria must be 4 or more characters long
+ * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED!
+ *
+ * @param string $criteria The partial or full name or username.
+ * @param int $limit Limit of the search.
+ * @param int $offset Offset.
+ * @param string $order_by The order.
+ * @param boolean $count Whether to return the count of results or just the results.
+ */
+function search_for_site($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) {
+       global $CONFIG;
+
+       $criteria = sanitise_string($criteria);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $order_by = sanitise_string($order_by);
+
+       $access = get_access_sql_suffix("e");
+
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
+       }
+
+       if ($count) {
+               $query = "SELECT count(e.guid) as total ";
+       } else {
+               $query = "SELECT e.* ";
+       }
+       $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}sites_entity s on e.guid=s.guid where match(s.name,s.description,s.url) against ('$criteria') and $access";
+
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
                }
-               
-               return false;
        }
-       
-       /**
-        * Initialise site handling
-        *
-        * Called at the beginning of system running, to set the ID of the current site.
-        * This is 0 by default, but plugins may alter this behaviour by attaching functions
-        * to the sites init event and changing $CONFIG->site_id.
-        * 
-        * @uses $CONFIG
-        * @param string $event Event API required parameter
-        * @param string $object_type Event API required parameter
-        * @param null $object Event API required parameter
-        * @return true
-        */
-               function sites_init($event, $object_type, $object) {
-                       
-                       global $CONFIG;
-                       
-                       if (is_installed() && is_db_installed()) {
-                               
-                               $site = trigger_plugin_hook("siteid","system");
-                               if ($site === null || $site === false) {
-                                       $CONFIG->site_id = (int) datalist_get('default_site');
-                               } else {
-                                       $CONFIG->site_id = $site;
-                               }
-                               $CONFIG->site_guid = $CONFIG->site_id;
-                               $CONFIG->site = get_entity($CONFIG->site_guid);
-                               
-                               return true;
-                       }
-                       
-                       return true;
+       return false;
+}
+
+/**
+ * Retrieve a site and return the domain portion of its url.
+ *
+ * @param int $guid
+ */
+function get_site_domain($guid) {
+       $guid = (int)$guid;
+
+       $site = get_entity($guid);
+       if ($site instanceof ElggSite) {
+               $breakdown = parse_url($site->url);
+               return $breakdown['host'];
+       }
+
+       return false;
+}
+
+/**
+ * Initialise site handling
+ *
+ * Called at the beginning of system running, to set the ID of the current site.
+ * This is 0 by default, but plugins may alter this behaviour by attaching functions
+ * to the sites init event and changing $CONFIG->site_id.
+ *
+ * @uses $CONFIG
+ * @param string $event Event API required parameter
+ * @param string $object_type Event API required parameter
+ * @param null $object Event API required parameter
+ * @return true
+ */
+function sites_init($event, $object_type, $object) {
+       global $CONFIG;
+
+       if (is_installed() && is_db_installed()) {
+               $site = trigger_plugin_hook("siteid","system");
+               if ($site === null || $site === false) {
+                       $CONFIG->site_id = (int) datalist_get('default_site');
+               } else {
+                       $CONFIG->site_id = $site;
                }
-               
-       // Register event handlers
-       register_elgg_event_handler('boot','system','sites_init',2);
-       
-       // Register with unit test
-       register_plugin_hook('unit_test', 'system', 'sites_test');
-       function sites_test($hook, $type, $value, $params) {
-               global $CONFIG;
-               $value[] = "{$CONFIG->path}engine/tests/objects/sites.php";
-               return $value;
+               $CONFIG->site_guid = $CONFIG->site_id;
+               $CONFIG->site = get_entity($CONFIG->site_guid);
+
+               return true;
        }
+
+       return true;
+}
+
+// Register event handlers
+register_elgg_event_handler('boot','system','sites_init',2);
+
+// Register with unit test
+register_plugin_hook('unit_test', 'system', 'sites_test');
+function sites_test($hook, $type, $value, $params) {
+       global $CONFIG;
+       $value[] = "{$CONFIG->path}engine/tests/objects/sites.php";
+       return $value;
+}
index e8bfccda59a927ab8f526454bcb97311af7e861e..381c7ea4f976d8b59e8e71f034194f468f8a31e6 100644 (file)
 <?php
+/**
+ * Elgg Social
+ * Functions and objects which provide powerful social aspects within Elgg
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider
+ * @link http://elgg.org/
 
-    /**
-        * Elgg Social
-        * Functions and objects which provide powerful social aspects within Elgg
-        * 
-        * @package Elgg
-        * @subpackage Core
+/**
+  * Filters a string into an array of significant words
+  *
+  * @param string $string
+  * @return array
+  */
+function filter_string($string) {
+       // Convert it to lower and trim
+       $string = strtolower($string);
+       $string = trim($string);
 
-        * @author Curverider
+       // Remove links and email addresses
+       // match protocol://address/path/file.extension?some=variable&another=asf%
+       $string = preg_replace("/\s([a-zA-Z]+:\/\/[a-z][a-z0-9\_\.\-]*[a-z]{2,6}[a-zA-Z0-9\/\*\-\?\&\%\=]*)([\s|\.|\,])/iu"," ", $string);
+       // match www.something.domain/path/file.extension?some=variable&another=asf%
+       $string = preg_replace("/\s(www\.[a-z][a-z0-9\_\.\-]*[a-z]{2,6}[a-zA-Z0-9\/\*\-\?\&\%\=]*)([\s|\.|\,])/iu"," ", $string);
+       // match name@address
+       $string = preg_replace("/\s([a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]*\@[a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]{2,6})([\s|\.|\,])/iu"," ", $string);
 
-        * @link http://elgg.org/
-        
-        /**
-      * Filters a string into an array of significant words
-      *
-      * @param string $string
-      * @return array
-      */
-        function filter_string($string) {
-            
-               // Convert it to lower and trim
-                  $string = strtolower($string);
-                  $string = trim($string);
-               
-               // Remove links and email addresses
-                  // match protocol://address/path/file.extension?some=variable&another=asf%
-                          $string = preg_replace("/\s([a-zA-Z]+:\/\/[a-z][a-z0-9\_\.\-]*[a-z]{2,6}[a-zA-Z0-9\/\*\-\?\&\%\=]*)([\s|\.|\,])/iu"," ", $string);
-               // match www.something.domain/path/file.extension?some=variable&another=asf%
-                          $string = preg_replace("/\s(www\.[a-z][a-z0-9\_\.\-]*[a-z]{2,6}[a-zA-Z0-9\/\*\-\?\&\%\=]*)([\s|\.|\,])/iu"," ", $string);
-               // match name@address
-                          $string = preg_replace("/\s([a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]*\@[a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]{2,6})([\s|\.|\,])/iu"," ", $string);
-               
-               // Sanitise the string; remove unwanted characters
-                  $string = preg_replace('/\W/ui', ' ', $string);
-                  
-            // Explode it into an array
-                  $terms = explode(' ',$string);
-                  
-            // Remove any blacklist terms
-               //$terms = array_filter($terms, 'remove_blacklist');
-                   
-               return $terms;
+       // Sanitise the string; remove unwanted characters
+       $string = preg_replace('/\W/ui', ' ', $string);
 
-        }
-        
-        /**
-         * Returns true if the word in $input is considered significant
-         *
-         * @param string $input
-         * @return true|false
-         */
-        function remove_blacklist($input) {
-               
-               global $CONFIG;
-               
-               if (!is_array($CONFIG->wordblacklist))
-                       return $input;
-               
-               if (strlen($input) < 3 || in_array($input,$CONFIG->wordblacklist))
-                  return false;
-               
-            return true;               
-               
-        }
-        
+       // Explode it into an array
+       $terms = explode(' ',$string);
 
-        /**
-         * Initialise.
-         *
-         * Sets a blacklist of words in the current language. This is a comma separated list in word:blacklist.
-         */       
-        function social_init() {
-            global $CONFIG;
-            
-               $CONFIG->wordblacklist = array();
-               
-               $list = explode(',', elgg_echo('word:blacklist'));
-               if ($list)
-               {
-                       foreach ($list as $l)
-                               $CONFIG->wordblacklist[] = trim($l);
-               }
-               else    
-               {                   
-                       // Fallback - shouldn't happen
-                                       $CONFIG->wordblacklist = array(
-                                   'and',
-                                   'the',
-                                   'then',
-                                   'but',
-                                   'she',
-                                   'his',
-                                   'her',
-                                   'him',
-                                   'one',
-                                   'not',
-                                   'also',
-                                   'about',
-                                   'now',
-                                               'hence',
-                                               'however',
-                                               'still',
-                                               'likewise',
-                                               'otherwise',
-                                               'therefore',
-                                               'conversely',
-                                               'rather',
-                                   'consequently',
-                                               'furthermore',
-                                               'nevertheless',
-                                               'instead',
-                                               'meanwhile',
-                                               'accordingly',
-                                               'this',
-                                               'seems',
-                                               'what',
-                                               'whom',
-                                               'whose',
-                                               'whoever',
-                                               'whomever',
-                               );
-               }
-        }
+       // Remove any blacklist terms
+       //$terms = array_filter($terms, 'remove_blacklist');
 
-        register_elgg_event_handler("init","system","social_init");
-        
-?>
\ No newline at end of file
+       return $terms;
+}
+
+/**
+ * Returns true if the word in $input is considered significant
+ *
+ * @param string $input
+ * @return true|false
+ */
+function remove_blacklist($input) {
+       global $CONFIG;
+
+       if (!is_array($CONFIG->wordblacklist)) {
+               return $input;
+       }
+
+       if (strlen($input) < 3 || in_array($input,$CONFIG->wordblacklist)) {
+               return false;
+       }
+
+       return true;
+}
+
+
+/**
+ * Initialise.
+ *
+ * Sets a blacklist of words in the current language. This is a comma separated list in word:blacklist.
+ */
+function social_init() {
+       global $CONFIG;
+
+       $CONFIG->wordblacklist = array();
+
+       $list = explode(',', elgg_echo('word:blacklist'));
+       if ($list) {
+               foreach ($list as $l) {
+                       $CONFIG->wordblacklist[] = trim($l);
+               }
+       } else {
+               // Fallback - shouldn't happen
+               $CONFIG->wordblacklist = array(
+                       'and',
+                       'the',
+                       'then',
+                       'but',
+                       'she',
+                       'his',
+                       'her',
+                       'him',
+                       'one',
+                       'not',
+                       'also',
+                       'about',
+                       'now',
+                       'hence',
+                       'however',
+                       'still',
+                       'likewise',
+                       'otherwise',
+                       'therefore',
+                       'conversely',
+                       'rather',
+                       'consequently',
+                       'furthermore',
+                       'nevertheless',
+                       'instead',
+                       'meanwhile',
+                       'accordingly',
+                       'this',
+                       'seems',
+                       'what',
+                       'whom',
+                       'whose',
+                       'whoever',
+                       'whomever',
+               );
+       }
+}
+
+register_elgg_event_handler("init","system","social_init");
\ No newline at end of file
index 24d2e41558a6a2659a05bc5b92994bb750dfa38f..b8bf2b012d6e848d03fe744270ebb1ad409c307d 100644 (file)
 <?php
-       /**
-        * Elgg statistics library.
-        * This file contains a number of functions for obtaining statistics about the running system.
-        * These statistics are mainly used by the administration pages, and is also where the basic views for statistics 
-        * are added.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
-        * @link http://elgg.org/
-        */
-       
-       /**
-        * Return an array reporting the number of various entities in the system.
-        * 
-        * @param int $owner_guid Optional owner of the statistics
-        * @return array
-        */
-       function get_entity_statistics($owner_guid = 0)
-       {
-               global $CONFIG;
-               
-               $entity_stats = array();
-               $owner_guid = (int)$owner_guid;
-               
-               $query = "SELECT distinct e.type,s.subtype,e.subtype as subtype_id from {$CONFIG->dbprefix}entities e left join {$CONFIG->dbprefix}entity_subtypes s on e.subtype=s.id";
-               $owner_query = "";
-               if ($owner_guid) {
-                       $query .= " where owner_guid=$owner_guid";
-                       $owner_query = "and owner_guid=$owner_guid ";
+/**
+ * Elgg statistics library.
+ * This file contains a number of functions for obtaining statistics about the running system.
+ * These statistics are mainly used by the administration pages, and is also where the basic views for statistics
+ * are added.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
+
+/**
+ * Return an array reporting the number of various entities in the system.
+ *
+ * @param int $owner_guid Optional owner of the statistics
+ * @return array
+ */
+function get_entity_statistics($owner_guid = 0) {
+       global $CONFIG;
+
+       $entity_stats = array();
+       $owner_guid = (int)$owner_guid;
+
+       $query = "SELECT distinct e.type,s.subtype,e.subtype as subtype_id from {$CONFIG->dbprefix}entities e left join {$CONFIG->dbprefix}entity_subtypes s on e.subtype=s.id";
+       $owner_query = "";
+       if ($owner_guid) {
+               $query .= " where owner_guid=$owner_guid";
+               $owner_query = "and owner_guid=$owner_guid ";
+       }
+
+       // Get a list of major types
+
+       $types = get_data($query);
+       foreach ($types as $type) {
+               // assume there are subtypes for now
+               if (!is_array($entity_stats[$type->type])) {
+                       $entity_stats[$type->type] = array();
+               }
+
+               $query = "SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='{$type->type}' $owner_query";
+               if ($type->subtype) {
+                       $query.= " and subtype={$type->subtype_id}";
                }
-               
-               // Get a list of major types
-               
-               $types = get_data($query);
-               foreach ($types as $type) {
-                       if (!is_array($entity_stats[$type->type])) 
-                               $entity_stats[$type->type] = array(); // assume there are subtypes for now
-                       
-                       $query = "SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='{$type->type}' $owner_query";
-                       if ($type->subtype) $query.= " and subtype={$type->subtype_id}";
-                         
-                       $subtype_cnt = get_data_row($query);
-                       
-                       if ($type->subtype)
-                               $entity_stats[$type->type][$type->subtype] = $subtype_cnt->count;
-                       else
-                               $entity_stats[$type->type]['__base__'] = $subtype_cnt->count;   
+
+               $subtype_cnt = get_data_row($query);
+
+               if ($type->subtype) {
+                       $entity_stats[$type->type][$type->subtype] = $subtype_cnt->count;
+               } else {
+                       $entity_stats[$type->type]['__base__'] = $subtype_cnt->count;
                }
-               
-               return $entity_stats;
        }
-         
-       /**
-        * Return the number of users registered in the system.
-        *
-        * @param bool $show_deactivated 
-        * @return int
-        */
-       function get_number_users($show_deactivated = false)
-       {
-               global $CONFIG;
-            
-               $access = "";
-               
-               if (!$show_deactivated)
-                       $access = "and " . get_access_sql_suffix();
-               
-               $result = get_data_row("SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='user' $access");
-            
-               if ($result)
-                       return $result->count;
-            
-               return false;
+
+       return $entity_stats;
+}
+
+/**
+ * Return the number of users registered in the system.
+ *
+ * @param bool $show_deactivated
+ * @return int
+ */
+function get_number_users($show_deactivated = false) {
+       global $CONFIG;
+
+       $access = "";
+
+       if (!$show_deactivated) {
+               $access = "and " . get_access_sql_suffix();
        }
-        
-       /**
-        * Return a list of how many users are currently online, rendered as a view.
-        */
-       function get_online_users()
-       {
-               $offset = get_input('offset',0);
-               $count = count(find_active_users(600,9999));
-               $objects = find_active_users(600,10,$offset);
-               
-               if ($objects)
-               {
-                       return elgg_view_entity_list($objects, $count,$offset,10,false);
-               }
+
+       $result = get_data_row("SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='user' $access");
+
+       if ($result) {
+               return $result->count;
        }
-        
-    /**
-        * Initialise the statistics admin page.
-        */
-       function statistics_init()
-       {
-               extend_elgg_admin_page('admin/statistics_opt/basic', 'admin/statistics');
-               extend_elgg_admin_page('admin/statistics_opt/numentities', 'admin/statistics'); 
-               extend_elgg_admin_page('admin/statistics_opt/online', 'admin/statistics'); 
-               
-               
-               
-               extend_elgg_settings_page('usersettings/statistics_opt/online', 'usersettings/statistics');
-               extend_elgg_settings_page('usersettings/statistics_opt/numentities', 'usersettings/statistics');  
+
+       return false;
+}
+
+/**
+ * Return a list of how many users are currently online, rendered as a view.
+  */
+function get_online_users() {
+       $offset = get_input('offset', 0);
+       $count = count(find_active_users(600, 9999));
+       $objects = find_active_users(600, 10, $offset);
+
+       if ($objects) {
+               return elgg_view_entity_list($objects, $count,$offset,10,false);
        }
-       
-       /// Register init function
-       register_elgg_event_handler('init','system','statistics_init');
-?>
+}
+
+/**
+ * Initialise the statistics admin page.
+ */
+function statistics_init() {
+       extend_elgg_admin_page('admin/statistics_opt/basic', 'admin/statistics');
+       extend_elgg_admin_page('admin/statistics_opt/numentities', 'admin/statistics');
+       extend_elgg_admin_page('admin/statistics_opt/online', 'admin/statistics');
+
+       extend_elgg_settings_page('usersettings/statistics_opt/online', 'usersettings/statistics');
+       extend_elgg_settings_page('usersettings/statistics_opt/numentities', 'usersettings/statistics');
+}
+
+/// Register init function
+register_elgg_event_handler('init','system','statistics_init');
\ No newline at end of file
index dd32602be95474395c61e9414194e86f6562d930..75a7cc531e0567505e644105b9de2552c16d4abf 100644 (file)
 <?php
+/**
+ * Elgg system log.
+ * Listens to events and writes crud events into the system log database.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @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 {
        /**
-        * Elgg system log.
-        * Listens to events and writes crud events into the system log database.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd
-        * @link http://elgg.org/
+        * Return an identification for the object for storage in the system log.
+        * This id must be an integer.
+        *
+        * @return int
         */
+       public function getSystemLogID();
 
        /**
-        * 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
+        * Return the class name of the object.
+        * Added as a function because get_class causes errors for some reason.
         */
-       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();
-       }
-       
+       public function getClassName();
+
        /**
-        * Retrieve the system log based on a number of parameters.
-        * 
-        * @param int or array $by_user The guid(s) of the user(s) who initiated the event.
-        * @param string $event The event you are searching on.
-        * @param string $class The class of object it effects.
-        * @param string $type The type
-        * @param string $subtype The subtype.
-        * @param int $limit Maximum number of responses to return.
-        * @param int $offset Offset of where to start.
-        * @param bool $count Return count or not
+        * Return the type of the object - eg. object, group, user, relationship, metadata, annotation etc
         */
-       function get_system_log($by_user = "", $event = "", $class = "", $type = "", $subtype = "", $limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $object_id = 0)
-       {
-               global $CONFIG;
-               
-               $by_user_orig = $by_user;
-               if (is_array($by_user) && sizeof($by_user) > 0) {
-                       foreach($by_user as $key => $val) {
-                               $by_user[$key] = (int) $val;
-                       }
-               } else {
-                       $by_user = (int)$by_user;
-               }
-               $event = sanitise_string($event);
-               $class = sanitise_string($class);
-               $type = sanitise_string($type);
-               $subtype = sanitise_string($subtype);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               
-               $where = array();
-               
-               if ($by_user_orig!=="")
-               {
-                       if (is_int($by_user)) {
-                               $where[] = "performed_by_guid=$by_user";
-                       } else if (is_array($by_user)) {
-                               $where [] = "performed_by_guid in (". implode(",",$by_user) .")";
-                       } 
-               }
-               if ($event != "")
-                       $where[] = "event='$event'";
-               if ($class!=="")
-                       $where[] = "object_class='$class'";
-               if ($type != "")
-                       $where[] = "object_type='$type'";
-               if ($subtype!=="")
-                       $where[] = "object_subtype='$subtype'";
-                       
-               if ($timebefore)
-                       $where[] = "time_created < " . ((int) $timebefore);
-               if ($timeafter)
-                       $where[] = "time_created > " . ((int) $timeafter);
-               if ($object_id)
-                       $where[] = "object_id = " . ((int) $object_id); 
-                       
-               $select = "*";
-               if ($count) $select = "count(*) as count";
-               $query = "SELECT $select from {$CONFIG->dbprefix}system_log where 1 ";
-               foreach ($where as $w)
-                       $query .= " and $w";
-               
-               if (!$count)
-               {
-                       $query .= " order by time_created desc";
-                       $query .= " limit $offset, $limit"; // Add order and limit
-               }
-       
-               if ($count)
-               {
-                       if ($numrows = get_data_row($query))
-                               return $numrows->count;
-               }
-               else
-                       return get_data($query);
-                       
-               return false;
-       }
-       
+       public function getType();
+
        /**
-        * Return a specific log entry.
-        *
-        * @param int $entry_id The log entry
+        * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type.
         */
-       function get_log_entry($entry_id)
-       {
-               global $CONFIG;
-               
-               $entry_id = (int)$entry_id;
-               
-               return get_data_row("SELECT * from {$CONFIG->dbprefix}system_log where id=$entry_id");
-       }
-       
+       public function getSubtype();
+
        /**
-        * Return the object referred to by a given log entry
-        *
-        * @param int $entry_id The log entry
+        * 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.
         */
-       function get_object_from_log_entry($entry_id)
-       {
-               $entry = get_log_entry($entry_id);
-               
-               if ($entry)
-               {
-                       $class = $entry->object_class;
-                       $tmp = new $class();
-                       $object = $tmp->getObjectFromID($entry->object_id);
-                       
-                       if ($object)
-                               return $object;
-               }
-               
-               return false;
-       }
-       
+       public function getObjectFromID($id);
+
        /**
-        * Log a system event related to a specific object.
-        * 
-        * This is called by the event system and should not be called directly.
-        * 
-        * @param $object The object you're talking about.
-        * @param $event String The event being logged
+        * Return the GUID of the owner of this object.
         */
-       function system_log($object, $event)
-       {
-               global $CONFIG;
-               static $logcache;
-
-               if ($object instanceof Loggable)
-               {
-                       
-                       if (!is_array($logcache)) $logcache = array();
-                       
-                       // Has loggable interface, extract the necessary information and store
-                       $object_id = (int)$object->getSystemLogID();
-                       $object_class = $object->getClassName();
-                       $object_type = $object->getType();
-                       $object_subtype = $object->getSubtype();
-                       $event = sanitise_string($event);
-                       $time = time();
-                       $performed_by = (int)$_SESSION['guid'];
-                       
-                       if (isset($object->access_id))
-                               $access_id = $object->access_id;
-                       else
-                               $access_id = ACCESS_PUBLIC;
-                       if (isset($object->enabled))
-                               $enabled = $object->enabled;
-                       else
-                               $enabled = 'yes';
-                               
-                       if (isset($object->owner_guid))
-                               $owner_guid = $object->owner_guid;
-                       else
-                               $owner_guid = 0;
-                       
-                       // Create log if we haven't already created it
-                       if (!isset($logcache[$time][$object_id][$event])) {
-                               insert_data("INSERT DELAYED into {$CONFIG->dbprefix}system_log (object_id, object_class, object_type, object_subtype, event, performed_by_guid, owner_guid, access_id, enabled, time_created) VALUES ('$object_id','$object_class','$object_type', '$object_subtype', '$event',$performed_by, $owner_guid, $access_id, '$enabled', '$time')");
-                                       
-                               $logcache[$time][$object_id][$event] = true;    
-                       }
-                       
-                       return true;
-                       
+       public function getObjectOwnerGUID();
+}
+
+/**
+ * Retrieve the system log based on a number of parameters.
+ *
+ * @param int or array $by_user The guid(s) of the user(s) who initiated the event.
+ * @param string $event The event you are searching on.
+ * @param string $class The class of object it effects.
+ * @param string $type The type
+ * @param string $subtype The subtype.
+ * @param int $limit Maximum number of responses to return.
+ * @param int $offset Offset of where to start.
+ * @param bool $count Return count or not
+ */
+function get_system_log($by_user = "", $event = "", $class = "", $type = "", $subtype = "", $limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $object_id = 0) {
+       global $CONFIG;
+
+       $by_user_orig = $by_user;
+       if (is_array($by_user) && sizeof($by_user) > 0) {
+               foreach($by_user as $key => $val) {
+                       $by_user[$key] = (int) $val;
                }
+       } else {
+               $by_user = (int)$by_user;
        }
-       
-       /**
-        * This function creates an archive copy of the system log.
-        * 
-        * @param int $offset An offset in seconds from now to archive (useful for log rotation)
-        */
-       function archive_log($offset = 0)
-       {
-               global $CONFIG;
-               
-               $offset = (int)$offset;
-               $now = time(); // Take a snapshot of now
-               
-               $ts = $now - $offset;
-       
-               // create table
-               if (!update_data("CREATE TABLE {$CONFIG->dbprefix}system_log_$now as SELECT * from {$CONFIG->dbprefix}system_log WHERE time_created<$ts"))
-                       return false;
-
-               // delete
-               if (delete_data("DELETE from {$CONFIG->dbprefix}system_log WHERE time_created<$ts")===false) // Don't delete on time since we are running in a concurrent environment
-                       return false;
-                       
-               // alter table to engine
-               if (!update_data("ALTER TABLE {$CONFIG->dbprefix}system_log_$now engine=archive"))
-                       return false;
-       
-               return true;
+       $event = sanitise_string($event);
+       $class = sanitise_string($class);
+       $type = sanitise_string($type);
+       $subtype = sanitise_string($subtype);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+
+       $where = array();
+
+       if ($by_user_orig!=="") {
+               if (is_int($by_user)) {
+                       $where[] = "performed_by_guid=$by_user";
+               } else if (is_array($by_user)) {
+                       $where [] = "performed_by_guid in (". implode(",",$by_user) .")";
+               }
        }
-       
-       /**
-        * Default system log handler, allows plugins to override, extend or disable logging.
-        *
-        * @param string $event
-        * @param string $object_type
-        * @param Loggable $object
-        * @return unknown
-        */
-       function system_log_default_logger($event, $object_type, $object)
-       {
-               system_log($object['object'], $object['event']);
-               
-               return true;
+       if ($event != "") {
+               $where[] = "event='$event'";
        }
-       
-       /**
-        * System log listener.
-        * This function listens to all events in the system and logs anything appropriate.
-        *
-        * @param String $event
-        * @param String $object_type
-        * @param Loggable $object
-        */
-       function system_log_listener($event, $object_type, $object)
-       {
-               if (($object_type!='systemlog') && ($event!='log')) 
-                       trigger_elgg_event('log', 'systemlog', array('object' => $object, 'event' => $event));
-               
+       if ($class!=="") {
+               $where[] = "object_class='$class'";
+       }
+       if ($type != "") {
+               $where[] = "object_type='$type'";
+       }
+       if ($subtype!=="") {
+               $where[] = "object_subtype='$subtype'";
+       }
+
+       if ($timebefore) {
+               $where[] = "time_created < " . ((int) $timebefore);
+       }
+       if ($timeafter) {
+               $where[] = "time_created > " . ((int) $timeafter);
+       }
+       if ($object_id) {
+               $where[] = "object_id = " . ((int) $object_id);
+       }
+
+       $select = "*";
+       if ($count) {
+               $select = "count(*) as count";
+       }
+       $query = "SELECT $select from {$CONFIG->dbprefix}system_log where 1 ";
+       foreach ($where as $w) {
+               $query .= " and $w";
+       }
+
+       if (!$count) {
+               $query .= " order by time_created desc";
+               $query .= " limit $offset, $limit"; // Add order and limit
+       }
+
+       if ($count) {
+               if ($numrows = get_data_row($query)) {
+                       return $numrows->count;
+               }
+       } else {
+               return get_data($query);
+       }
+
+       return false;
+}
+
+/**
+ * Return a specific log entry.
+ *
+ * @param int $entry_id The log entry
+ */
+function get_log_entry($entry_id) {
+       global $CONFIG;
+
+       $entry_id = (int)$entry_id;
+
+       return get_data_row("SELECT * from {$CONFIG->dbprefix}system_log where id=$entry_id");
+}
+
+/**
+ * Return the object referred to by a given log entry
+ *
+ * @param int $entry_id The log entry
+ */
+function get_object_from_log_entry($entry_id) {
+       $entry = get_log_entry($entry_id);
+
+       if ($entry) {
+               $class = $entry->object_class;
+               $tmp = new $class();
+               $object = $tmp->getObjectFromID($entry->object_id);
+
+               if ($object) {
+                       return $object;
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Log a system event related to a specific object.
+ *
+ * This is called by the event system and should not be called directly.
+ *
+ * @param $object The object you're talking about.
+ * @param $event String The event being logged
+ */
+function system_log($object, $event) {
+       global $CONFIG;
+       static $logcache;
+
+       if ($object instanceof Loggable) {
+               if (!is_array($logcache)) {
+                       $logcache = array();
+               }
+
+               // Has loggable interface, extract the necessary information and store
+               $object_id = (int)$object->getSystemLogID();
+               $object_class = $object->getClassName();
+               $object_type = $object->getType();
+               $object_subtype = $object->getSubtype();
+               $event = sanitise_string($event);
+               $time = time();
+               $performed_by = (int)$_SESSION['guid'];
+
+               if (isset($object->access_id)) {
+                       $access_id = $object->access_id;
+               } else {
+                       $access_id = ACCESS_PUBLIC;
+               }
+               if (isset($object->enabled)) {
+                       $enabled = $object->enabled;
+               } else {
+                       $enabled = 'yes';
+               }
+
+               if (isset($object->owner_guid)) {
+                       $owner_guid = $object->owner_guid;
+               } else {
+                       $owner_guid = 0;
+               }
+
+               // Create log if we haven't already created it
+               if (!isset($logcache[$time][$object_id][$event])) {
+                       insert_data("INSERT DELAYED into {$CONFIG->dbprefix}system_log (object_id, object_class, object_type, object_subtype, event, performed_by_guid, owner_guid, access_id, enabled, time_created) VALUES ('$object_id','$object_class','$object_type', '$object_subtype', '$event',$performed_by, $owner_guid, $access_id, '$enabled', '$time')");
+
+                       $logcache[$time][$object_id][$event] = true;
+               }
+
                return true;
        }
-       
-       /** Register event to listen to all events **/
-       register_elgg_event_handler('all','all','system_log_listener', 400);
-       
-       /** Register a default system log handler */
-       register_elgg_event_handler('log','systemlog','system_log_default_logger', 999);
-       
-?>
\ No newline at end of file
+}
+
+/**
+ * This function creates an archive copy of the system log.
+ *
+ * @param int $offset An offset in seconds from now to archive (useful for log rotation)
+ */
+function archive_log($offset = 0) {
+       global $CONFIG;
+
+       $offset = (int)$offset;
+       $now = time(); // Take a snapshot of now
+
+       $ts = $now - $offset;
+
+       // create table
+       if (!update_data("CREATE TABLE {$CONFIG->dbprefix}system_log_$now as SELECT * from {$CONFIG->dbprefix}system_log WHERE time_created<$ts")) {
+               return false;
+       }
+
+       // delete
+       // Don't delete on time since we are running in a concurrent environment
+       if (delete_data("DELETE from {$CONFIG->dbprefix}system_log WHERE time_created<$ts") === false) {
+               return false;
+       }
+
+       // alter table to engine
+       if (!update_data("ALTER TABLE {$CONFIG->dbprefix}system_log_$now engine=archive")) {
+               return false;
+       }
+
+       return true;
+}
+
+/**
+ * Default system log handler, allows plugins to override, extend or disable logging.
+ *
+ * @param string $event
+ * @param string $object_type
+ * @param Loggable $object
+ * @return unknown
+ */
+function system_log_default_logger($event, $object_type, $object) {
+       system_log($object['object'], $object['event']);
+
+       return true;
+}
+
+/**
+ * System log listener.
+ * This function listens to all events in the system and logs anything appropriate.
+ *
+ * @param String $event
+ * @param String $object_type
+ * @param Loggable $object
+ */
+function system_log_listener($event, $object_type, $object) {
+       if (($object_type!='systemlog') && ($event!='log')) {
+               trigger_elgg_event('log', 'systemlog', array('object' => $object, 'event' => $event));
+       }
+
+       return true;
+}
+
+/** Register event to listen to all events **/
+register_elgg_event_handler('all','all','system_log_listener', 400);
+
+/** Register a default system log handler */
+register_elgg_event_handler('log','systemlog','system_log_default_logger', 999);
\ No newline at end of file
index d3db842d15144cfa02359c385514c1ea467f3444..3c65c2a7aac75534a1b84dfe430a8662a3396778 100644 (file)
 <?php
-       /**
-        * Elgg tags
-        * Functions for managing tags and tag clouds.
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd <info@elgg.com>
-
-        * @link http://elgg.org/
-        */
-
-       
-       /** 
-        * The algorithm working out the size of font based on the number of tags.
-        * This is quick and dirty.
-        */
-       function calculate_tag_size($min, $max, $number_of_tags, $buckets = 6)
-       {
-
-               $delta =  (($max - $min) / $buckets);
-               $thresholds = array();
-
-               for ($n=1; $n <= $buckets; $n++) {
-                       $thresholds[$n-1] = ($min + $n) * $delta;
-               }
-       
-               // Correction
-               if ($thresholds[$buckets-1]>$max) $thresholds[$buckets-1] = $max;
-
-               $size = 0;
-               for ($n = 0; $n < count($thresholds); $n++) {
-                       if ($number_of_tags >= $thresholds[$n]) 
-                               $size = $n;
+/**
+ * Elgg tags
+ * Functions for managing tags and tag clouds.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @link http://elgg.org/
+ */
+
+
+/**
+ * The algorithm working out the size of font based on the number of tags.
+ * This is quick and dirty.
+ */
+function calculate_tag_size($min, $max, $number_of_tags, $buckets = 6) {
+
+       $delta =  (($max - $min) / $buckets);
+       $thresholds = array();
+
+       for ($n=1; $n <= $buckets; $n++) {
+               $thresholds[$n-1] = ($min + $n) * $delta;
+       }
+
+       // Correction
+       if ($thresholds[$buckets-1]>$max) {
+               $thresholds[$buckets-1] = $max;
+       }
+
+       $size = 0;
+       for ($n = 0; $n < count($thresholds); $n++) {
+               if ($number_of_tags >= $thresholds[$n]) {
+                       $size = $n;
                }
+       }
+
+       return $size;
+}
+
+/**
+ * This function generates an array of tags with a weighting.
+ *
+ * @param array $tags The array of tags.
+ * @return An associated array of tags with a weighting, this can then be mapped to a display class.
+ */
+function generate_tag_cloud(array $tags, $buckets = 6) {
+       $cloud = array();
+
+       $min = 65535;
+       $max = 0;
+
+       foreach ($tags as $tag) {
+               $cloud[$tag]++;
 
-               return $size;
-       }
-       
-       /**
-        * This function generates an array of tags with a weighting.
-        *
-        * @param array $tags The array of tags.
-        * @return An associated array of tags with a weighting, this can then be mapped to a display class. 
-        */
-       function generate_tag_cloud(array $tags, $buckets = 6)
-       {
-               $cloud = array();
-               
-               $min = 65535;
-               $max = 0;
-               
-               foreach ($tags as $tag)
-               {
-                       $cloud[$tag]++;
-                       
-                       if ($cloud[$tag]>$max) $max = $cloud[$tag];
-                       if ($cloud[$tag]<$min) $min = $cloud[$tag];
+               if ($cloud[$tag]>$max) {
+                       $max = $cloud[$tag];
                }
-               
-               foreach ($cloud as $k => $v)
-                       $cloud[$k] = calculate_tag_size($min, $max, $v, $buckets);
-               
-               return $cloud;
-       }
-       
-       /**
-        * Get an array of tags with weights for use with the output/tagcloud view.
-        *
-        * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances)
-        * @param int $limit Number of tags to return
-        * @param string $metadata_name Optionally, the name of the field you want to grab for
-        * @param string $entity_type Optionally, the entity type ('object' etc)
-        * @param string $entity_subtype The entity subtype, optionally
-        * @param int $owner_guid The GUID of the tags owner, optionally
-        * @param int $site_guid Optionally, the site to restrict to (default is the current site)
-        * @param int $start_ts Optionally specify a start timestamp for tags used to generate cloud.
-        * @param int $ent_ts Optionally specify an end timestamp for tags used to generate cloud.
-        * @return array|false Array of objects with ->tag and ->total values, or false on failure
-        */
-       
-       function get_tags($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1, $start_ts = "", $end_ts = "") {
-               
-               global $CONFIG;
-               
-               $threshold = (int) $threshold;
-               $limit = (int) $limit;
-               
-               if (!empty($metadata_name)) {
-                       $metadata_name = (int) get_metastring_id($metadata_name);
-               } else {
-                       $metadata_name = 0;
+
+               if ($cloud[$tag]<$min) {
+                       $min = $cloud[$tag];
                }
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $entity_type = sanitise_string($entity_type);
-               
-               if ($owner_guid != "")
+       }
+
+       foreach ($cloud as $k => $v) {
+               $cloud[$k] = calculate_tag_size($min, $max, $v, $buckets);
+       }
+
+       return $cloud;
+}
+
+/**
+ * Get an array of tags with weights for use with the output/tagcloud view.
+ *
+ * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances)
+ * @param int $limit Number of tags to return
+ * @param string $metadata_name Optionally, the name of the field you want to grab for
+ * @param string $entity_type Optionally, the entity type ('object' etc)
+ * @param string $entity_subtype The entity subtype, optionally
+ * @param int $owner_guid The GUID of the tags owner, optionally
+ * @param int $site_guid Optionally, the site to restrict to (default is the current site)
+ * @param int $start_ts Optionally specify a start timestamp for tags used to generate cloud.
+ * @param int $ent_ts Optionally specify an end timestamp for tags used to generate cloud.
+ * @return array|false Array of objects with ->tag and ->total values, or false on failure
+ */
+
+function get_tags($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1, $start_ts = "", $end_ts = "") {
+       global $CONFIG;
+
+       $threshold = (int) $threshold;
+       $limit = (int) $limit;
+
+       if (!empty($metadata_name)) {
+               $metadata_name = (int) get_metastring_id($metadata_name);
+       } else {
+               $metadata_name = 0;
+       }
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $entity_type = sanitise_string($entity_type);
+
+       if ($owner_guid != "") {
                if (is_array($owner_guid)) {
-                       foreach($owner_guid as $key => $val)
+                       foreach($owner_guid as $key => $val) {
                                $owner_guid[$key] = (int) $val;
+                       }
                } else {
                        $owner_guid = (int) $owner_guid;
                }
-               
-               if ($site_guid < 0) {
-                       $site_guid = $CONFIG->site_id;
-               }
-               
-               //$access = get_access_list();
-               
-               $query = "SELECT msvalue.string as tag, count(msvalue.id) as total ";
-               $query .= "FROM {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}metadata md on md.entity_guid = e.guid ";
-               if ($entity_subtype > 0)
-                       $query .= " join {$CONFIG->dbprefix}entity_subtypes subtype on subtype.id = e.subtype ";
-               $query .= " join {$CONFIG->dbprefix}metastrings msvalue on msvalue.id = md.value_id ";
-               
-               $query .= " where msvalue.string != '' ";
-               
-               if ($metadata_name > 0) {
-                       $query .= " and md.name_id = {$metadata_name} ";
-               }
-               if ($site_guid > 0) {
-                       $query .= " and e.site_guid = {$site_guid} ";
-               }
-               if ($entity_subtype > 0) {
-                       $query .= " and e.subtype = {$entity_subtype} ";
-               }
-               if ($entity_type != "") {
-                       $query .= " and e.type = '{$entity_type}' ";
-               }
-               if (is_array($owner_guid)) {
-                       $query .= " and e.container_guid in (".implode(",",$owner_guid).")";
-               } else if (is_int($owner_guid)) {
-                       $query .= " and e.container_guid = {$owner_guid} ";
-               }
-               if ($start_ts) {
-                       $start_ts = (int)$start_ts;
-                       $query .= " and e.time_created>=$start_ts";
-               }
-                       
-               if ($end_ts) {
-                       $end_ts = (int)$end_ts;
-                       $query .= " and e.time_created<=$end_ts";
-               }
-               
-               //$userid = get_loggedin_userid();
-               //$query .= " and (e.access_id in {$access} or (e.access_id = " . ACCESS_PRIVATE . " and e.owner_guid = {$userid}))";
-               $query .= ' and ' . get_access_sql_suffix("e"); // Add access controls
-               
-               $query .= " group by msvalue.string having total > {$threshold} order by total desc limit {$limit} ";
-
-               return get_data($query);
-               
-       }
-
-       /**
-        * Loads and displays a tagcloud given particular criteria.
-        *
-        * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances)
-        * @param int $limit Number of tags to return
-        * @param string $metadata_name Optionally, the name of the field you want to grab for
-        * @param string $entity_type Optionally, the entity type ('object' etc)
-        * @param string $entity_subtype The entity subtype, optionally
-        * @param int $owner_guid The GUID of the tags owner, optionally
-        * @param int $site_guid Optionally, the site to restrict to (default is the current site)
-        * @return string THe HTML (or other, depending on view type) of the tagcloud.
-        */
-       
-       function display_tagcloud($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1) {
-               
-               return elgg_view("output/tagcloud",array('value' => get_tags($threshold, $limit, $metadata_name, $entity_type, $entity_subtype, $owner_guid, $site_guid),'object' => $entity_type, 'subtype' => $entity_subtype));
-               
-       }
-
-?>
\ No newline at end of file
+       }
+
+       if ($site_guid < 0) {
+               $site_guid = $CONFIG->site_id;
+       }
+
+       //$access = get_access_list();
+
+       $query = "SELECT msvalue.string as tag, count(msvalue.id) as total ";
+       $query .= "FROM {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}metadata md on md.entity_guid = e.guid ";
+       if ($entity_subtype > 0) {
+               $query .= " join {$CONFIG->dbprefix}entity_subtypes subtype on subtype.id = e.subtype ";
+       }
+       $query .= " join {$CONFIG->dbprefix}metastrings msvalue on msvalue.id = md.value_id ";
+
+       $query .= " where msvalue.string != '' ";
+
+       if ($metadata_name > 0) {
+               $query .= " and md.name_id = {$metadata_name} ";
+       }
+       if ($site_guid > 0) {
+               $query .= " and e.site_guid = {$site_guid} ";
+       }
+       if ($entity_subtype > 0) {
+               $query .= " and e.subtype = {$entity_subtype} ";
+       }
+       if ($entity_type != "") {
+               $query .= " and e.type = '{$entity_type}' ";
+       }
+       if (is_array($owner_guid)) {
+               $query .= " and e.container_guid in (".implode(",",$owner_guid).")";
+       } else if (is_int($owner_guid)) {
+               $query .= " and e.container_guid = {$owner_guid} ";
+       }
+       if ($start_ts) {
+               $start_ts = (int)$start_ts;
+               $query .= " and e.time_created>=$start_ts";
+       }
+
+       if ($end_ts) {
+               $end_ts = (int)$end_ts;
+               $query .= " and e.time_created<=$end_ts";
+       }
+
+       //$userid = get_loggedin_userid();
+       //$query .= " and (e.access_id in {$access} or (e.access_id = " . ACCESS_PRIVATE . " and e.owner_guid = {$userid}))";
+       $query .= ' and ' . get_access_sql_suffix("e"); // Add access controls
+
+       $query .= " group by msvalue.string having total > {$threshold} order by total desc limit {$limit} ";
+
+       return get_data($query);
+}
+
+/**
+ * Loads and displays a tagcloud given particular criteria.
+ *
+ * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances)
+ * @param int $limit Number of tags to return
+ * @param string $metadata_name Optionally, the name of the field you want to grab for
+ * @param string $entity_type Optionally, the entity type ('object' etc)
+ * @param string $entity_subtype The entity subtype, optionally
+ * @param int $owner_guid The GUID of the tags owner, optionally
+ * @param int $site_guid Optionally, the site to restrict to (default is the current site)
+ * @return string THe HTML (or other, depending on view type) of the tagcloud.
+ */
+
+function display_tagcloud($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1) {
+       return elgg_view("output/tagcloud",array('value' => get_tags($threshold, $limit, $metadata_name, $entity_type, $entity_subtype, $owner_guid, $site_guid),'object' => $entity_type, 'subtype' => $entity_subtype));
+}
\ No newline at end of file
index 6aecdc669aac9567a1b5f4b89cea9a5a857a6c17..7d1fa3d586788e175b901127052c57f934f81d72 100644 (file)
 <?php
-
+/**
+ * Elgg users
+ * Functions to manage multiple or single users in an Elgg install
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
+
+/// Map a username to a cached GUID
+$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 {
        /**
-        * Elgg users
-        * Functions to manage multiple or single users in an Elgg install
+        * Initialise the attributes array.
+        * This is vital to distinguish between metadata and base parameters.
         *
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd
-
-        * @link http://elgg.org/
+        * Place your base parameters here.
         */
-
-       /// Map a username to a cached GUID
-       $USERNAME_TO_GUID_MAP_CACHE = array();
-
-       /// Map a user code to a cached GUID
-       $CODE_TO_GUID_MAP_CACHE = array();
+       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['tables_split'] = 2;
+       }
 
        /**
-        * ElggUser
-        *
-        * Representation of a "user" in the system.
+        * Construct a new user entity, optionally from a given id value.
         *
-        * @package Elgg
-        * @subpackage Core
+        * @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.
         */
-       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['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));
+       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;
-
+                       // 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)
-                               {
-                                       foreach ($guid->attributes as $key => $value)
-                                               $this->attributes[$key] = $value;
+                       // Is $guid is an ElggUser? Use a copy constructor
+                       else if ($guid instanceof ElggUser) {
+                               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'));
+                       // 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)) IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid));
+                       // We assume if we have got this far, $guid is an int
+                       else if (is_numeric($guid)) {
+                               if (!$this->load($guid)) {
+                                       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())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter
-
-                       // 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()
-               {
-                       // Delete owned data
-                       clear_annotations_by_owner($this->guid);
-                       clear_metadata_by_owner($this->guid);
-
-                       // 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'; }
-
-               /**
-                * 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',
-                       ));
+                       else {
+                               throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue'));
+                       }
                }
        }
 
        /**
-        * Return the user specific details of a user by a row.
+        * 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
         */
-       function get_user_entity_as_row($guid)
-       {
-               global $CONFIG;
-
-               /*$row = retrieve_cached_entity_row($guid);
-               if ($row)
-               {
-                       // We have already cached this object, so retrieve its value from the cache
-                       if (isset($CONFIG->debug) && $CONFIG->debug == true)
-                               error_log("** Retrieving sub part of GUID:$guid from cache");
-
-                       return $row;
+       protected function load($guid) {
+               // Test to see if we have the generic stuff
+               if (!parent::load($guid)) {
+                       return false;
                }
-               else
-               {*/
-                       // Object not cached, load it.
-                       if (isset($CONFIG->debug) && $CONFIG->debug == true)
-                               error_log("** Sub part of GUID:$guid loaded from DB");
-
-                       $guid = (int)$guid;
 
-                       return get_data_row("SELECT * from {$CONFIG->dbprefix}users_entity where guid=$guid");
-               //}
-       }
+               // Check the type
+               if ($this->attributes['type']!='user') {
+                       throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class()));
+               }
 
-       /**
-        * Create or update the extras table for a given user.
-        * Call create_entity first.
-        *
-        * @param int $guid
-        * @param string $name
-        * @param string $description
-        * @param string $url
-        */
-       function create_user_entity($guid, $name, $username, $password, $salt, $email, $language, $code)
-       {
-               global $CONFIG;
-
-               $guid = (int)$guid;
-               $name = sanitise_string($name);
-               $username = sanitise_string($username);
-               $password = sanitise_string($password);
-               $salt = sanitise_string($salt);
-               $email = sanitise_string($email);
-               $language = sanitise_string($language);
-               $code = sanitise_string($code);
-
-               $row = get_entity_as_row($guid);
-               if ($row)
-               {
-                       // Exists and you have access to it
-
-                       if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}users_entity where guid = {$guid}")) {
-                               $result = update_data("UPDATE {$CONFIG->dbprefix}users_entity set name='$name', username='$username', password='$password', salt='$salt', email='$email', language='$language', code='$code', last_action = ". time() ." where guid = {$guid}");
-                               if ($result != false)
-                               {
-                                       // Update succeeded, continue
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('update',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete();
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               // Update failed, attempt an insert.
-                               $result = insert_data("INSERT into {$CONFIG->dbprefix}users_entity (guid, name, username, password, salt, email, language, code) values ($guid, '$name', '$username', '$password', '$salt', '$email', '$language', '$code')");
-                               if ($result!==false) {
-                                       $entity = get_entity($guid);
-                                       if (trigger_elgg_event('create',$entity->type,$entity)) {
-                                               return $guid;
-                                       } else {
-                                               $entity->delete(); //delete_entity($guid);
-                                       }
-                               }
-                       }
+               // 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 false;
+               return true;
        }
 
        /**
-        * Disables all of a user's entities
-        *
-        * @param int $owner_guid The owner GUID
-        * @return true|false Depending on success
+        * Saves this user to the database.
+        * @return true|false
         */
-       function disable_user_entities($owner_guid) {
-
-               global $CONFIG;
-               $owner_guid = (int) $owner_guid;
-               if ($entity = get_entity($owner_guid)) {
-                       if (trigger_elgg_event('disable',$entity->type,$entity)) {
-                               if ($entity->canEdit()) {
-                                       $res = update_data("UPDATE {$CONFIG->dbprefix}entities set enabled='no' where owner_guid={$owner_guid} or container_guid = {$owner_guid}");
-                                       return $res;
-                               }
-                       }
+       public function save() {
+               // Save generic stuff
+               if (!parent::save()) {
+                       return false;
                }
-               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'));
        }
 
        /**
-        * Ban a user
+        * User specific override of the entity delete method.
         *
-        * @param int $user_guid The user guid
-        * @param string $reason A reason
+        * @return bool
         */
-       function ban_user($user_guid, $reason = "")
-       {
-               global $CONFIG;
-
-               $user_guid = (int)$user_guid;
-               $reason = sanitise_string($reason);
-
-               $user = get_entity($user_guid);
-
-               if (($user) && ($user->canEdit()) && ($user instanceof ElggUser))
-               {
-                       if (trigger_elgg_event('ban', 'user', $user)) {
-                               // Add reason
-                               if ($reason)
-                                       create_metadata($user_guid, 'ban_reason', $reason,'', 0, ACCESS_PUBLIC);
-
-                               // Set ban flag
-                               return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='yes' where guid=$user_guid");
-                       }
-               }
+       public function delete() {
+               // Delete owned data
+               clear_annotations_by_owner($this->guid);
+               clear_metadata_by_owner($this->guid);
 
-               return false;
+               // Delete entity
+               return parent::delete();
        }
 
        /**
-        * Unban a user.
+        * Ban this user.
         *
-        * @param int $user_guid Unban a user.
+        * @param string $reason Optional reason
         */
-       function unban_user($user_guid)
-       {
-               global $CONFIG;
-
-               $user_guid = (int)$user_guid;
-
-               $user = get_entity($user_guid);
-
-               if (($user) && ($user->canEdit()) && ($user instanceof ElggUser))
-               {
-                       if (trigger_elgg_event('unban', 'user', $user)) {
-                               create_metadata($user_guid, 'ban_reason', '','', 0, ACCESS_PUBLIC);
-                               return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='no' where guid=$user_guid");
-                       }
-               }
-
-               return false;
+       public function ban($reason = "") {
+               return ban_user($this->guid, $reason);
        }
 
        /**
-        * THIS FUNCTION IS DEPRECATED.
-        *
-        * Delete a user's extra data.
-        *
-        * @param int $guid
+        * Unban this user.
         */
-       function delete_user_entity($guid)
-       {
-               system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
-
-               return 1; // Always return that we have deleted one row in order to not break existing code.
+       public function unban() {
+               return unban_user($this->guid);
        }
 
        /**
-        * Get the sites this user is part of
+        * Is this user banned or not?
         *
-        * @param int $user_guid The user's GUID
-        * @param int $limit Number of results to return
-        * @param int $offset Any indexing offset
-        * @return false|array On success, an array of ElggSites
+        * @return bool
         */
-       function get_user_sites($user_guid, $limit = 10, $offset = 0) {
-               $user_guid = (int)$user_guid;
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-
-               return get_entities_from_relationship("member_of_site", $user_guid, false, "site", "", 0, "time_created desc", $limit, $offset);
+       public function isBanned() {
+               return $this->banned == 'yes';
        }
 
        /**
-        * Adds a user to another user's friends list.
+        * Get sites that this user is a member of
         *
-        * @param int $user_guid The GUID of the friending user
-        * @param int $friend_guid The GUID of the user to friend
-        * @return true|false Depending on success
+        * @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 user_add_friend($user_guid, $friend_guid) {
-               $user_guid = (int) $user_guid;
-               $friend_guid = (int) $friend_guid;
-               if ($user_guid == $friend_guid) return false;
-               if (!$friend = get_entity($friend_guid)) return false;
-               if (!$user = get_entity($user_guid)) return false;
-               if ( (!($user instanceof ElggUser)) || (!($friend instanceof ElggUser)) ) return false;
-               return add_entity_relationship($user_guid, "friend", $friend_guid);
+       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);
        }
 
        /**
-        * Removes a user from another user's friends list.
+        * Add this user to a particular site
         *
-        * @param int $user_guid The GUID of the friending user
-        * @param int $friend_guid The GUID of the user on the friends list
-        * @return true|false Depending on success
+        * @param int $site_guid The guid of the site to add it to
+        * @return true|false
         */
-       function user_remove_friend($user_guid, $friend_guid) {
-               global $CONFIG;
-
-               $user_guid = (int) $user_guid;
-               $friend_guid = (int) $friend_guid;
-
-               // perform cleanup for access lists.
-               $collections = get_user_access_collections($user_guid);
-               foreach ($collections as $collection) {
-                       remove_user_from_access_collection($friend_guid, $collection->id);
-               }
-
-               return remove_entity_relationship($user_guid, "friend", $friend_guid);
+       function addToSite($site_guid) {
+               // return add_site_user($this->getGUID(), $site_guid);
+               return add_site_user($site_guid, $this->getGUID());
        }
 
        /**
-        * Determines whether or not a user is another user's friend.
+        * Remove this user from a particular site
         *
-        * @param int $user_guid The GUID of the user
-        * @param int $friend_guid The GUID of the friend
+        * @param int $site_guid The guid of the site to remove it from
         * @return true|false
         */
-       function user_is_friend($user_guid, $friend_guid) {
-               return check_entity_relationship($user_guid, "friend", $friend_guid);
+       function removeFromSite($site_guid) {
+               //return remove_site_user($this->getGUID(), $site_guid);
+               return remove_site_user($site_guid, $this->getGUID());
        }
 
        /**
-        * Obtains a given user's friends
+        * Adds a user to this user's friends list
         *
-        * @param int $user_guid The user's GUID
-        * @param string $subtype The subtype of users, if any
-        * @param int $limit Number of results to return (default 10)
-        * @param int $offset Indexing offset, if any
-        * @return false|array Either an array of ElggUsers or false, depending on success
+        * @param int $friend_guid The GUID of the user to add
+        * @return true|false Depending on success
         */
-       function get_user_friends($user_guid, $subtype = "", $limit = 10, $offset = 0) {
-               return get_entities_from_relationship("friend",$user_guid,false,"user",$subtype,0,"time_created desc",$limit,$offset);
+       function addFriend($friend_guid) {
+               return user_add_friend($this->getGUID(), $friend_guid);
        }
 
        /**
-        * Obtains the people who have made a given user a friend
+        * Removes a user from this user's friends list
         *
-        * @param int $user_guid The user's GUID
-        * @param string $subtype The subtype of users, if any
-        * @param int $limit Number of results to return (default 10)
-        * @param int $offset Indexing offset, if any
-        * @return false|array Either an array of ElggUsers or false, depending on success
+        * @param int $friend_guid The GUID of the user to remove
+        * @return true|false Depending on success
         */
-       function get_user_friends_of($user_guid, $subtype = "", $limit = 10, $offset = 0) {
-               return get_entities_from_relationship("friend",$user_guid,true,"user",$subtype,0,"time_created desc",$limit,$offset);
+       function removeFriend($friend_guid) {
+               return user_remove_friend($this->getGUID(), $friend_guid);
        }
 
        /**
-        * Obtains a list of objects owned by a user
+        * Determines whether or not this user is a friend of the currently logged in user
         *
-        * @param int $user_guid The GUID of the owning user
-        * @param string $subtype Optionally, the subtype of objects
-        * @param int $limit The number of results to return (default 10)
-        * @param int $offset Indexing offset, if any
-        * @param int $timelower The earliest time the entity can have been created. Default: all
-        * @param int $timeupper The latest time the entity can have been created. Default: all
-        * @return false|array An array of ElggObjects or false, depending on success
+        * @return true|false
         */
-       function get_user_objects($user_guid, $subtype = "", $limit = 10, $offset = 0, $timelower = 0, $timeupper = 0) {
-               $ntt = get_entities('object',$subtype, $user_guid, "time_created desc", $limit, $offset,false,0,$user_guid,$timelower, $timeupper);
-               return $ntt;
+       function isFriend() {
+               return user_is_friend(get_loggedin_userid(), $this->getGUID());
        }
 
        /**
-        * Counts the objects (optionally of a particular subtype) owned by a user
+        * Determines whether this user is friends with another user
         *
-        * @param int $user_guid The GUID of the owning user
-        * @param string $subtype Optionally, the subtype of objects
-        * @param int $timelower The earliest time the entity can have been created. Default: all
-        * @param int $timeupper The latest time the entity can have been created. Default: all
-        * @return int The number of objects the user owns (of this subtype)
+        * @param int $user_guid The GUID of the user to check is on this user's friends list
+        * @return true|false
         */
-       function count_user_objects($user_guid, $subtype = "", $timelower, $timeupper) {
-               $total = get_entities('object', $subtype, $user_guid, "time_created desc", null, null, true, 0, $user_guid,$timelower,$timeupper);
-               return $total;
+       function isFriendsWith($user_guid) {
+               return user_is_friend($this->getGUID(), $user_guid);
        }
 
        /**
-        * Displays a list of user objects of a particular subtype, with navigation.
-        *
-        * @see elgg_view_entity_list
+        * Determines whether or not this user is on another user's friends list
         *
-        * @param int $user_guid The GUID of the user
-        * @param string $subtype The object subtype
-        * @param int $limit The number of entities to display on a page
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param int $timelower The earliest time the entity can have been created. Default: all
-        * @param int $timeupper The latest time the entity can have been created. Default: all
-        * @return string The list in a form suitable to display
+        * @param int $user_guid The GUID of the user to check against
+        * @return true|false
         */
-       function list_user_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true, $timelower = 0, $timeupper = 0) {
-
-               $offset = (int) get_input('offset');
-               $limit = (int) $limit;
-               $count = (int) count_user_objects($user_guid, $subtype,$timelower,$timeupper);
-               $entities = get_user_objects($user_guid, $subtype, $limit, $offset, $timelower, $timeupper);
-
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-
+       function isFriendOf($user_guid) {
+               return user_is_friend($user_guid, $this->getGUID());
        }
 
        /**
-        * Obtains a list of objects owned by a user's friends
+        * Retrieves a list of this user's friends
         *
-        * @param int $user_guid The GUID of the user to get the friends of
-        * @param string $subtype Optionally, the subtype of objects
-        * @param int $limit The number of results to return (default 10)
+        * @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 false|array An array of ElggObjects or false, depending on success
+        * @return array|false Array of ElggUsers, or false, depending on success
         */
-       function get_user_friends_objects($user_guid, $subtype = "", $limit = 10, $offset = 0) {
-               if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) {
-                       $friendguids = array();
-                       foreach($friends as $friend) {
-                               $friendguids[] = $friend->getGUID();
-                       }
-                       return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, false, 0, $friendguids);
-               }
-               return false;
+       function getFriends($subtype = "", $limit = 10, $offset = 0) {
+               return get_user_friends($this->getGUID(), $subtype, $limit, $offset);
        }
 
        /**
-        * Counts the number of objects owned by a user's friends
+        * Retrieves a list of people who have made this user a friend
         *
-        * @param int $user_guid The GUID of the user to get the friends of
-        * @param string $subtype Optionally, the subtype of objects
-        * @return int The number of objects
+        * @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 count_user_friends_objects($user_guid, $subtype = "") {
-               if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) {
-                       $friendguids = array();
-                       foreach($friends as $friend) {
-                               $friendguids[] = $friend->getGUID();
-                       }
-                       return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, true, 0, $friendguids);
-               }
-               return 0;
+       function getFriendsOf($subtype = "", $limit = 10, $offset = 0) {
+               return get_user_friends_of($this->getGUID(), $subtype, $limit, $offset);
        }
 
        /**
-        * Displays a list of a user's friends' objects of a particular subtype, with navigation.
+        * Get an array of ElggObjects owned by this user.
         *
-        * @see elgg_view_entity_list
-        *
-        * @param int $user_guid The GUID of the user
-        * @param string $subtype The object subtype
-        * @param int $limit The number of entities to display on a page
-        * @param true|false $fullview Whether or not to display the full view (default: true)
-        * @param true|false $viewtypetoggle Whether or not to allow you to flip to gallery mode (default: true)
-        * @return string The list in a form suitable to display
+        * @param string $subtype The subtype of the objects, if any
+        * @param int $limit Number of results to return
+        * @param int $offset Any indexing offset
         */
-       function list_user_friends_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) {
-
-               $offset = (int) get_input('offset');
-               $limit = (int) $limit;
-               $count = (int) count_user_friends_objects($user_guid, $subtype);
-               $entities = get_user_friends_objects($user_guid, $subtype, $limit, $offset);
-
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-
+       public function getObjects($subtype="", $limit = 10, $offset = 0) {
+               return get_user_objects($this->getGUID(), $subtype, $limit, $offset);
        }
 
        /**
-        * Get user objects by an array of metadata
+        * Get an array of ElggObjects owned by this user's friends.
         *
-        * @param int $user_guid The GUID of the owning user
-        * @param string $subtype Optionally, the subtype of objects
-        * @paran array $metadata An array of metadata
-        * @param int $limit The number of results to return (default 10)
-        * @param int $offset Indexing offset, if any
-        * @return false|array An array of ElggObjects or false, depending on success
-        * @return unknown
+        * @param string $subtype The subtype of the objects, if any
+        * @param int $limit Number of results to return
+        * @param int $offset Any indexing offset
         */
-       function get_user_objects_by_metadata($user_guid, $subtype = "", $metadata = array(), $limit = 0, $offset = 0) {
-
-               return get_entities_from_metadata_multi($metadata,"object",$subtype,$user_guid,$limit,$offset);
-
+       public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) {
+               return get_user_friends_objects($this->getGUID(), $subtype, $limit, $offset);
        }
 
        /**
-        * Get a user object from a GUID.
+        * Counts the number of ElggObjects owned by this user
         *
-        * This function returns an ElggUser from a given GUID.
-        * @param int $guid The GUID
-        * @return ElggUser|false
+        * @param string $subtype The subtypes of the objects, if any
+        * @return int The number of ElggObjects
         */
-       function get_user($guid)
-       {
-               if (!empty($guid)) // Fixes "Exception thrown without stack frame" when db_select fails
-                       $result = get_entity($guid);
-
-               if ((!empty($result)) && (!($result instanceof ElggUser)))
-                       //throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, 'ElggUser'));
-                       return false;
-
-               if (!empty($result))
-                       return $result;
-
-               return false;
+       public function countObjects($subtype = "") {
+               return count_user_objects($this->getGUID(), $subtype);
        }
 
        /**
-        * Get user by username
+        * Get the collections associated with a user.
         *
-        * @param string $username The user's username
-        * @return ElggUser|false Depending on success
+        * @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
         */
-       function get_user_by_username($username)
-       {
-               global $CONFIG, $USERNAME_TO_GUID_MAP_CACHE;
-
-               $username = sanitise_string($username);
-               $access = get_access_sql_suffix('e');
-
-               // Caching
-               if ( (isset($USERNAME_TO_GUID_MAP_CACHE[$username])) && (retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username])) )
-                       return retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]);
-
-               $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.username='$username' and $access ");
-               if ($row) {
-                       $USERNAME_TO_GUID_MAP_CACHE[$username] = $row->guid;
-                       return new ElggUser($row);
-               }
-
-               return false;
+       public function getCollections($subtype="", $limit = 10, $offset = 0) {
+               return get_user_collections($this->getGUID(), $subtype, $limit, $offset);
        }
 
        /**
-        * Get user by session code
+        * If a user's owner is blank, return its own GUID as the owner
         *
-        * @param string $code The session code
-        * @return ElggUser|false Depending on success
+        * @return int User GUID
         */
-       function get_user_by_code($code)
-       {
-               global $CONFIG, $CODE_TO_GUID_MAP_CACHE;
-
-               $code = sanitise_string($code);
-
-               $access = get_access_sql_suffix('e');
-
-               // Caching
-               if ( (isset($CODE_TO_GUID_MAP_CACHE[$code])) && (retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code])) )
-                       return retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]);
-
-               $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.code='$code' and $access");
-               if ($row) {
-                       $CODE_TO_GUID_MAP_CACHE[$code] = $row->guid;
-                       return new ElggUser($row);
+       function getOwner() {
+               if ($this->owner_guid == 0) {
+                       return $this->getGUID();
                }
 
-               return false;
+               return $this->owner_guid;
        }
 
-       /**
-        * Get an array of users from their
-        *
-        * @param string $email Email address.
-        * @return Array of users
-        */
-       function get_user_by_email($email)
-       {
-               global $CONFIG;
-
-               $email = sanitise_string($email);
-
-               $access = get_access_sql_suffix('e');
-
-               $query = "SELECT e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where email='$email' and $access";
-
-               return get_data($query, 'entity_row_to_elggstar');
-       }
+       // EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
 
        /**
-        * Searches for a user based on a complete or partial name or username.
-        *
-        * @param string $criteria The partial or full name or username.
-        * @param int $limit Limit of the search.
-        * @param int $offset Offset.
-        * @param string $order_by The order.
-        * @param boolean $count Whether to return the count of results or just the results.
+        * Return an array of fields which can be exported.
         */
-       function search_for_user($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false)
+       public function getExportableValues() {
+               return array_merge(parent::getExportableValues(), array(
+                       'name',
+                       'username',
+                       'language',
+               ));
+       }
+}
+
+/**
+ * Return the user specific details of a user by a row.
+ *
+ * @param int $guid
+ */
+function get_user_entity_as_row($guid) {
+       global $CONFIG;
+
+       /*$row = retrieve_cached_entity_row($guid);
+       if ($row)
        {
-               global $CONFIG;
+               // We have already cached this object, so retrieve its value from the cache
+               if (isset($CONFIG->debug) && $CONFIG->debug == true)
+                       error_log("** Retrieving sub part of GUID:$guid from cache");
 
-               $criteria = sanitise_string($criteria);
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               $order_by = sanitise_string($order_by);
-
-               $access = get_access_sql_suffix("e");
-
-               if ($order_by == "") $order_by = "e.time_created desc";
+               return $row;
+       }
+       else
+       {*/
+       // Object not cached, load it.
+       if (isset($CONFIG->debug) && $CONFIG->debug == true) {
+               error_log("** Sub part of GUID:$guid loaded from DB");
+       }
 
-               if ($count) {
-                       $query = "SELECT count(e.guid) as total ";
-               } else {
-                       $query = "SELECT e.* ";
-               }
-               $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where ";
-               // $query .= " match(u.name,u.username) against ('$criteria') ";
-               $query .= "(u.name like \"%{$criteria}%\" or u.username like \"%{$criteria}%\")";
-               $query .= " and $access";
-
-               if (!$count) {
-                       $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
+       $guid = (int)$guid;
+
+       return get_data_row("SELECT * from {$CONFIG->dbprefix}users_entity where guid=$guid");
+       //}
+}
+
+/**
+ * Create or update the extras table for a given user.
+ * Call create_entity first.
+ *
+ * @param int $guid
+ * @param string $name
+ * @param string $description
+ * @param string $url
+ */
+function create_user_entity($guid, $name, $username, $password, $salt, $email, $language, $code) {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+       $name = sanitise_string($name);
+       $username = sanitise_string($username);
+       $password = sanitise_string($password);
+       $salt = sanitise_string($salt);
+       $email = sanitise_string($email);
+       $language = sanitise_string($language);
+       $code = sanitise_string($code);
+
+       $row = get_entity_as_row($guid);
+       if ($row) {
+               // Exists and you have access to it
+
+               if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}users_entity where guid = {$guid}")) {
+                       $result = update_data("UPDATE {$CONFIG->dbprefix}users_entity set name='$name', username='$username', password='$password', salt='$salt', email='$email', language='$language', code='$code', last_action = ". time() ." where guid = {$guid}");
+                       if ($result != false) {
+                               // Update succeeded, continue
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('update',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete();
+                               }
+                       }
                } else {
-                       if ($count = get_data_row($query)) {
-                               return $count->total;
+                       // Update failed, attempt an insert.
+                       $result = insert_data("INSERT into {$CONFIG->dbprefix}users_entity (guid, name, username, password, salt, email, language, code) values ($guid, '$name', '$username', '$password', '$salt', '$email', '$language', '$code')");
+                       if ($result!==false) {
+                               $entity = get_entity($guid);
+                               if (trigger_elgg_event('create',$entity->type,$entity)) {
+                                       return $guid;
+                               } else {
+                                       $entity->delete(); //delete_entity($guid);
+                               }
                        }
                }
-               return false;
        }
 
-       /**
-        * Displays a list of user objects that have been searched for.
-        *
-        * @see elgg_view_entity_list
-        *
-        * @param string $tag Search criteria
-        * @param int $limit The number of entities to display on a page
-        * @return string The list in a form suitable to display
-        */
-       function list_user_search($tag, $limit = 10) {
-
-               $offset = (int) get_input('offset');
-               $limit = (int) $limit;
-               $count = (int) search_for_user($tag, 10, 0, '', true);
-               $entities = search_for_user($tag, $limit, $offset);
-
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false);
-
+       return false;
+}
+
+/**
+ * Disables all of a user's entities
+ *
+ * @param int $owner_guid The owner GUID
+ * @return true|false Depending on success
+ */
+function disable_user_entities($owner_guid) {
+       global $CONFIG;
+       $owner_guid = (int) $owner_guid;
+       if ($entity = get_entity($owner_guid)) {
+               if (trigger_elgg_event('disable',$entity->type,$entity)) {
+                       if ($entity->canEdit()) {
+                               $res = update_data("UPDATE {$CONFIG->dbprefix}entities set enabled='no' where owner_guid={$owner_guid} or container_guid = {$owner_guid}");
+                               return $res;
+                       }
+               }
        }
 
-       /**
-        * A function that returns a maximum of $limit users who have done something within the last
-        * $seconds seconds.
-        *
-        * @param int $seconds Number of seconds (default 600 = 10min)
-        * @param int $limit Limit, default 10.
-        * @param int $offset Offset, defualt 0.
-        */
-       function find_active_users($seconds = 600, $limit = 10, $offset = 0)
-       {
-               global $CONFIG;
+       return false;
+}
 
-               $seconds = (int)$seconds;
-               $limit = (int)$limit;
-               $offset = (int)$offset;
+/**
+ * Ban a user
+ *
+ * @param int $user_guid The user guid
+ * @param string $reason A reason
+ */
+function ban_user($user_guid, $reason = "") {
+       global $CONFIG;
 
-               $time = time() - $seconds;
+       $user_guid = (int)$user_guid;
+       $reason = sanitise_string($reason);
 
-               $access = get_access_sql_suffix("e");
+       $user = get_entity($user_guid);
 
-               $query = "SELECT distinct e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid = u.guid where u.last_action >= {$time} and $access order by u.last_action desc limit {$offset},{$limit}";
+       if (($user) && ($user->canEdit()) && ($user instanceof ElggUser)) {
+               if (trigger_elgg_event('ban', 'user', $user)) {
+                       // Add reason
+                       if ($reason) {
+                               create_metadata($user_guid, 'ban_reason', $reason,'', 0, ACCESS_PUBLIC);
+                       }
 
-               return get_data($query, "entity_row_to_elggstar");
+                       // Set ban flag
+                       return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='yes' where guid=$user_guid");
+               }
        }
 
-       /**
-        * Generate and send a password request email to a given user's registered email address.
-        *
-        * @param int $user_guid
-        */
-       function send_new_password_request($user_guid)
-       {
-               global $CONFIG;
-
-               $user_guid = (int)$user_guid;
+       return false;
+}
 
-               $user = get_entity($user_guid);
-               if ($user)
-               {
-                       // generate code
-                       $code = generate_random_cleartext_password();
-                       //create_metadata($user_guid, 'conf_code', $code,'', 0, ACCESS_PRIVATE);
-                       set_private_setting($user_guid, 'passwd_conf_code', $code);
-
-                       // generate link
-                       $link = $CONFIG->site->url . "action/user/passwordreset?u=$user_guid&c=$code";
+/**
+ * Unban a user.
+ *
+ * @param int $user_guid Unban a user.
+ */
+function unban_user($user_guid) {
+       global $CONFIG;
 
-                       // generate email
-                       $email = sprintf(elgg_echo('email:resetreq:body'), $user->name, $_SERVER['REMOTE_ADDR'], $link);
+       $user_guid = (int)$user_guid;
 
-                       return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetreq:subject'), $email, NULL, 'email');
+       $user = get_entity($user_guid);
 
+       if (($user) && ($user->canEdit()) && ($user instanceof ElggUser)) {
+               if (trigger_elgg_event('unban', 'user', $user)) {
+                       create_metadata($user_guid, 'ban_reason', '','', 0, ACCESS_PUBLIC);
+                       return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='no' where guid=$user_guid");
                }
+       }
 
+       return false;
+}
+
+/**
+ * THIS FUNCTION IS DEPRECATED.
+ *
+ * Delete a user's extra data.
+ *
+ * @param int $guid
+ */
+function delete_user_entity($guid) {
+       system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity'));
+
+       return 1; // Always return that we have deleted one row in order to not break existing code.
+}
+
+/**
+ * Get the sites this user is part of
+ *
+ * @param int $user_guid The user's GUID
+ * @param int $limit Number of results to return
+ * @param int $offset Any indexing offset
+ * @return false|array On success, an array of ElggSites
+ */
+function get_user_sites($user_guid, $limit = 10, $offset = 0) {
+       $user_guid = (int)$user_guid;
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+
+       return get_entities_from_relationship("member_of_site", $user_guid, false, "site", "", 0, "time_created desc", $limit, $offset);
+}
+
+/**
+ * Adds a user to another user's friends list.
+ *
+ * @param int $user_guid The GUID of the friending user
+ * @param int $friend_guid The GUID of the user to friend
+ * @return true|false Depending on success
+ */
+function user_add_friend($user_guid, $friend_guid) {
+       $user_guid = (int) $user_guid;
+       $friend_guid = (int) $friend_guid;
+       if ($user_guid == $friend_guid) {
                return false;
        }
-
-       /**
-        * Low level function to reset a given user's password.
-        *
-        * This can only be called from execute_new_password_request().
-        *
-        * @param int $user_guid The user.
-        * @param string $password password text (which will then be converted into a hash and stored)
-        */
-       function force_user_password_reset($user_guid, $password)
-       {
-               global $CONFIG;
-
-               if (call_gatekeeper('execute_new_password_request', __FILE__))
-               {
-                       $user = get_entity($user_guid);
-
-                       if ($user)
-                       {
-                               $salt = generate_random_cleartext_password(); // Reset the salt
-                               $user->salt = $salt;
-
-                               $hash = generate_user_password($user, $password);
-
-                               return update_data("UPDATE {$CONFIG->dbprefix}users_entity set password='$hash', salt='$salt' where guid=$user_guid");
-                       }
-               }
-
+       if (!$friend = get_entity($friend_guid)) {
                return false;
        }
-
-       /**
-        * Validate and execute a password reset for a user.
-        *
-        * @param int $user_guid The user id
-        * @param string $conf_code Confirmation code as sent in the request email.
-        */
-       function execute_new_password_request($user_guid, $conf_code)
-       {
-               global $CONFIG;
-
-               $user_guid = (int)$user_guid;
-
-               $user = get_entity($user_guid);
-               if (($user) && (get_private_setting($user_guid, 'passwd_conf_code') == $conf_code))
-               {
-                       $password = generate_random_cleartext_password();
-
-                       if (force_user_password_reset($user_guid, $password))
-                       {
-                               //remove_metadata($user_guid, 'conf_code');
-                               remove_private_setting($user_guid, 'passwd_conf_code');
-
-                               $email = sprintf(elgg_echo('email:resetpassword:body'), $user->name, $password);
-
-                               return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetpassword:subject'), $email, NULL, 'email');
-                       }
-               }
-
+       if (!$user = get_entity($user_guid)) {
+               return false;
+       }
+       if ((!($user instanceof ElggUser)) || (!($friend instanceof ElggUser))) {
                return false;
        }
+       return add_entity_relationship($user_guid, "friend", $friend_guid);
+}
+
+/**
+ * Removes a user from another user's friends list.
+ *
+ * @param int $user_guid The GUID of the friending user
+ * @param int $friend_guid The GUID of the user on the friends list
+ * @return true|false Depending on success
+ */
+function user_remove_friend($user_guid, $friend_guid) {
+       global $CONFIG;
+
+       $user_guid = (int) $user_guid;
+       $friend_guid = (int) $friend_guid;
+
+       // perform cleanup for access lists.
+       $collections = get_user_access_collections($user_guid);
+       foreach ($collections as $collection) {
+               remove_user_from_access_collection($friend_guid, $collection->id);
+       }
 
-       /**
-        * Set the validation status for a user.
-        *
-        * @param bool $status Validated (true) or false
-        * @param string $method Optional method to say how a user was validated
-        * @return bool
-        */
-       function set_user_validation_status($user_guid, $status, $method = '')
-       {
-               if (!$status) $method = '';
-
-               if ($status)
-               {
-                       if (
-                               (create_metadata($user_guid, 'validated', $status,'', 0, ACCESS_PUBLIC)) &&
-                               (create_metadata($user_guid, 'validated_method', $method,'', 0, ACCESS_PUBLIC))
-                       )
-                               return true;
+       return remove_entity_relationship($user_guid, "friend", $friend_guid);
+}
+
+/**
+ * Determines whether or not a user is another user's friend.
+ *
+ * @param int $user_guid The GUID of the user
+ * @param int $friend_guid The GUID of the friend
+ * @return true|false
+ */
+function user_is_friend($user_guid, $friend_guid) {
+       return check_entity_relationship($user_guid, "friend", $friend_guid);
+}
+
+/**
+ * Obtains a given user's friends
+ *
+ * @param int $user_guid The user's GUID
+ * @param string $subtype The subtype of users, if any
+ * @param int $limit Number of results to return (default 10)
+ * @param int $offset Indexing offset, if any
+ * @return false|array Either an array of ElggUsers or false, depending on success
+ */
+function get_user_friends($user_guid, $subtype = "", $limit = 10, $offset = 0) {
+       return get_entities_from_relationship("friend",$user_guid,false,"user",$subtype,0,"time_created desc",$limit,$offset);
+}
+
+/**
+ * Obtains the people who have made a given user a friend
+ *
+ * @param int $user_guid The user's GUID
+ * @param string $subtype The subtype of users, if any
+ * @param int $limit Number of results to return (default 10)
+ * @param int $offset Indexing offset, if any
+ * @return false|array Either an array of ElggUsers or false, depending on success
+ */
+function get_user_friends_of($user_guid, $subtype = "", $limit = 10, $offset = 0) {
+       return get_entities_from_relationship("friend",$user_guid,true,"user",$subtype,0,"time_created desc",$limit,$offset);
+}
+
+/**
+ * Obtains a list of objects owned by a user
+ *
+ * @param int $user_guid The GUID of the owning user
+ * @param string $subtype Optionally, the subtype of objects
+ * @param int $limit The number of results to return (default 10)
+ * @param int $offset Indexing offset, if any
+ * @param int $timelower The earliest time the entity can have been created. Default: all
+ * @param int $timeupper The latest time the entity can have been created. Default: all
+ * @return false|array An array of ElggObjects or false, depending on success
+ */
+function get_user_objects($user_guid, $subtype = "", $limit = 10, $offset = 0, $timelower = 0, $timeupper = 0) {
+       $ntt = get_entities('object',$subtype, $user_guid, "time_created desc", $limit, $offset,false,0,$user_guid,$timelower, $timeupper);
+       return $ntt;
+}
+
+/**
+ * Counts the objects (optionally of a particular subtype) owned by a user
+ *
+ * @param int $user_guid The GUID of the owning user
+ * @param string $subtype Optionally, the subtype of objects
+ * @param int $timelower The earliest time the entity can have been created. Default: all
+ * @param int $timeupper The latest time the entity can have been created. Default: all
+ * @return int The number of objects the user owns (of this subtype)
+ */
+function count_user_objects($user_guid, $subtype = "", $timelower, $timeupper) {
+       $total = get_entities('object', $subtype, $user_guid, "time_created desc", null, null, true, 0, $user_guid,$timelower,$timeupper);
+       return $total;
+}
+
+/**
+ * Displays a list of user objects of a particular subtype, with navigation.
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param int $user_guid The GUID of the user
+ * @param string $subtype The object subtype
+ * @param int $limit The number of entities to display on a page
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param int $timelower The earliest time the entity can have been created. Default: all
+ * @param int $timeupper The latest time the entity can have been created. Default: all
+ * @return string The list in a form suitable to display
+ */
+function list_user_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true, $timelower = 0, $timeupper = 0) {
+       $offset = (int) get_input('offset');
+       $limit = (int) $limit;
+       $count = (int) count_user_objects($user_guid, $subtype,$timelower,$timeupper);
+       $entities = get_user_objects($user_guid, $subtype, $limit, $offset, $timelower, $timeupper);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Obtains a list of objects owned by a user's friends
+ *
+ * @param int $user_guid The GUID of the user to get the friends of
+ * @param string $subtype Optionally, the subtype of objects
+ * @param int $limit The number of results to return (default 10)
+ * @param int $offset Indexing offset, if any
+ * @return false|array An array of ElggObjects or false, depending on success
+ */
+function get_user_friends_objects($user_guid, $subtype = "", $limit = 10, $offset = 0) {
+       if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) {
+               $friendguids = array();
+               foreach($friends as $friend) {
+                       $friendguids[] = $friend->getGUID();
                }
-               else
-               {
-                       $validated = get_metadata_byname($user_guid,  'validated');
-                       $validated_method = get_metadata_byname($user_guid,  'validated_method');
-
-                       if (
-                               ($validated) &&
-                               ($validated_method) &&
-                               (delete_metadata($validated->id)) &&
-                               (delete_metadata($validated_method->id))
-                       )
-                               return true;
+               return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, false, 0, $friendguids);
+       }
+       return false;
+}
+
+/**
+ * Counts the number of objects owned by a user's friends
+ *
+ * @param int $user_guid The GUID of the user to get the friends of
+ * @param string $subtype Optionally, the subtype of objects
+ * @return int The number of objects
+ */
+function count_user_friends_objects($user_guid, $subtype = "") {
+       if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) {
+               $friendguids = array();
+               foreach($friends as $friend) {
+                       $friendguids[] = $friend->getGUID();
                }
+               return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, true, 0, $friendguids);
+       }
+       return 0;
+}
+
+/**
+ * Displays a list of a user's friends' objects of a particular subtype, with navigation.
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param int $user_guid The GUID of the user
+ * @param string $subtype The object subtype
+ * @param int $limit The number of entities to display on a page
+ * @param true|false $fullview Whether or not to display the full view (default: true)
+ * @param true|false $viewtypetoggle Whether or not to allow you to flip to gallery mode (default: true)
+ * @return string The list in a form suitable to display
+ */
+function list_user_friends_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) {
+       $offset = (int) get_input('offset');
+       $limit = (int) $limit;
+       $count = (int) count_user_friends_objects($user_guid, $subtype);
+       $entities = get_user_friends_objects($user_guid, $subtype, $limit, $offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Get user objects by an array of metadata
+ *
+ * @param int $user_guid The GUID of the owning user
+ * @param string $subtype Optionally, the subtype of objects
+ * @paran array $metadata An array of metadata
+ * @param int $limit The number of results to return (default 10)
+ * @param int $offset Indexing offset, if any
+ * @return false|array An array of ElggObjects or false, depending on success
+ * @return unknown
+ */
+function get_user_objects_by_metadata($user_guid, $subtype = "", $metadata = array(), $limit = 0, $offset = 0) {
+       return get_entities_from_metadata_multi($metadata,"object",$subtype,$user_guid,$limit,$offset);
+}
+
+/**
+ * Get a user object from a GUID.
+ *
+ * This function returns an ElggUser from a given GUID.
+ * @param int $guid The GUID
+ * @return ElggUser|false
+ */
+function get_user($guid) {
+       // Fixes "Exception thrown without stack frame" when db_select fails
+       if (!empty($guid)) {
+               $result = get_entity($guid);
+       }
 
+       if ((!empty($result)) && (!($result instanceof ElggUser))) {
+               //throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, 'ElggUser'));
                return false;
        }
 
-       /**
-        * Trigger an event requesting that a user guid be validated somehow - either by email address or some other way.
-        *
-        * This event invalidates any existing values and returns
-        *
-        * @param unknown_type $user_guid
-        */
-       function request_user_validation($user_guid)
-       {
-               $user = get_entity($user_guid);
+       if (!empty($result)) {
+               return $result;
+       }
 
-               if (($user) && ($user instanceof ElggUser))
-               {
-                       // invalidate any existing validations
-                       set_user_validation_status($user_guid, false);
+       return false;
+}
 
-                       // request validation
-                       trigger_elgg_event('validate', 'user', $user);
+/**
+ * Get user by username
+ *
+ * @param string $username The user's username
+ * @return ElggUser|false Depending on success
+ */
+function get_user_by_username($username) {
+       global $CONFIG, $USERNAME_TO_GUID_MAP_CACHE;
 
-               }
+       $username = sanitise_string($username);
+       $access = get_access_sql_suffix('e');
+
+       // Caching
+       if ( (isset($USERNAME_TO_GUID_MAP_CACHE[$username])) && (retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username])) ) {
+               return retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]);
        }
 
-       /**
-        * Validates an email address.
-        *
-        * @param string $address Email address.
-        * @return bool
-        */
-       function is_email_address($address)
-       {
-               // TODO: Make this better!
+       $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.username='$username' and $access ");
+       if ($row) {
+               $USERNAME_TO_GUID_MAP_CACHE[$username] = $row->guid;
+               return new ElggUser($row);
+       }
 
-               if (strpos($address, '@')=== false)
-                       return false;
+       return false;
+}
 
-               if (strpos($address, '.')=== false)
-                       return false;
+/**
+ * Get user by session code
+ *
+ * @param string $code The session code
+ * @return ElggUser|false Depending on success
+ */
+function get_user_by_code($code) {
+       global $CONFIG, $CODE_TO_GUID_MAP_CACHE;
 
-               return true;
-       }
+       $code = sanitise_string($code);
 
-       /**
-        * Simple function that will generate a random clear text password suitable for feeding into generate_user_password().
-        *
-        * @see generate_user_password
-        * @return string
-        */
-       function generate_random_cleartext_password()
-       {
-               return substr(md5(microtime() . rand()), 0, 8);
+       $access = get_access_sql_suffix('e');
+
+       // Caching
+       if ( (isset($CODE_TO_GUID_MAP_CACHE[$code])) && (retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code])) ) {
+               return retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]);
        }
 
-       /**
-        * Generate a password for a user, currently uses MD5.
-        *
-        * Later may introduce salting etc.
-        *
-        * @param ElggUser $user The user this is being generated for.
-        * @param string $password Password in clear text
-        */
-       function generate_user_password(ElggUser $user, $password)
-       {
-               return md5($password . $user->salt);
+       $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.code='$code' and $access");
+       if ($row) {
+               $CODE_TO_GUID_MAP_CACHE[$code] = $row->guid;
+               return new ElggUser($row);
        }
 
-       /**
-        * Simple function which ensures that a username contains only valid characters.
-        *
-        * This should only permit chars that are valid on the file system as well.
-        *
-        * @param string $username
-        * @throws RegistrationException on invalid
-        */
-       function validate_username($username)
-       {
-               global $CONFIG;
+       return false;
+}
 
-               // Basic, check length
-               if (!isset($CONFIG->minusername)) {
-                       $CONFIG->minusername = 4;
-               }
+/**
+ * Get an array of users from their
+ *
+ * @param string $email Email address.
+ * @return Array of users
+ */
+function get_user_by_email($email) {
+       global $CONFIG;
 
-               if (strlen($username) < $CONFIG->minusername)
-                       throw new RegistrationException(elgg_echo('registration:usernametooshort'));
+       $email = sanitise_string($email);
 
-               // Blacklist for bad characters (partially nicked from mediawiki)
+       $access = get_access_sql_suffix('e');
 
-               $blacklist = '/[' .
-                       '\x{0080}-\x{009f}' . # iso-8859-1 control chars
-                       '\x{00a0}' .          # non-breaking space
-                       '\x{2000}-\x{200f}' . # various whitespace
-                       '\x{2028}-\x{202f}' . # breaks and control chars
-                       '\x{3000}' .          # ideographic space
-                       '\x{e000}-\x{f8ff}' . # private use
-                       ']/u';
+       $query = "SELECT e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where email='$email' and $access";
 
-               if (
-                       preg_match($blacklist, $username)
-               )
-                       throw new RegistrationException(elgg_echo('registration:invalidchars'));
+       return get_data($query, 'entity_row_to_elggstar');
+}
 
-               // Belts and braces TODO: Tidy into main unicode
-               $blacklist2 = '/\\"\'*& ?#%^(){}[]~?<>;|¬`@-+=';
-               for ($n=0; $n < strlen($blacklist2); $n++)
-                       if (strpos($username, $blacklist2[$n])!==false)
-                               throw new RegistrationException(elgg_echo('registration:invalidchars'));
+/**
+ * Searches for a user based on a complete or partial name or username.
+ *
+ * @param string $criteria The partial or full name or username.
+ * @param int $limit Limit of the search.
+ * @param int $offset Offset.
+ * @param string $order_by The order.
+ * @param boolean $count Whether to return the count of results or just the results.
+ */
+function search_for_user($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) {
+       global $CONFIG;
 
-               $result = true;
-               return trigger_plugin_hook('registeruser:validate:username', 'all', array('username' => $username), $result);
-       }
+       $criteria = sanitise_string($criteria);
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       $order_by = sanitise_string($order_by);
 
-       /**
-        * Simple validation of a password.
-        *
-        * @param string $password
-        * @throws RegistrationException on invalid
-        */
-       function validate_password($password)
-       {
-               if (strlen($password)<6) throw new RegistrationException(elgg_echo('registration:passwordtooshort'));
+       $access = get_access_sql_suffix("e");
 
-               $result = true;
-               return trigger_plugin_hook('registeruser:validate:password', 'all', array('password' => $password), $result);
+       if ($order_by == "") {
+               $order_by = "e.time_created desc";
        }
 
-       /**
-        * Simple validation of a email.
-        *
-        * @param string $address
-        * @throws RegistrationException on invalid
-        * @return bool
-        */
-       function validate_email_address($address)
-       {
-               if (!is_email_address($address)) throw new RegistrationException(elgg_echo('registration:notemail'));
+       if ($count) {
+               $query = "SELECT count(e.guid) as total ";
+       } else {
+               $query = "SELECT e.* ";
+       }
+       $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where ";
+       // $query .= " match(u.name,u.username) against ('$criteria') ";
+       $query .= "(u.name like \"%{$criteria}%\" or u.username like \"%{$criteria}%\")";
+       $query .= " and $access";
 
-               // Got here, so lets try a hook (defaulting to ok)
-               $result = true;
-               return trigger_plugin_hook('registeruser:validate:email', 'all', array('email' => $address), $result);
+       if (!$count) {
+               $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($count = get_data_row($query)) {
+                       return $count->total;
+               }
+       }
+       return false;
+}
+
+/**
+ * Displays a list of user objects that have been searched for.
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param string $tag Search criteria
+ * @param int $limit The number of entities to display on a page
+ * @return string The list in a form suitable to display
+ */
+function list_user_search($tag, $limit = 10) {
+       $offset = (int) get_input('offset');
+       $limit = (int) $limit;
+       $count = (int) search_for_user($tag, 10, 0, '', true);
+       $entities = search_for_user($tag, $limit, $offset);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false);
+}
+
+/**
+ * A function that returns a maximum of $limit users who have done something within the last
+ * $seconds seconds.
+ *
+ * @param int $seconds Number of seconds (default 600 = 10min)
+ * @param int $limit Limit, default 10.
+ * @param int $offset Offset, defualt 0.
+ */
+function find_active_users($seconds = 600, $limit = 10, $offset = 0) {
+       global $CONFIG;
+
+       $seconds = (int)$seconds;
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+
+       $time = time() - $seconds;
+
+       $access = get_access_sql_suffix("e");
+
+       $query = "SELECT distinct e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid = u.guid where u.last_action >= {$time} and $access order by u.last_action desc limit {$offset},{$limit}";
+
+       return get_data($query, "entity_row_to_elggstar");
+}
+
+/**
+ * Generate and send a password request email to a given user's registered email address.
+ *
+ * @param int $user_guid
+ */
+function send_new_password_request($user_guid) {
+       global $CONFIG;
+
+       $user_guid = (int)$user_guid;
+
+       $user = get_entity($user_guid);
+       if ($user) {
+               // generate code
+               $code = generate_random_cleartext_password();
+               //create_metadata($user_guid, 'conf_code', $code,'', 0, ACCESS_PRIVATE);
+               set_private_setting($user_guid, 'passwd_conf_code', $code);
+
+               // generate link
+               $link = $CONFIG->site->url . "action/user/passwordreset?u=$user_guid&c=$code";
+
+               // generate email
+               $email = sprintf(elgg_echo('email:resetreq:body'), $user->name, $_SERVER['REMOTE_ADDR'], $link);
+
+               return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetreq:subject'), $email, NULL, 'email');
        }
 
-       /**
-        * Registers a user, returning false if the username already exists
-        *
-        * @param string $username The username of the new user
-        * @param string $password The password
-        * @param string $name The user's display name
-        * @param string $email Their email address
-        * @param bool $allow_multiple_emails Allow the same email address to be registered multiple times?
-        * @param int $friend_guid Optionally, GUID of a user this user will friend once fully registered
-        * @return int|false The new user's GUID; false on failure
-        */
-       function register_user($username, $password, $name, $email, $allow_multiple_emails = false, $friend_guid = 0, $invitecode = '') {
-
-               // Load the configuration
-                       global $CONFIG;
-
-                       $username = trim($username);
-                       // no need to trim password.
-                       $password = $password;
-                       $name = trim($name);
-                       $email = trim($email);
-
-               // A little sanity checking
-                       if (empty($username)
-                               || empty($password)
-                               || empty($name)
-                               || empty($email)) {
-                                       return false;
-                               }
+       return false;
+}
+
+/**
+ * Low level function to reset a given user's password.
+ *
+ * This can only be called from execute_new_password_request().
+ *
+ * @param int $user_guid The user.
+ * @param string $password password text (which will then be converted into a hash and stored)
+ */
+function force_user_password_reset($user_guid, $password) {
+       global $CONFIG;
+
+       if (call_gatekeeper('execute_new_password_request', __FILE__)) {
+               $user = get_entity($user_guid);
 
-                       // See if it exists and is disabled
-                       $access_status = access_get_show_hidden_status();
-                       access_show_hidden_entities(true);
+               if ($user) {
+                       $salt = generate_random_cleartext_password(); // Reset the salt
+                       $user->salt = $salt;
 
-                       // Validate email address
-                       if (!validate_email_address($email)) throw new RegistrationException(elgg_echo('registration:emailnotvalid'));
+                       $hash = generate_user_password($user, $password);
 
-                       // Validate password
-                       if (!validate_password($password)) throw new RegistrationException(elgg_echo('registration:passwordnotvalid'));
+                       return update_data("UPDATE {$CONFIG->dbprefix}users_entity set password='$hash', salt='$salt' where guid=$user_guid");
+               }
+       }
 
-                       // Validate the username
-                       if (!validate_username($username)) throw new RegistrationException(elgg_echo('registration:usernamenotvalid'));
+       return false;
+}
 
-               // Check to see if $username exists already
-                       if ($user = get_user_by_username($username)) {
-                               //return false;
-                               throw new RegistrationException(elgg_echo('registration:userexists'));
-                       }
+/**
+ * Validate and execute a password reset for a user.
+ *
+ * @param int $user_guid The user id
+ * @param string $conf_code Confirmation code as sent in the request email.
+ */
+function execute_new_password_request($user_guid, $conf_code) {
+       global $CONFIG;
 
-               // If we're not allowed multiple emails then see if this address has been used before
-                       if ((!$allow_multiple_emails) && (get_user_by_email($email)))
-                       {
-                               throw new RegistrationException(elgg_echo('registration:dupeemail'));
-                       }
+       $user_guid = (int)$user_guid;
 
-                       access_show_hidden_entities($access_status);
-
-               // Check to see if we've registered the first admin yet.
-               // If not, this is the first admin user!
-                       $admin = datalist_get('admin_registered');
-
-               // Otherwise ...
-                       $user = new ElggUser();
-                       $user->username = $username;
-                       $user->email = $email;
-                       $user->name = $name;
-                       $user->access_id = ACCESS_PUBLIC;
-                       $user->salt = generate_random_cleartext_password(); // Note salt generated before password!
-                       $user->password = generate_user_password($user, $password);
-                       $user->owner_guid = 0; // Users aren't owned by anyone, even if they are admin created.
-                       $user->container_guid = 0; // Users aren't contained by anyone, even if they are admin created.
-                       $user->save();
-
-               // If $friend_guid has been set, make mutual friends
-                       if ($friend_guid) {
-                               if ($friend_user = get_user($friend_guid)) {
-                                       if ($invitecode == generate_invite_code($friend_user->username)) {
-                                               $user->addFriend($friend_guid);
-                                               $friend_user->addFriend($user->guid);
-                                       }
-                               }
-                       }
+       $user = get_entity($user_guid);
+       if (($user) && (get_private_setting($user_guid, 'passwd_conf_code') == $conf_code)) {
+               $password = generate_random_cleartext_password();
 
-                       global $registering_admin;
-                       if (!$admin) {
-                               $user->admin = true;
-                               datalist_set('admin_registered',1);
-                               $registering_admin = true;
-                       } else {
-                               $registering_admin = false;
-                       }
+               if (force_user_password_reset($user_guid, $password)) {
+                       //remove_metadata($user_guid, 'conf_code');
+                       remove_private_setting($user_guid, 'passwd_conf_code');
 
-                       // Turn on email notifications by default
-                       set_user_notification_setting($user->getGUID(), 'email', true);
+                       $email = sprintf(elgg_echo('email:resetpassword:body'), $user->name, $password);
 
-                       return $user->getGUID();
+                       return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetpassword:subject'), $email, NULL, 'email');
+               }
        }
 
-       /**
-        * Generates a unique invite code for a user
-        *
-        * @param string $username The username of the user sending the invitation
-        * @return string Invite code
-        */
-       function generate_invite_code($username) {
+       return false;
+}
+
+/**
+ * Set the validation status for a user.
+ *
+ * @param bool $status Validated (true) or false
+ * @param string $method Optional method to say how a user was validated
+ * @return bool
+ */
+function set_user_validation_status($user_guid, $status, $method = '') {
+       if (!$status) {
+               $method = '';
+       }
 
-               $secret = datalist_get('__site_secret__');
-               return md5($username . $secret);
+       if ($status) {
+               if (
+                       (create_metadata($user_guid, 'validated', $status,'', 0, ACCESS_PUBLIC)) &&
+                       (create_metadata($user_guid, 'validated_method', $method,'', 0, ACCESS_PUBLIC))
+               ) {
+                       return true;
+               }
+       } else {
+               $validated = get_metadata_byname($user_guid,  'validated');
+               $validated_method = get_metadata_byname($user_guid,  'validated_method');
 
+               if (
+                       ($validated) &&
+                       ($validated_method) &&
+                       (delete_metadata($validated->id)) &&
+                       (delete_metadata($validated_method->id))
+               )
+                       return true;
        }
 
-       /**
-        * Adds collection submenu items
-        *
-        */
-       function collections_submenu_items() {
-               global $CONFIG;
-               $user = get_loggedin_user();
-               add_submenu_item(elgg_echo('friends:collections'), $CONFIG->wwwroot . "pg/collections/" . $user->username);
-               add_submenu_item(elgg_echo('friends:collections:add'),$CONFIG->wwwroot."pg/collections/add");
+       return false;
+}
+
+/**
+ * Trigger an event requesting that a user guid be validated somehow - either by email address or some other way.
+ *
+ * This event invalidates any existing values and returns
+ *
+ * @param unknown_type $user_guid
+ */
+function request_user_validation($user_guid) {
+       $user = get_entity($user_guid);
+
+       if (($user) && ($user instanceof ElggUser)) {
+               // invalidate any existing validations
+               set_user_validation_status($user_guid, false);
+
+               // request validation
+               trigger_elgg_event('validate', 'user', $user);
+       }
+}
+
+/**
+ * Validates an email address.
+ *
+ * @param string $address Email address.
+ * @return bool
+ */
+function is_email_address($address) {
+       // TODO: Make this better!
+
+       if (strpos($address, '@')=== false) {
+               return false;
        }
 
-       /**
-        * Page handler for friends
-        *
-        */
-       function friends_page_handler($page_elements) {
-
-               if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) {
-                       set_page_owner($user->getGUID());
-               }
-               if ($_SESSION['guid'] == page_owner()) {
-                       collections_submenu_items();
-               }
-               require_once(dirname(dirname(dirname(__FILE__))) . "/friends/index.php");
-
+       if (strpos($address, '.')=== false) {
+               return false;
        }
 
-       /**
-        * Page handler for friends of
-        *
-        */
-       function friends_of_page_handler($page_elements) {
+       return true;
+}
+
+/**
+ * Simple function that will generate a random clear text password suitable for feeding into generate_user_password().
+ *
+ * @see generate_user_password
+ * @return string
+ */
+function generate_random_cleartext_password() {
+       return substr(md5(microtime() . rand()), 0, 8);
+}
+
+/**
+ * Generate a password for a user, currently uses MD5.
+ *
+ * Later may introduce salting etc.
+ *
+ * @param ElggUser $user The user this is being generated for.
+ * @param string $password Password in clear text
+ */
+function generate_user_password(ElggUser $user, $password) {
+       return md5($password . $user->salt);
+}
+
+/**
+ * Simple function which ensures that a username contains only valid characters.
+ *
+ * This should only permit chars that are valid on the file system as well.
+ *
+ * @param string $username
+ * @throws RegistrationException on invalid
+ */
+function validate_username($username) {
+       global $CONFIG;
+
+       // Basic, check length
+       if (!isset($CONFIG->minusername)) {
+               $CONFIG->minusername = 4;
+       }
 
-               if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) {
-                       set_page_owner($user->getGUID());
-               }
-               if ($_SESSION['guid'] == page_owner()) {
-                       collections_submenu_items();
-               }
-               require_once(dirname(dirname(dirname(__FILE__))) . "/friends/of.php");
+       if (strlen($username) < $CONFIG->minusername) {
+               throw new RegistrationException(elgg_echo('registration:usernametooshort'));
+       }
 
+       // Blacklist for bad characters (partially nicked from mediawiki)
+
+       $blacklist = '/[' .
+               '\x{0080}-\x{009f}' . # iso-8859-1 control chars
+               '\x{00a0}' .          # non-breaking space
+               '\x{2000}-\x{200f}' . # various whitespace
+               '\x{2028}-\x{202f}' . # breaks and control chars
+               '\x{3000}' .          # ideographic space
+               '\x{e000}-\x{f8ff}' . # private use
+               ']/u';
+
+       if (
+               preg_match($blacklist, $username)
+       ) {
+               throw new RegistrationException(elgg_echo('registration:invalidchars'));
        }
 
-       /**
-        * Page handler for friends of
-        *
-        */
-       function collections_page_handler($page_elements) {
-
-               if (isset($page_elements[0])) {
-                       if ($page_elements[0] == "add") {
-                               set_page_owner($_SESSION['guid']);
-                               collections_submenu_items();
-                               require_once(dirname(dirname(dirname(__FILE__))) . "/friends/add.php");
-                       } else {
-                               if ($user = get_user_by_username($page_elements[0])) {
-                                       set_page_owner($user->getGUID());
-                                       if ($_SESSION['guid'] == page_owner()) {
-                                               collections_submenu_items();
-                                       }
-                                       require_once(dirname(dirname(dirname(__FILE__))) . "/friends/collections.php");
-                               }
-                       }
+       // Belts and braces TODO: Tidy into main unicode
+       $blacklist2 = '/\\"\'*& ?#%^(){}[]~?<>;|¬`@-+=';
+       for ($n=0; $n < strlen($blacklist2); $n++) {
+               if (strpos($username, $blacklist2[$n])!==false) {
+                       throw new RegistrationException(elgg_echo('registration:invalidchars'));
                }
-
        }
 
-       /**
-        * Page handler for dashboard
-        */
-       function dashboard_page_handler($page_elements) {
-               require_once(dirname(dirname(dirname(__FILE__))) . "/dashboard/index.php");
+       $result = true;
+       return trigger_plugin_hook('registeruser:validate:username', 'all', array('username' => $username), $result);
+}
+
+/**
+ * Simple validation of a password.
+ *
+ * @param string $password
+ * @throws RegistrationException on invalid
+ */
+function validate_password($password) {
+       if (strlen($password) < 6) {
+               throw new RegistrationException(elgg_echo('registration:passwordtooshort'));
        }
 
-       /**
-        * Sets the last action time of the given user to right now.
-        *
-        * @param int $user_guid The user GUID
-        */
-       function set_last_action($user_guid) {
-
-               $user_guid = (int) $user_guid;
-               global $CONFIG;
-               $time = time();
-
-               execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_action = last_action, last_action = {$time} where guid = {$user_guid}");
-
+       $result = true;
+       return trigger_plugin_hook('registeruser:validate:password', 'all', array('password' => $password), $result);
+}
+
+/**
+ * Simple validation of a email.
+ *
+ * @param string $address
+ * @throws RegistrationException on invalid
+ * @return bool
+ */
+function validate_email_address($address) {
+       if (!is_email_address($address)) {
+               throw new RegistrationException(elgg_echo('registration:notemail'));
        }
 
-       /**
-        * Sets the last logon time of the given user to right now.
-        *
-        * @param int $user_guid The user GUID
-        */
-       function set_last_login($user_guid) {
-
-               $user_guid = (int) $user_guid;
-               global $CONFIG;
-               $time = time();
+       // Got here, so lets try a hook (defaulting to ok)
+       $result = true;
+       return trigger_plugin_hook('registeruser:validate:email', 'all', array('email' => $address), $result);
+}
+
+/**
+ * Registers a user, returning false if the username already exists
+ *
+ * @param string $username The username of the new user
+ * @param string $password The password
+ * @param string $name The user's display name
+ * @param string $email Their email address
+ * @param bool $allow_multiple_emails Allow the same email address to be registered multiple times?
+ * @param int $friend_guid Optionally, GUID of a user this user will friend once fully registered
+ * @return int|false The new user's GUID; false on failure
+ */
+function register_user($username, $password, $name, $email, $allow_multiple_emails = false, $friend_guid = 0, $invitecode = '') {
+       // Load the configuration
+       global $CONFIG;
+
+       $username = trim($username);
+       // no need to trim password.
+       $password = $password;
+       $name = trim($name);
+       $email = trim($email);
+
+       // A little sanity checking
+       if (empty($username)
+       || empty($password)
+       || empty($name)
+       || empty($email)) {
+               return false;
+       }
 
-               execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_login = last_login, last_login = {$time} where guid = {$user_guid}");
+       // See if it exists and is disabled
+       $access_status = access_get_show_hidden_status();
+       access_show_hidden_entities(true);
 
+       // Validate email address
+       if (!validate_email_address($email)) {
+               throw new RegistrationException(elgg_echo('registration:emailnotvalid'));
        }
 
-       /**
-        * A permissions plugin hook that grants access to users if they are newly created - allows
-        * for email activation.
-        *
-        * TODO: Do this in a better way!
-        *
-        * @param unknown_type $hook
-        * @param unknown_type $entity_type
-        * @param unknown_type $returnvalue
-        * @param unknown_type $params
-        */
-       function new_user_enable_permissions_check($hook, $entity_type, $returnvalue, $params)
-       {
-               $entity = $params['entity'];
-               $user = $params['user'];
-               if (($entity) && ($entity instanceof ElggUser))
-               {
-                       if (
-                               (($entity->disable_reason == 'new_user') || (
-                                       // if this isn't set at all they're a "new user"
-                                       !$entity->validated
-                               ))
-                               && (!isloggedin()))
-                               return true;
-
-               }
+       // Validate password
+       if (!validate_password($password)) {
+               throw new RegistrationException(elgg_echo('registration:passwordnotvalid'));
+       }
 
-               return $returnvalue;
+       // Validate the username
+       if (!validate_username($username)) {
+               throw new RegistrationException(elgg_echo('registration:usernamenotvalid'));
        }
 
-       /**
-        * Sets up user-related menu items
-        *
-        */
-       function users_pagesetup() {
+       // Check to see if $username exists already
+       if ($user = get_user_by_username($username)) {
+               //return false;
+               throw new RegistrationException(elgg_echo('registration:userexists'));
+       }
 
-               // Load config
-                       global $CONFIG;
+       // If we're not allowed multiple emails then see if this address has been used before
+       if ((!$allow_multiple_emails) && (get_user_by_email($email))) {
+               throw new RegistrationException(elgg_echo('registration:dupeemail'));
+       }
 
-               //add submenu options
-                       if (get_context() == "friends" ||
-                               get_context() == "friendsof" ||
-                               get_context() == "collections") {
-                               add_submenu_item(elgg_echo('friends'),$CONFIG->wwwroot."pg/friends/" . page_owner_entity()->username);
-                               add_submenu_item(elgg_echo('friends:of'),$CONFIG->wwwroot."pg/friendsof/" . page_owner_entity()->username);
+       access_show_hidden_entities($access_status);
+
+       // Check to see if we've registered the first admin yet.
+       // If not, this is the first admin user!
+       $admin = datalist_get('admin_registered');
+
+       // Otherwise ...
+       $user = new ElggUser();
+       $user->username = $username;
+       $user->email = $email;
+       $user->name = $name;
+       $user->access_id = ACCESS_PUBLIC;
+       $user->salt = generate_random_cleartext_password(); // Note salt generated before password!
+       $user->password = generate_user_password($user, $password);
+       $user->owner_guid = 0; // Users aren't owned by anyone, even if they are admin created.
+       $user->container_guid = 0; // Users aren't contained by anyone, even if they are admin created.
+       $user->save();
+
+       // If $friend_guid has been set, make mutual friends
+       if ($friend_guid) {
+               if ($friend_user = get_user($friend_guid)) {
+                       if ($invitecode == generate_invite_code($friend_user->username)) {
+                               $user->addFriend($friend_guid);
+                               $friend_user->addFriend($user->guid);
                        }
+               }
+       }
 
+       global $registering_admin;
+       if (!$admin) {
+               $user->admin = true;
+               datalist_set('admin_registered',1);
+               $registering_admin = true;
+       } else {
+               $registering_admin = false;
        }
 
-       /**
-        * Users initialisation function, which establishes the page handler
-        *
-        */
-       function users_init() {
+       // Turn on email notifications by default
+       set_user_notification_setting($user->getGUID(), 'email', true);
+
+       return $user->getGUID();
+}
+
+/**
+ * Generates a unique invite code for a user
+ *
+ * @param string $username The username of the user sending the invitation
+ * @return string Invite code
+ */
+function generate_invite_code($username) {
+       $secret = datalist_get('__site_secret__');
+       return md5($username . $secret);
+}
+
+/**
+ * Adds collection submenu items
+ *
+ */
+function collections_submenu_items() {
+       global $CONFIG;
+       $user = get_loggedin_user();
+       add_submenu_item(elgg_echo('friends:collections'), $CONFIG->wwwroot . "pg/collections/" . $user->username);
+       add_submenu_item(elgg_echo('friends:collections:add'),$CONFIG->wwwroot."pg/collections/add");
+}
+
+/**
+ * Page handler for friends
+ *
+ */
+function friends_page_handler($page_elements) {
+       if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) {
+               set_page_owner($user->getGUID());
+       }
+       if ($_SESSION['guid'] == page_owner()) {
+               collections_submenu_items();
+       }
 
-               // Load config
-                       global $CONFIG;
+       require_once(dirname(dirname(dirname(__FILE__))) . "/friends/index.php");
+}
 
-               // Set up menu for logged in users
-                       if (isloggedin()) {
-                               $user = get_loggedin_user();
-                               add_menu(elgg_echo('friends'), $CONFIG->wwwroot . "pg/friends/" . $user->username);
+/**
+ * Page handler for friends of
+ *
+ */
+function friends_of_page_handler($page_elements) {
+       if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) {
+               set_page_owner($user->getGUID());
+       }
+       if ($_SESSION['guid'] == page_owner()) {
+               collections_submenu_items();
+       }
+       require_once(dirname(dirname(dirname(__FILE__))) . "/friends/of.php");
+}
+
+/**
+ * Page handler for friends of
+ *
+ */
+function collections_page_handler($page_elements) {
+       if (isset($page_elements[0])) {
+               if ($page_elements[0] == "add") {
+                       set_page_owner($_SESSION['guid']);
+                       collections_submenu_items();
+                       require_once(dirname(dirname(dirname(__FILE__))) . "/friends/add.php");
+               } else {
+                       if ($user = get_user_by_username($page_elements[0])) {
+                               set_page_owner($user->getGUID());
+                               if ($_SESSION['guid'] == page_owner()) {
+                                       collections_submenu_items();
+                               }
+                               require_once(dirname(dirname(dirname(__FILE__))) . "/friends/collections.php");
                        }
+               }
+       }
+}
+
+/**
+ * Page handler for dashboard
+ */
+function dashboard_page_handler($page_elements) {
+       require_once(dirname(dirname(dirname(__FILE__))) . "/dashboard/index.php");
+}
+
+/**
+ * Sets the last action time of the given user to right now.
+ *
+ * @param int $user_guid The user GUID
+ */
+function set_last_action($user_guid) {
+       $user_guid = (int) $user_guid;
+       global $CONFIG;
+       $time = time();
+
+       execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_action = last_action, last_action = {$time} where guid = {$user_guid}");
+}
+
+/**
+ * Sets the last logon time of the given user to right now.
+ *
+ * @param int $user_guid The user GUID
+ */
+function set_last_login($user_guid) {
+       $user_guid = (int) $user_guid;
+       global $CONFIG;
+       $time = time();
+
+       execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_login = last_login, last_login = {$time} where guid = {$user_guid}");
+}
+
+/**
+ * A permissions plugin hook that grants access to users if they are newly created - allows
+ * for email activation.
+ *
+ * TODO: Do this in a better way!
+ *
+ * @param unknown_type $hook
+ * @param unknown_type $entity_type
+ * @param unknown_type $returnvalue
+ * @param unknown_type $params
+ */
+function new_user_enable_permissions_check($hook, $entity_type, $returnvalue, $params) {
+       $entity = $params['entity'];
+       $user = $params['user'];
+       if (($entity) && ($entity instanceof ElggUser)) {
+               if (
+                       (($entity->disable_reason == 'new_user') || (
+                               // if this isn't set at all they're a "new user"
+                               !$entity->validated
+                       ))
+                       && (!isloggedin())) {
+                               return true;
+               }
+       }
 
-               register_page_handler('friends','friends_page_handler');
-               register_page_handler('friendsof','friends_of_page_handler');
-               register_page_handler('collections','collections_page_handler');
-               register_page_handler('dashboard','dashboard_page_handler');
-               register_action("register",true);
-               register_action("useradd",true);
-               register_action("friends/add");
-               register_action("friends/remove");
-               register_action('friends/addcollection');
-               register_action('friends/deletecollection');
-               register_action('friends/editcollection');
-               register_action("user/spotlight");
+       return $returnvalue;
+}
+
+/**
+ * Sets up user-related menu items
+ *
+ */
+function users_pagesetup() {
+       // Load config
+       global $CONFIG;
+
+       //add submenu options
+       if (get_context() == "friends" || get_context() == "friendsof" || get_context() == "collections") {
+               add_submenu_item(elgg_echo('friends'),$CONFIG->wwwroot."pg/friends/" . page_owner_entity()->username);
+               add_submenu_item(elgg_echo('friends:of'),$CONFIG->wwwroot."pg/friendsof/" . page_owner_entity()->username);
+       }
+}
+
+/**
+ * Users initialisation function, which establishes the page handler
+ *
+ */
+function users_init() {
+       // Load config
+       global $CONFIG;
+
+       // Set up menu for logged in users
+       if (isloggedin()) {
+               $user = get_loggedin_user();
+               add_menu(elgg_echo('friends'), $CONFIG->wwwroot . "pg/friends/" . $user->username);
+       }
 
-               register_action("usersettings/save");
+       register_page_handler('friends','friends_page_handler');
+       register_page_handler('friendsof','friends_of_page_handler');
+       register_page_handler('collections','collections_page_handler');
+       register_page_handler('dashboard','dashboard_page_handler');
+       register_action("register",true);
+       register_action("useradd",true);
+       register_action("friends/add");
+       register_action("friends/remove");
+       register_action('friends/addcollection');
+       register_action('friends/deletecollection');
+       register_action('friends/editcollection');
+       register_action("user/spotlight");
 
-               register_action("user/passwordreset");
-               register_action("user/requestnewpassword");
+       register_action("usersettings/save");
 
-               // User name change
-               extend_elgg_settings_page('user/settings/name', 'usersettings/user', 1);
-               //register_action("user/name");
+       register_action("user/passwordreset");
+       register_action("user/requestnewpassword");
 
-               // User password change
-               extend_elgg_settings_page('user/settings/password', 'usersettings/user', 1);
-               //register_action("user/password");
+       // User name change
+       extend_elgg_settings_page('user/settings/name', 'usersettings/user', 1);
+       //register_action("user/name");
 
-               // Add email settings
-               extend_elgg_settings_page('user/settings/email', 'usersettings/user', 1);
-               //register_action("email/save");
+       // User password change
+       extend_elgg_settings_page('user/settings/password', 'usersettings/user', 1);
+       //register_action("user/password");
 
-               // Add language settings
-               extend_elgg_settings_page('user/settings/language', 'usersettings/user', 1);
+       // Add email settings
+       extend_elgg_settings_page('user/settings/email', 'usersettings/user', 1);
+       //register_action("email/save");
 
-               // Add default access settings
-               extend_elgg_settings_page('user/settings/default_access', 'usersettings/user', 1);
+       // Add language settings
+       extend_elgg_settings_page('user/settings/language', 'usersettings/user', 1);
 
-               //register_action("user/language");
+       // Add default access settings
+       extend_elgg_settings_page('user/settings/default_access', 'usersettings/user', 1);
 
-               // Register the user type
-               register_entity_type('user','');
+       //register_action("user/language");
 
-               register_plugin_hook('usersettings:save','user','users_settings_save');
-               register_plugin_hook('search','all','search_list_users_by_name');
+       // Register the user type
+       register_entity_type('user','');
 
+       register_plugin_hook('usersettings:save','user','users_settings_save');
+       register_plugin_hook('search','all','search_list_users_by_name');
 
-               // Handle a special case for newly created users when the user is not logged in
-               // TODO: handle this better!
-               register_plugin_hook('permissions_check','all','new_user_enable_permissions_check');
-       }
 
-       /**
-        * Returns a formatted list of users suitable for injecting into search.
-        *
-        */
-       function search_list_users_by_name($hook, $user, $returnvalue, $tag) {
+       // Handle a special case for newly created users when the user is not logged in
+       // TODO: handle this better!
+       register_plugin_hook('permissions_check','all','new_user_enable_permissions_check');
+}
 
-               // Change this to set the number of users that display on the search page
-               $threshold = 4;
+/**
+ * Returns a formatted list of users suitable for injecting into search.
+ *
+ */
+function search_list_users_by_name($hook, $user, $returnvalue, $tag) {
+       // Change this to set the number of users that display on the search page
+       $threshold = 4;
 
-               $object = get_input('object');
+       $object = get_input('object');
 
-               if (!get_input('offset') && (empty($object) || $object == 'user'))
+       if (!get_input('offset') && (empty($object) || $object == 'user')) {
                if ($users = search_for_user($tag,$threshold)) {
-
                        $countusers = search_for_user($tag,0,0,"",true);
 
                        $return = elgg_view('user/search/startblurb',array('count' => $countusers, 'tag' => $tag));
                        return $return;
 
                }
-
-       }
-
-       function users_settings_save() {
-
-               global $CONFIG;
-               include($CONFIG->path . "actions/user/name.php");
-               include($CONFIG->path . "actions/user/password.php");
-               include($CONFIG->path . "actions/email/save.php");
-               include($CONFIG->path . "actions/user/language.php");
-               include($CONFIG->path . "actions/user/default_access.php");
-
        }
-
-       //register actions *************************************************************
-
-               register_elgg_event_handler('init','system','users_init',0);
-               register_elgg_event_handler('pagesetup','system','users_pagesetup',0);
-
-?>
\ No newline at end of file
+}
+
+function users_settings_save() {
+       global $CONFIG;
+       include($CONFIG->path . "actions/user/name.php");
+       include($CONFIG->path . "actions/user/password.php");
+       include($CONFIG->path . "actions/email/save.php");
+       include($CONFIG->path . "actions/user/language.php");
+       include($CONFIG->path . "actions/user/default_access.php");
+}
+
+//register actions *************************************************************
+register_elgg_event_handler('init','system','users_init',0);
+register_elgg_event_handler('pagesetup','system','users_pagesetup',0);
index 5a562540f02dd6c207e7125a0521869a202afca4..24a956a62ac5ee0b014adba8a3d0d9027c234520 100644 (file)
@@ -1,84 +1,77 @@
 <?php
-       /**
       * Elgg user settings functions.
       * Functions for adding and manipulating options on the user settings panel.
-        * 
       * @package Elgg
       * @subpackage Core
-        * @author Curverider Ltd 
       * @link http://elgg.org/
       */
+/**
+ * Elgg user settings functions.
+ * Functions for adding and manipulating options on the user settings panel.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Register a user settings page with the admin panel.
-        * This function extends the view "usersettings/main" with the provided view. This view should provide a description
-        * and either a control or a link to.
-        * 
-        * Usage:
-        *      - To add a control to the main admin panel then extend usersettings/main
-        *  - To add a control to a new page create a page which renders a view usersettings/subpage (where subpage is your new page - 
-        *    nb. some pages already exist that you can extend), extend the main view to point to it, and add controls to your 
-        *        new view.
-        * 
-        * At the moment this is essentially a wrapper around extend_view.
-        * 
-        * @param string $new_settings_view The view associated with the control you're adding  
-        * @param string $view The view to extend, by default this is 'usersettings/main'.
-        * @param int $priority Optional priority to govern the appearance in the list.
-        */
-       function extend_elgg_settings_page( $new_settings_view, $view = 'usersettings/main', $priority = 500)
-       {
-               return extend_view($view, $new_settings_view, $priority);
-       }
+/**
+ * Register a user settings page with the admin panel.
+ * This function extends the view "usersettings/main" with the provided view. This view should provide a description
+ * and either a control or a link to.
+ *
+ * Usage:
+ *     - To add a control to the main admin panel then extend usersettings/main
+ *  - To add a control to a new page create a page which renders a view usersettings/subpage (where subpage is your new page -
+ *    nb. some pages already exist that you can extend), extend the main view to point to it, and add controls to your
+ *       new view.
+ *
+ * At the moment this is essentially a wrapper around extend_view.
+ *
+ * @param string $new_settings_view The view associated with the control you're adding
+ * @param string $view The view to extend, by default this is 'usersettings/main'.
+ * @param int $priority Optional priority to govern the appearance in the list.
+ */
+function extend_elgg_settings_page( $new_settings_view, $view = 'usersettings/main', $priority = 500) {
+       return extend_view($view, $new_settings_view, $priority);
+}
+
+function usersettings_pagesetup() {
+       // Get config
+       global $CONFIG;
 
-       function usersettings_pagesetup() {
-               
-               // Get config
-                       global $CONFIG;
-               
-               // Menu options
-                       if (get_context() == "settings") {
-                               $user = get_loggedin_user();
-                               add_submenu_item(elgg_echo('usersettings:user:opt:linktext'),$CONFIG->wwwroot . "pg/settings/user/{$user->username}/");
-                               //add_submenu_item(elgg_echo('profile:editicon'), $CONFIG->wwwroot . 'mod/profile/editicon.php');
-                               add_submenu_item(elgg_echo('usersettings:plugins:opt:linktext'),$CONFIG->wwwroot . "pg/settings/plugins/{$user->username}/");
-                               add_submenu_item(elgg_echo('usersettings:statistics:opt:linktext'),$CONFIG->wwwroot . "pg/settings/statistics/{$user->username}/");
-                       }
+       // Menu options
+       if (get_context() == "settings") {
+               $user = get_loggedin_user();
+               add_submenu_item(elgg_echo('usersettings:user:opt:linktext'),$CONFIG->wwwroot . "pg/settings/user/{$user->username}/");
+               //add_submenu_item(elgg_echo('profile:editicon'), $CONFIG->wwwroot . 'mod/profile/editicon.php');
+               add_submenu_item(elgg_echo('usersettings:plugins:opt:linktext'),$CONFIG->wwwroot . "pg/settings/plugins/{$user->username}/");
+               add_submenu_item(elgg_echo('usersettings:statistics:opt:linktext'),$CONFIG->wwwroot . "pg/settings/statistics/{$user->username}/");
        }
-       
-       function usersettings_page_handler($page)
-       {
-               global $CONFIG;
-               
-               $path = $CONFIG->path . "settings/index.php";
-               
-               if ($page[0])
-               {
-                       switch ($page[0])
-                       {
-                               case 'user' : $path = $CONFIG->path . "settings/user.php"; break;
-                               case 'statistics' : $path = $CONFIG->path . "settings/statistics.php"; break;
-                               case 'plugins' : $path = $CONFIG->path . "settings/plugins.php"; break;
-                       }
+}
+
+function usersettings_page_handler($page) {
+       global $CONFIG;
+
+       $path = $CONFIG->path . "settings/index.php";
+
+       if ($page[0]) {
+               switch ($page[0]) {
+                       case 'user' : $path = $CONFIG->path . "settings/user.php"; break;
+                       case 'statistics' : $path = $CONFIG->path . "settings/statistics.php"; break;
+                       case 'plugins' : $path = $CONFIG->path . "settings/plugins.php"; break;
                }
-               
-               if ($page[1])
-                       set_input('username', $page[1]);
-                       
-               include($path);
        }
-       
-       /**
-        * Initialise the admin page.
-        */
-       function usersettings_init()
-       {
-               // Page handler
-               register_page_handler('settings','usersettings_page_handler');
+
+       if ($page[1]) {
+               set_input('username', $page[1]);
        }
-       
-       /// Register init function
-       register_elgg_event_handler('init','system','usersettings_init');
-       register_elgg_event_handler('pagesetup','system','usersettings_pagesetup');
-       
-?>
\ No newline at end of file
+
+       include($path);
+}
+
+/**
+ * Initialise the admin page.
+ */
+function usersettings_init() {
+       // Page handler
+       register_page_handler('settings','usersettings_page_handler');
+}
+
+/// Register init function
+register_elgg_event_handler('init','system','usersettings_init');
+register_elgg_event_handler('pagesetup','system','usersettings_pagesetup');
\ No newline at end of file
index 8251efe678bebc17fdd404e1e470ab1c1e591deb..3728fb8ec9cb5306200b8a56fdff43b6956f89fc 100644 (file)
 <?php
+/**
+ * Elgg version library.
+ * Contains code for handling versioning and upgrades.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @link http://elgg.org/
+ */
 
-       /**
-        * Elgg version library.
-        * Contains code for handling versioning and upgrades.
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-
-        * @link http://elgg.org/
-        */
-
-       /**
-        * Run any php upgrade scripts which are required
-        *
-        * @param unknown_type $version
-        */
-       function upgrade_code($version) 
-       {
-               global $CONFIG;
-               
-               // Elgg and its database must be installed to upgrade it!
-        if (!is_db_installed() || !is_installed()) return false;
-               
-               $version = (int) $version;
-               
-        if ($handle = opendir($CONFIG->path . 'engine/lib/upgrades/')) {
-                       
-               $upgrades = array();
-               
-               while ($updatefile = readdir($handle)) {
-                       
-                       // Look for upgrades and add to upgrades list
-                       if (!is_dir($CONFIG->path . 'engine/lib/upgrades/' . $updatefile)) {
-                               if (preg_match('/([0-9]*)\.php/',$updatefile,$matches)) {
-                                       $core_version = (int) $matches[1];
-                                       if ($core_version > $version) {
-                                               $upgrades[] = $updatefile;
-                                       }
-                               }
-                       }
-                       
-               }
-               
-               // Sort and execute
-               asort($upgrades);
-               if (sizeof($upgrades) > 0) {
-                       foreach($upgrades as $upgrade) {
-                               try {
-                                       include($CONFIG->path . 'engine/lib/upgrades/' . $upgrade);
-                               } catch (Exception $e) {
-                                       error_log($e->getmessage());
-                               }       
-                               
-                       }
-               }
-
-               return true;
-        }
-               
-        return false;
+/**
+ * Run any php upgrade scripts which are required
+ *
+ * @param unknown_type $version
+ */
+function upgrade_code($version) {
+       global $CONFIG;
+
+       // Elgg and its database must be installed to upgrade it!
+       if (!is_db_installed() || !is_installed()) {
+               return false;
        }
 
-       /**
-        * Get the current version information
-        *
-        * @param true|false $humanreadable Whether to return a human readable version (default: false)
-        * @return string|false Depending on success
-        */
-               function get_version($humanreadable = false) {
-                       
-                       global $CONFIG;
-                       if (include($CONFIG->path . "version.php")) {
-                               if (!$humanreadable) return $version;
-                               return $release;
+       $version = (int) $version;
+
+       if ($handle = opendir($CONFIG->path . 'engine/lib/upgrades/')) {
+               $upgrades = array();
+
+               while ($updatefile = readdir($handle)) {
+                       // Look for upgrades and add to upgrades list
+                       if (!is_dir($CONFIG->path . 'engine/lib/upgrades/' . $updatefile)) {
+                               if (preg_match('/([0-9]*)\.php/',$updatefile,$matches)) {
+                                       $core_version = (int) $matches[1];
+                                       if ($core_version > $version) {
+                                               $upgrades[] = $updatefile;
+                                       }
+                               }
                        }
-                       
-                       return false;
-                       
                }
-               
-       /**
-        * Determines whether or not the database needs to be upgraded.
-        *
-        * @return true|false Depending on whether or not the db version matches the code version
-        */
-               function version_upgrade_check() {
-                       
-                       $dbversion = (int) datalist_get('version');
-                       $version = get_version();
-                       
-                       if ($version > $dbversion) {
-                               return true;
+
+               // Sort and execute
+               asort($upgrades);
+               if (sizeof($upgrades) > 0) {
+                       foreach($upgrades as $upgrade) {
+                               try {
+                                       include($CONFIG->path . 'engine/lib/upgrades/' . $upgrade);
+                               } catch (Exception $e) {
+                                       error_log($e->getmessage());
+                               }
                        }
-                       return false;
-                       
-               }
-               
-       /**
-        * Upgrades Elgg
-        *
-        */
-               function version_upgrade() {
-                       
-                       $dbversion = (int) datalist_get('version');
-                       
-                       // Upgrade database
-                       db_upgrade($dbversion);
-                       system_message(elgg_echo('upgrade:db'));
-                       
-                       // Upgrade core
-                       if (upgrade_code($dbversion))
-                               system_message(elgg_echo('upgrade:core'));
-                               
-                       // Now we trigger an event to give the option for plugins to do something
-                       $upgrade_details = stdClass;
-                       $upgrade_details->from = $dbversion;
-                       $upgrade_details->to = get_version();
-                       
-                       trigger_elgg_event('upgrade', 'upgrade', $upgrade_details);
-                               
-                       // Update the version
-                       datalist_set('version', get_version());
-                       
                }
-               
-?>
\ No newline at end of file
+
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ * Get the current version information
+ *
+ * @param true|false $humanreadable Whether to return a human readable version (default: false)
+ * @return string|false Depending on success
+ */
+function get_version($humanreadable = false) {
+       global $CONFIG;
+
+       if (include($CONFIG->path . "version.php")) {
+               if (!$humanreadable) return $version;
+               return $release;
+       }
+
+       return false;
+}
+
+/**
+ * Determines whether or not the database needs to be upgraded.
+ *
+ * @return true|false Depending on whether or not the db version matches the code version
+ */
+function version_upgrade_check() {
+       $dbversion = (int) datalist_get('version');
+       $version = get_version();
+
+       if ($version > $dbversion) {
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ * Upgrades Elgg
+ *
+ */
+function version_upgrade() {
+       $dbversion = (int) datalist_get('version');
+
+       // Upgrade database
+       db_upgrade($dbversion);
+       system_message(elgg_echo('upgrade:db'));
+
+       // Upgrade core
+       if (upgrade_code($dbversion)) {
+               system_message(elgg_echo('upgrade:core'));
+       }
+
+       // Now we trigger an event to give the option for plugins to do something
+       $upgrade_details = stdClass;
+       $upgrade_details->from = $dbversion;
+       $upgrade_details->to = get_version();
+
+       trigger_elgg_event('upgrade', 'upgrade', $upgrade_details);
+
+       // Update the version
+       datalist_set('version', get_version());
+}
index f6f01f660e04503e6b8a47e07c1713d33d6bb79a..7adf5ffade8c1eba9b8aaaee5de740da9fa9be3d 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Elgg widgets library.
         * Contains code for handling widgets.
-        * 
+        *
         * @package Elgg
         * @subpackage Core
 
                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.
                 */
                        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;
                }
                {
                        if (array_key_exists($name, $this->attributes))
                        {
-                               // Check that we're not trying to change the guid! 
+                               // 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 
+                       else
                                return set_private_setting($this->guid, $name, $value);
-               
+
                        return true;
                }
        }
@@ -70,7 +70,7 @@
         * @param string $context The context we wish to enable context for
         */
                function use_widgets($context) {
-                       
+
                        global $CONFIG;
                        if (!isset($CONFIG->widgets))
                                $CONFIG->widgets = new stdClass;
                        if (!empty($context)) {
                                $CONFIG->widgets->contexts[] = $context;
                        }
-                       
+
                }
-               
+
        /**
         * Determines whether or not the current context is using widgets
         *
         * @return true|false Depending on widget status
         */
                function using_widgets() {
-                       
+
                        global $CONFIG;
                        $context = get_context();
                        if (isset($CONFIG->widgets->contexts) && is_array($CONFIG->widgets->contexts)) {
                                if (in_array($context, $CONFIG->widgets->contexts)) return true;
                        }
-                       
+
                        return false;
-                       
+
                }
-               
+
        /**
         * When given a widget entity and a new requested location, saves the new location
         * and also provides a sensible ordering for all widgets in that column
         * @return true|false Depending on success
         */
                function save_widget_location(ElggObject $widget, $order, $column) {
-                       
+
                        if ($widget instanceof ElggObject) {
                                if ($widget->subtype == "widget") {
-                                       
+
                                        // If you can't move the widget, don't save a new location
                                        if (!$widget->draggable)
                                                return false;
-                                       
+
                                        // Sanitise the column value
                                        if ($column != 1 || $column != 2 || $column != 3)
                                                $column = 1;
-                                               
+
                                        $widget->column = (int) $column;
-                                       
+
                                        $ordertmp = array();
-                                       
-                                       if ($entities = get_entities_from_metadata_multi(array(                                                                                                                                         
+
+                                       if ($entities = get_entities_from_metadata_multi(array(
                                                        'context' => $widget->context,
                                                        'column' => $column,
                                                        ),'object','widget')) {
                                                foreach($entities as $entity) {
                                                        $entityorder = $entity->order;
                                                        if ($entityorder < $order) {
-                                                               $ordertmp[$entityorder] = $entity;                                                               
+                                                               $ordertmp[$entityorder] = $entity;
                                                        }
                                                        if ($entityorder >= $order) {
                                                                $ordertmp[$entityorder + 10000] = $entity;
                                                        }
-                                               }       
+                                               }
                                        }
-                                       
+
                                        $ordertmp[$order] = $widget;
                                        ksort($ordertmp);
-                                       
+
                                        $orderticker = 10;
                                        foreach($ordertmp as $orderval => $entity) {
                                                $entity->order = $orderticker;
                                                $orderticker += 10;
                                        }
-                                       
+
                                        return true;
-                                       
+
                                } else {
                                        register_error($widget->subtype);
                                }
-                               
+
                        }
-                       
+
                        return false;
-                       
+
                }
-               
+
        /**
         * Get widgets for a particular context and column, in order of display
         *
         * @return array|false An array of widget ElggObjects, or false
         */
                function get_widgets($user_guid, $context, $column) {
-                       
+
                        if ($widgets = get_entities_from_private_setting_multi(array(
                                                                                                'column' => $column,
                                                                                                'context' => $context), "object", "widget", $user_guid, "", 10000))
                        /*if ($widgets = get_user_objects_by_metadata($user_guid, "widget", array(
                                                                                                'column' => $column,
-                                                                                               'context' => $context, 
+                                                                                               'context' => $context,
                                                                                                                                        ), 10000)) {
                        */
                        {
-                                                                                                                                               
+
                                $widgetorder = array();
                                foreach($widgets as $widget) {
                                        $order = $widget->order;
                                        while(isset($widgetorder[$order])) {
                                                $order++;
                                        }
-                                       $widgetorder[$order] = $widget; 
+                                       $widgetorder[$order] = $widget;
                                }
-                               
+
                                ksort($widgetorder);
-                               
+
                                return $widgetorder;
-                                                                                                                                               
+
                        }
-                       
+
                        return false;
-                       
+
                }
 
        /**
         * @return string The HTML for the widget, including JavaScript wrapper
         */
                function display_widget(ElggObject $widget) {
-                       
+
                        return elgg_view_entity($widget);
-                       
+
                }
-               
+
        /**
         * Add a new widget
         *
         * @return true|false Depending on success
         */
                function add_widget($user_guid, $handler, $context, $order = 0, $column = 1, $access_id = null) {
-                       
+
                        if (empty($user_guid) || empty($context) || empty($handler) || !widget_type_exists($handler))
                                return false;
-                       
+
                        if ($user = get_user($user_guid)) {
-                               
+
                                $widget = new ElggWidget;
                                $widget->owner_guid = $user_guid;
                                $widget->container_guid = $user_guid;
 
                                if (!$widget->save())
                                        return false;
-                                       
+
                                $widget->handler = $handler;
                                $widget->context = $context;
                                $widget->column = $column;
                                $widget->order = $order;
-                               
+
                                // save_widget_location($widget, $order, $column);
                                return true;
-                               
+
                        }
-                       
+
                        return false;
-                       
+
                }
-               
+
        /**
         * Define a new widget type
         *
         * @param string $position A comma-separated list of positions on the page (side or main) where this widget is allowed (default: "side,main")
         * @return true|false Depending on success
         */
-               
+
                function add_widget_type($handler, $name, $description, $context = "all", $multiple = false, $positions = "side,main") {
 
                        if (!empty($handler) && !empty($name)) {
-                               
+
                                global $CONFIG;
-                               
+
                                if (!isset($CONFIG->widgets))
                                        $CONFIG->widgets = new stdClass;
-                                       
+
                                if (!isset($CONFIG->widgets->handlers))
                                        $CONFIG->widgets->handlers = array();
-                               
+
                                $handlerobj = new stdClass;
                                $handlerobj->name = $name;
                                $handlerobj->description = $description;
                                $handlerobj->context = explode(",",$context);
                                $handlerobj->multiple = $multiple;
                                $handlerobj->positions = explode(",",$positions);
-                                       
+
                                $CONFIG->widgets->handlers[$handler] = $handlerobj;
 
                                return true;
-                                       
+
                        }
-                       
+
                        return false;
-                       
+
                }
-               
+
        /**
         * Determines whether or not widgets with the specified handler have been defined
         *
         * @return true|false Whether or not those widgets exist
         */
                function widget_type_exists($handler) {
-                       
+
                        global $CONFIG;
-                       if (!empty($CONFIG->widgets) 
-                               && !empty($CONFIG->widgets->handlers) 
-                               && is_array($CONFIG->widgets->handlers) 
+                       if (!empty($CONFIG->widgets)
+                               && !empty($CONFIG->widgets->handlers)
+                               && is_array($CONFIG->widgets->handlers)
                                && array_key_exists($handler, $CONFIG->widgets->handlers))
                                        return true;
 
                        return false;
-                       
+
                }
-               
+
        /**
         * Returns an array of stdClass objects representing the defined widget types
         *
         * @return array A list of types defined (if any)
         */
                function get_widget_types() {
-                       
+
                        global $CONFIG;
-                       if (!empty($CONFIG->widgets) 
-                               && !empty($CONFIG->widgets->handlers) 
+                       if (!empty($CONFIG->widgets)
+                               && !empty($CONFIG->widgets->handlers)
                                && is_array($CONFIG->widgets->handlers)) {
-                                       
+
                                        $context = get_context();
-                                       
+
                                        foreach($CONFIG->widgets->handlers as $key => $handler) {
                                                if (!in_array('all',$handler->context) &&
                                                        !in_array($context,$handler->context)) {
                                                                unset($CONFIG->widgets->handlers[$key]);
                                                }
                                        }
-                                       
+
                                        return $CONFIG->widgets->handlers;
-                                       
+
                                }
-                               
+
                        return array();
-                       
+
                }
-               
+
        /**
         * Saves a widget's settings (by passing an array of (name => value) pairs to save_{$handler}_widget)
         *
         * @param int $widget_guid The GUID of the widget we're saving to
-        * @param array $params An array of name => value parameters 
+        * @param array $params An array of name => value parameters
         */
                function save_widget_info($widget_guid, $params) {
-                       
+
                        if ($widget = get_entity($widget_guid)) {
-                               
+
                                $subtype = $widget->getSubtype();
-                               
+
                                if ($subtype != "widget") return false;
                                $handler = $widget->handler;
                                if (empty($handler) || !widget_type_exists($handler)) return false;
-                               
+
                                if (!$widget->canEdit()) return false;
-                               
-                               // Save the params to the widget 
+
+                               // Save the params to the widget
                                if (is_array($params) && sizeof($params) > 0) {
                                        foreach($params as $name => $value) {
-                                               
+
                                                if (!empty($name) && !in_array($name,array(
                                                                'guid','owner_guid','site_guid'
                                                                                                                                        ))) {
                                        }
                                        $widget->save();
                                }
-                               
+
                                $function = "save_{$handler}_widget";
                                if (is_callable($function)) {
                                        return $function($params);
                                }
-                               
+
                                return true;
-                               
+
                        }
-                       
+
                        return false;
-                       
+
                }
-               
+
                function reorder_widgets_from_panel($panelstring1, $panelstring2, $panelstring3, $context, $owner) {
-                       
+
                        $return = true;
-                       
+
                        $mainwidgets = explode('::',$panelstring1);
                        $sidewidgets = explode('::',$panelstring2);
                        $rightwidgets = explode('::',$panelstring3);
-                       
+
                        $handlers = array();
                        $guids = array();
-                       
+
                        if (is_array($mainwidgets) && sizeof($mainwidgets) > 0) {
                                foreach($mainwidgets as $widget) {
-                                       
+
                                        $guid = (int) $widget;
 
                                        if ("{$guid}" == "{$widget}") {
                                        } else {
                                                $handlers[1][] = $widget;
                                        }
-                                       
+
                                }
                        }
                        if (is_array($sidewidgets) && sizeof($sidewidgets) > 0) {
                                foreach($sidewidgets as $widget) {
-                                       
+
                                        $guid = (int) $widget;
 
                                        if ("{$guid}" == "{$widget}") {
                                        } else {
                                                $handlers[2][] = $widget;
                                        }
-                                       
+
                                }
                        }
                        if (is_array($rightwidgets) && sizeof($rightwidgets) > 0) {
                                foreach($rightwidgets as $widget) {
-                                       
+
                                        $guid = (int) $widget;
 
                                        if ("{$guid}" == "{$widget}") {
                                        } else {
                                                $handlers[3][] = $widget;
                                        }
-                                       
+
                                }
                        }
-                       
+
                        // Reorder existing widgets or delete ones that have vanished
                        foreach (array(1,2,3) as $column) {
                                if ($dbwidgets = get_widgets($owner,$context,$column)) {
-                                       
+
                                        foreach($dbwidgets as $dbwidget) {
                                                if (in_array($dbwidget->getGUID(),$guids[1]) || in_array($dbwidget->getGUID(),$guids[2]) || in_array($dbwidget->getGUID(),$guids[3])) {
                                                        if (in_array($dbwidget->getGUID(),$guids[1])) {
                                                        }
                                                }
                                        }
-                                       
+
                                }
                                // Add new ones
                                if (sizeof($guids[$column]) > 0) {
                                        }
                                }
                        }
-                       
+
                        return $return;
-                       
+
                }
-               
+
                /**
                 * Run some things once.
                 *
                function widget_run_once()
                {
                        // Register a class
-                       add_subtype("object", "widget", "ElggWidget");  
+                       add_subtype("object", "widget", "ElggWidget");
                }
 
        /**
         *
         */
                function widgets_init() {
-                       
+
                        register_action('widgets/reorder');
                        register_action('widgets/save');
                        register_action('widgets/add');
-                       
+
                        // Now run this stuff, but only once
                        run_function_once("widget_run_once");
                }
-               
+
        // Register event
                register_elgg_event_handler('init','system','widgets_init');