]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Standardized annotations.php.
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Fri, 9 Oct 2009 22:20:28 +0000 (22:20 +0000)
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Fri, 9 Oct 2009 22:20:28 +0000 (22:20 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@3525 36083f99-b078-4883-b0ff-0f9b5a30f544

engine/lib/annotations.php

index d0862345d7d036b09ab31bba02c3e51748074440..f6535a03616699559f4a937c555439dfeb2e5a41 100644 (file)
 <?php
-       /**
-        * Elgg annotations
-        * Functions to manage object annotations.
-        * 
-        * @package Elgg
-        * @subpackage Core
-
-        * @author Curverider Ltd <info@elgg.com>
+/**
+ * Elgg annotations
+ * Functions to manage object annotations.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ * @link http://elgg.org/
+ */
 
-        * @link http://elgg.org/
-        */
+/**
+ * Include the ElggExtender superclass
+ *
+ */
+require_once('extender.php');
 
-    /**
-     * Include the ElggExtender superclass
-     * 
-     */
-       require_once('extender.php');
+/**
+ * ElggAnnotation
+ *
+ * An annotation is similar to metadata each entity can contain more than one of each annotation.
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd <info@elgg.com>
+ */
+class ElggAnnotation extends ElggExtender {
 
        /**
-        * ElggAnnotation
-        * 
-        * An annotation is similar to metadata each entity can contain more than one of each annotation.
-        * 
-        * @package Elgg
-        * @subpackage Core
-        * @author Curverider Ltd <info@elgg.com>
+        * Construct a new site object, optionally from a given id value or db row.
+        *
+        * @param mixed $id
         */
-       class ElggAnnotation extends ElggExtender
-       {
-               
-               /**
-                * Construct a new site object, optionally from a given id value or db row.
-                *
-                * @param mixed $id
-                */
-               function __construct($id = null) 
-               {
-                       $this->attributes = array();
-                       
-                       if (!empty($id)) {
-                               if ($id instanceof stdClass)
-                                       $annotation = $id;
-                               else
-                                       $annotation = get_annotation($id);
-                               
-                               if ($annotation) {
-                                       $objarray = (array) $annotation;
-                                       foreach($objarray as $key => $value) {
-                                               $this->attributes[$key] = $value;
-                                       }
-                                       $this->attributes['type'] = "annotation";
-                               }
+       function __construct($id = null) {
+               $this->attributes = array();
+
+               if (!empty($id)) {
+                       if ($id instanceof stdClass) {
+                               $annotation = $id;
+                       } else {
+                               $annotation = get_annotation($id);
                        }
-               }
-               
-               /**
-                * Class member get overloading
-                *
-                * @param string $name
-                * @return mixed
-                */
-               function __get($name) {
-                       return $this->get($name);
-               }
-               
-               /**
-                * Class member set overloading
-                *
-                * @param string $name
-                * @param mixed $value
-                * @return void
-                */
-               function __set($name, $value) {
-                       return $this->set($name, $value);
-               }               
-               
-               /**
-                * Save this instance
-                *
-                * @return int an object id
-                */
-               function save()
-               {
-                       if ($this->id > 0)
-                               return update_annotation($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
-                       else
-                       { 
-                               $this->id = create_annotation($this->entity_guid, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
-                               if (!$this->id) throw new IOException(sprintf(elgg_new('IOException:UnableToSaveNew'), get_class()));
-                               return $this->id;
+
+                       if ($annotation) {
+                               $objarray = (array) $annotation;
+
+                               foreach($objarray as $key => $value) {
+                                       $this->attributes[$key] = $value;
+                               }
+
+                               $this->attributes['type'] = "annotation";
                        }
                }
-               
-               /**
-                * Delete a given site.
-                */
-               function delete() 
-               { 
-                       return delete_annotation($this->id); 
-               }
-               
-               /**
-                * Get a url for this annotation.
-                *
-                * @return string
-                */
-               public function getURL() { return get_annotation_url($this->id); }
-       
-               // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
-
-               /**
-                * For a given ID, return the object associated with it.
-                * This is used by the river functionality primarily.
-                * This is useful for checking access permissions etc on objects.
-                */
-               public function getObjectFromID($id) { return get_annotation($id); }
-       }
-       
+       }
+
        /**
-        * Convert a database row to a new ElggAnnotation
+        * Class member get overloading
         *
-        * @param stdClass $row
-        * @return stdClass or ElggAnnotation
+        * @param string $name
+        * @return mixed
         */
-       function row_to_elggannotation($row) 
-       {
-               if (!($row instanceof stdClass))
-                       return $row;
-                       
-               return new ElggAnnotation($row);
-       }
-       
+       function __get($name) {
+               return $this->get($name);
+       }
+
        /**
-        * Get a specific annotation.
+        * Class member set overloading
         *
-        * @param int $annotation_id
+        * @param string $name
+        * @param mixed $value
+        * @return void
         */
-       function get_annotation($annotation_id)
-       {
-               global $CONFIG;
-               
-               $annotation_id = (int) $annotation_id;
-               $access = get_access_sql_suffix("a");
-               
-               return row_to_elggannotation(get_data_row("SELECT a.*, n.string as name, v.string as value from {$CONFIG->dbprefix}annotations a JOIN {$CONFIG->dbprefix}metastrings n on a.name_id = n.id JOIN {$CONFIG->dbprefix}metastrings v on a.value_id = v.id where a.id=$annotation_id and $access"));                 
-       }
-       
+       function __set($name, $value) {
+               return $this->set($name, $value);
+       }
+
        /**
-        * Create a new annotation.
+        * Save this instance
         *
-        * @param int $entity_guid
-        * @param string $name
-        * @param string $value
-        * @param string $value_type
-        * @param int $owner_guid
-        * @param int $access_id
+        * @return int an object id
         */
-       function create_annotation($entity_guid, $name, $value, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE)
-       {
-               global $CONFIG;
+       function save() {
+               if ($this->id > 0) {
+                       return update_annotation($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id);
+               } else {
+                       $this->id = create_annotation($this->entity_guid, $this->name, $this->value,
+                               $this->value_type, $this->owner_guid, $this->access_id);
 
-               $result = false;
-               
-               $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)));
-               
-               $owner_guid = (int)$owner_guid;
-               if ($owner_guid==0) $owner_guid = get_loggedin_userid();
-               
-               $access_id = (int)$access_id;
-               
-               $time = time();
-               
-               // Add the metastring
-               $value = add_metastring($value);
-               if (!$value) return false;
-               
-               $name = add_metastring($name);
-               if (!$name) return false;
-               
-               $entity = get_entity($entity_guid);
-               
-               if (trigger_elgg_event('annotate',$entity->type,$entity)) {
-                       system_log($entity, 'annotate');
-                       
-                       // If ok then add it
-                       $result = insert_data("INSERT into {$CONFIG->dbprefix}annotations (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 ($result!==false) {
-                               $obj = get_annotation($result);
-                               if (trigger_elgg_event('create', 'annotation', $obj)) {
-                                       return $result;
-                               } else {
-                                       delete_annotation($result);
-                               }
+                       if (!$this->id) {
+                               throw new IOException(sprintf(elgg_new('IOException:UnableToSaveNew'), get_class()));
                        }
+                       return $this->id;
                }
-               
-               return $result;
        }
-       
+
        /**
-        * Update an annotation.
-        *
-        * @param int $annotation_id
-        * @param string $name
-        * @param string $value
-        * @param string $value_type
-        * @param int $owner_guid
-        * @param int $access_id
+        * Delete a given site.
         */
-       function update_annotation($annotation_id, $name, $value, $value_type, $owner_guid, $access_id)
-       {
-               global $CONFIG;
-
-               $annotation_id = (int)$annotation_id;
-               $name = (trim($name));
-               $value = (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();
-               
-               // Add the metastring
-               $value = add_metastring($value);
-               if (!$value) return false;
-               
-               $name = add_metastring($name);
-               if (!$name) return false;
-               
-               // If ok then add it            
-               $result = update_data("UPDATE {$CONFIG->dbprefix}annotations set value_id='$value', value_type='$value_type', access_id=$access_id, owner_guid=$owner_guid where id=$annotation_id and name_id='$name' and $access");
-               if ($result!==false) {
-                       $obj = get_annotation($annotation_id);
-                       if (trigger_elgg_event('update', 'annotation', $obj)) {
-                               return true;
-                       } else {
-                               delete_annotation($annotation_id);
-                       }
-               }
-               
-               return $result;
+       function delete() {
+               return delete_annotation($this->id);
        }
-       
+
        /**
-        * Get a list of annotations for a given object/user/annotation type.
+        * Get a url for this annotation.
         *
-        * @param int|array $entity_guid
-        * @param string $entity_type
-        * @param string $entity_subtype
-        * @param string $name
-        * @param mixed $value
-        * @param int|array $owner_guid
-        * @param int $limit
-        * @param int $offset
-        * @param string $order_by
+        * @return string
         */
-       function get_annotations($entity_guid = 0, $entity_type = "", $entity_subtype = "", $name = "", 
-       $value = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "asc", $timelower = 0, $timeupper = 0, $entity_owner_guid = 0)
-       {
-               global $CONFIG;
-               
-               $timelower = (int) $timelower;
-               $timeupper = (int) $timeupper;
-               
-               if (is_array($entity_guid)) {
-                       if (sizeof($entity_guid) > 0) {
-                               foreach($entity_guid as $key => $val) {
-                                       $entity_guid[$key] = (int) $val;
-                               }
+       public function getURL() {
+               return get_annotation_url($this->id);
+       }
+
+       // SYSTEM LOG INTERFACE ////////////////////////////////////////////////////////////
+
+       /**
+        * For a given ID, return the object associated with it.
+        * This is used by the river functionality primarily.
+        * This is useful for checking access permissions etc on objects.
+        */
+       public function getObjectFromID($id) {
+               return get_annotation($id);
+       }
+}
+
+/**
+ * Convert a database row to a new ElggAnnotation
+ *
+ * @param stdClass $row
+ * @return stdClass or ElggAnnotation
+ */
+function row_to_elggannotation($row) {
+       if (!($row instanceof stdClass)) {
+               return $row;
+       }
+
+       return new ElggAnnotation($row);
+}
+
+/**
+ * Get a specific annotation.
+ *
+ * @param int $annotation_id
+ */
+function get_annotation($annotation_id) {
+       global $CONFIG;
+
+       $annotation_id = (int) $annotation_id;
+       $access = get_access_sql_suffix("a");
+
+       return row_to_elggannotation(get_data_row("SELECT a.*, n.string as name, v.string as value from {$CONFIG->dbprefix}annotations a JOIN {$CONFIG->dbprefix}metastrings n on a.name_id = n.id JOIN {$CONFIG->dbprefix}metastrings v on a.value_id = v.id where a.id=$annotation_id and $access"));
+}
+
+/**
+ * Create a new annotation.
+ *
+ * @param int $entity_guid
+ * @param string $name
+ * @param string $value
+ * @param string $value_type
+ * @param int $owner_guid
+ * @param int $access_id
+ */
+function create_annotation($entity_guid, $name, $value, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE) {
+       global $CONFIG;
+
+       $result = false;
+
+       $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)));
+
+       $owner_guid = (int)$owner_guid;
+       if ($owner_guid==0) {
+               $owner_guid = get_loggedin_userid();
+       }
+
+       $access_id = (int)$access_id;
+       $time = time();
+
+       // Add the metastring
+       $value = add_metastring($value);
+       if (!$value) {
+               return false;
+       }
+
+       $name = add_metastring($name);
+       if (!$name) {
+               return false;
+       }
+
+       $entity = get_entity($entity_guid);
+
+       if (trigger_elgg_event('annotate',$entity->type,$entity)) {
+               system_log($entity, 'annotate');
+
+               // If ok then add it
+               $result = insert_data("INSERT into {$CONFIG->dbprefix}annotations
+                       (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 ($result!==false) {
+                       $obj = get_annotation($result);
+                       if (trigger_elgg_event('create', 'annotation', $obj)) {
+                               return $result;
                        } else {
-                               $entity_guid = 0;
+                               delete_annotation($result);
                        }
-               } else {
-                       $entity_guid = (int)$entity_guid;
                }
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               if ($name)
-               {
-                       $name = get_metastring_id($name);
-               
-                       if ($name === false)
-                               $name = 0;
-               }
-               if ($value != "") $value = get_metastring_id($value);
-               if (is_array($owner_guid)) {
-                       if (sizeof($owner_guid) > 0) {
-                               foreach($owner_guid as $key => $val) {
-                                       $owner_guid[$key] = (int) $val;
-                               }
-                       } else {
-                               $owner_guid = 0;
-                       }
+       }
+
+       return $result;
+}
+
+/**
+ * Update an annotation.
+ *
+ * @param int $annotation_id
+ * @param string $name
+ * @param string $value
+ * @param string $value_type
+ * @param int $owner_guid
+ * @param int $access_id
+ */
+function update_annotation($annotation_id, $name, $value, $value_type, $owner_guid, $access_id) {
+       global $CONFIG;
+
+       $annotation_id = (int)$annotation_id;
+       $name = (trim($name));
+       $value = (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();
+
+       // Add the metastring
+       $value = add_metastring($value);
+       if (!$value) {
+               return false;
+       }
+
+       $name = add_metastring($name);
+       if (!$name) {
+               return false;
+       }
+
+       // If ok then add it
+       $result = update_data("UPDATE {$CONFIG->dbprefix}annotations
+               set value_id='$value', value_type='$value_type', access_id=$access_id, owner_guid=$owner_guid
+               where id=$annotation_id and name_id='$name' and $access");
+
+       if ($result!==false) {
+               $obj = get_annotation($annotation_id);
+               if (trigger_elgg_event('update', 'annotation', $obj)) {
+                       return true;
                } else {
-                       $owner_guid = (int)$owner_guid;
+                       delete_annotation($annotation_id);
                }
+       }
 
-               if (is_array($entity_owner_guid)) {
-                       if (sizeof($entity_owner_guid) > 0) {
-                               foreach($entity_owner_guid as $key => $val) {
-                                       $entity_owner_guid[$key] = (int) $val;
-                               }
-                       } else {
-                               $entity_owner_guid = 0;
+       return $result;
+}
+
+/**
+ * Get a list of annotations for a given object/user/annotation type.
+ *
+ * @param int|array $entity_guid
+ * @param string $entity_type
+ * @param string $entity_subtype
+ * @param string $name
+ * @param mixed $value
+ * @param int|array $owner_guid
+ * @param int $limit
+ * @param int $offset
+ * @param string $order_by
+ */
+function get_annotations($entity_guid = 0, $entity_type = "", $entity_subtype = "", $name = "",
+$value = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "asc", $timelower = 0, $timeupper = 0, $entity_owner_guid = 0) {
+       global $CONFIG;
+
+       $timelower = (int) $timelower;
+       $timeupper = (int) $timeupper;
+
+       if (is_array($entity_guid)) {
+               if (sizeof($entity_guid) > 0) {
+                       foreach($entity_guid as $key => $val) {
+                               $entity_guid[$key] = (int) $val;
                        }
                } else {
-                       $entity_owner_guid = (int)$entity_owner_guid;
+                       $entity_guid = 0;
                }
-               
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if($order_by == 'asc')
-                   $order_by = "a.time_created asc";
-                   
-               if($order_by == 'desc')
-                   $order_by = "a.time_created desc";
-               
-               $where = array();
-               
-               if ($entity_guid != 0 && !is_array($entity_guid)) {
-                       $where[] = "a.entity_guid=$entity_guid";
-               } else if (is_array($entity_guid)) {
-                       $where[] = "a.entity_guid in (". implode(",",$entity_guid) . ")";
+       } else {
+               $entity_guid = (int)$entity_guid;
+       }
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       if ($name) {
+               $name = get_metastring_id($name);
+
+               if ($name === false) {
+                       $name = 0;
                }
-                       
-               if ($entity_type != "")
-                       $where[] = "e.type='$entity_type'";
-                       
-               if ($entity_subtype != "")
-                       $where[] = "e.subtype='$entity_subtype'";
-               
-               if ($owner_guid != 0 && !is_array($owner_guid)) {
-                       $where[] = "a.owner_guid=$owner_guid";
+       }
+       if ($value != "") {
+               $value = get_metastring_id($value);
+       }
+
+       if (is_array($owner_guid)) {
+               if (sizeof($owner_guid) > 0) {
+                       foreach($owner_guid as $key => $val) {
+                               $owner_guid[$key] = (int) $val;
+                       }
                } else {
-                       if (is_array($owner_guid))
-                               $where[] = "a.owner_guid in (" . implode(",",$owner_guid) . ")";
+                       $owner_guid = 0;
                }
-               
-               if ($entity_owner_guid != 0 && !is_array($entity_owner_guid)) {
-                       $where[] = "e.owner_guid=$entity_owner_guid";
+       } else {
+               $owner_guid = (int)$owner_guid;
+       }
+
+       if (is_array($entity_owner_guid)) {
+               if (sizeof($entity_owner_guid) > 0) {
+                       foreach($entity_owner_guid as $key => $val) {
+                               $entity_owner_guid[$key] = (int) $val;
+                       }
                } else {
-                       if (is_array($entity_owner_guid))
-                               $where[] = "e.owner_guid in (" . implode(",",$entity_owner_guid) . ")";
+                       $entity_owner_guid = 0;
                }
-                       
-               if ($name !== "")
-                       $where[] = "a.name_id='$name'";
-                       
-               if ($value != "")
-                       $where[] = "a.value_id='$value'";
-                       
-               if ($timelower)
-                       $where[] = "a.time_created >= {$timelower}";
-               if ($timeupper)
-                       $where[] = "a.time_created <= {$timeupper}";
-                       
-               $query = "SELECT a.*, n.string as name, v.string as value from {$CONFIG->dbprefix}annotations a JOIN {$CONFIG->dbprefix}entities e on a.entity_guid = e.guid JOIN {$CONFIG->dbprefix}metastrings v on a.value_id=v.id JOIN {$CONFIG->dbprefix}metastrings n on a.name_id = n.id where ";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("a"); // Add access controls
-               $query .= " order by $order_by limit $offset,$limit"; // Add order and limit
-               
-               return get_data($query, "row_to_elggannotation");
-               
-       }
-       
-       /**
-        * Return a list of entities which are annotated with a specific annotation. 
-        * These can be ordered by when the annotation was created/updated.
-        * 
-        * @param string $entity_type Type of entity.
-        * @param string $entity_subtype Subtype of entity.
-        * @param string $name Name of annotation.
-        * @param string $value Value of annotation.
-        * @param int $owner_guid Owner.
-        * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
-        * @param int $limit Maximum number of results to return.
-        * @param int $offset Place to start.
-        * @param string $order_by How to order results.
-        * @param boolean $count Whether to count entities rather than return them
-        * @param int $timelower The earliest time the annotation can have been created. Default: all
-        * @param int $timeupper The latest time the annotation can have been created. Default: all
-        */
-       function get_entities_from_annotations($entity_type = "", $entity_subtype = "", $name = "", $value = "", $owner_guid = 0, $group_guid = 0, $limit = 10, $offset = 0, $order_by = "asc", $count = false, $timelower = 0, $timeupper = 0)
-       {
-               global $CONFIG;
-               
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $timelower = (int) $timelower;
-               $timeupper = (int) $timeupper;
-               
-               if ($name)
-               {
-                       $name = get_metastring_id($name);
-               
-                       if ($name === false)
-                               $name = 0;
-               }
-               if ($value != "") $value = get_metastring_id($value);
+       } else {
+               $entity_owner_guid = (int)$entity_owner_guid;
+       }
+
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if($order_by == 'asc') {
+               $order_by = "a.time_created asc";
+       }
+
+       if($order_by == 'desc') {
+               $order_by = "a.time_created desc";
+       }
+
+       $where = array();
+
+       if ($entity_guid != 0 && !is_array($entity_guid)) {
+               $where[] = "a.entity_guid=$entity_guid";
+       } else if (is_array($entity_guid)) {
+               $where[] = "a.entity_guid in (". implode(",",$entity_guid) . ")";
+       }
+
+       if ($entity_type != "") {
+               $where[] = "e.type='$entity_type'";
+       }
+
+       if ($entity_subtype != "") {
+               $where[] = "e.subtype='$entity_subtype'";
+       }
+
+       if ($owner_guid != 0 && !is_array($owner_guid)) {
+               $where[] = "a.owner_guid=$owner_guid";
+       } else {
                if (is_array($owner_guid)) {
-                       if (sizeof($owner_guid) > 0) {
-                               foreach($owner_guid as $key => $val) {
-                                       $owner_guid[$key] = (int) $val;
-                               }
-                       } else {
-                               $owner_guid = 0;
-                       }
-               } else {
-                       $owner_guid = (int)$owner_guid;
+                       $where[] = "a.owner_guid in (" . implode(",",$owner_guid) . ")";
                }
-               $group_guid = (int)$group_guid;
-               
-               $limit = (int)$limit;
-               $offset = (int)$offset;
-               if($order_by == 'asc')
-                   $order_by = "maxtime asc";
-                   
-               if($order_by == 'desc')
-                   $order_by = "maxtime desc";
-               
-               $where = array();
-               
-               if ($entity_type != "")
-                       $where[] = "e.type='$entity_type'";
-                       
-               if ($entity_subtype != "")
-                       $where[] = "e.subtype='$entity_subtype'";
-               
-               if ($owner_guid != 0 && !is_array($owner_guid)) {
-                       $where[] = "a.owner_guid=$owner_guid";
-               } else {
-                       if (is_array($owner_guid))
-                               $where[] = "a.owner_guid in (" . implode(",",$owner_guid) . ")";
+       }
+
+       if ($entity_owner_guid != 0 && !is_array($entity_owner_guid)) {
+               $where[] = "e.owner_guid=$entity_owner_guid";
+       } else {
+               if (is_array($entity_owner_guid)) {
+                       $where[] = "e.owner_guid in (" . implode(",",$entity_owner_guid) . ")";
                }
-               
-               if (($group_guid != 0) && ($entity_type=='object'))
-                       $where[] = "e.container_guid = $group_guid";
-                       
-               if ($name !== "")
-                       $where[] = "a.name_id='$name'";
-                       
-               if ($value != "")
-                       $where[] = "a.value_id='$value'";
-
-               if ($timelower)
-                       $where[] = "a.time_created >= {$timelower}";
-               if ($timeupper)
-                       $where[] = "a.time_created <= {$timeupper}";
-               
-               if ($count) {
-                       $query = "SELECT count(distinct e.guid) as total ";
-               } else {
-                       $query = "SELECT e.*, max(a.time_created) as maxtime ";                 
+       }
+
+       if ($name !== "") {
+               $where[] = "a.name_id='$name'";
+       }
+
+       if ($value != "") {
+               $where[] = "a.value_id='$value'";
+       }
+
+       if ($timelower) {
+               $where[] = "a.time_created >= {$timelower}";
+       }
+
+       if ($timeupper) {
+               $where[] = "a.time_created <= {$timeupper}";
+       }
+
+       $query = "SELECT a.*, n.string as name, v.string as value
+               FROM {$CONFIG->dbprefix}annotations a
+               JOIN {$CONFIG->dbprefix}entities e on a.entity_guid = e.guid
+               JOIN {$CONFIG->dbprefix}metastrings v on a.value_id=v.id
+               JOIN {$CONFIG->dbprefix}metastrings n on a.name_id = n.id where ";
+
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+       $query .= get_access_sql_suffix("a"); // Add access controls
+       $query .= " order by $order_by limit $offset,$limit"; // Add order and limit
+
+       return get_data($query, "row_to_elggannotation");
+}
+
+/**
+ * Return a list of entities which are annotated with a specific annotation.
+ * These can be ordered by when the annotation was created/updated.
+ *
+ * @param string $entity_type Type of entity.
+ * @param string $entity_subtype Subtype of entity.
+ * @param string $name Name of annotation.
+ * @param string $value Value of annotation.
+ * @param int $owner_guid Owner.
+ * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
+ * @param int $limit Maximum number of results to return.
+ * @param int $offset Place to start.
+ * @param string $order_by How to order results.
+ * @param boolean $count Whether to count entities rather than return them
+ * @param int $timelower The earliest time the annotation can have been created. Default: all
+ * @param int $timeupper The latest time the annotation can have been created. Default: all
+ */
+function get_entities_from_annotations($entity_type = "", $entity_subtype = "", $name = "", $value = "", $owner_guid = 0, $group_guid = 0, $limit = 10, $offset = 0, $order_by = "asc", $count = false, $timelower = 0, $timeupper = 0) {
+       global $CONFIG;
+
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $timelower = (int) $timelower;
+       $timeupper = (int) $timeupper;
+
+       if ($name) {
+               $name = get_metastring_id($name);
+
+               if ($name === false) {
+                       $name = 0;
                }
-               $query .= "from {$CONFIG->dbprefix}annotations a JOIN {$CONFIG->dbprefix}entities e on e.guid = a.entity_guid ";
-               if ($value != "")
-                       $query .= " JOIN {$CONFIG->dbprefix}metastrings v on a.value_id=v.id ";
-               
-               if (($group_guid != 0) && ($entity_type=='object')) $query .= "JOIN {$CONFIG->dbprefix}objects_entity o on o.guid = e.guid";
-               $query .= " where";
-                   
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("a"); // Add access controls
-               $query .= ' and ' . get_access_sql_suffix("e"); // Add access controls
-               
-               if ($count) {
-                       $row = get_data_row($query);
-                       return $row->total;
-               } else {
-                       $query .= " group by a.entity_guid order by $order_by limit $offset,$limit"; // Add order and limit
-                       return get_data($query, "entity_row_to_elggstar");
-               }    
        }
-       
-       /**
-        * Lists entities
-        *
-        * @see elgg_view_entity_list
-        * 
-        * @param string $entity_type Type of entity.
-        * @param string $entity_subtype Subtype of entity.
-        * @param string $name Name of annotation.
-        * @param string $value Value of annotation.
-        * @param int $limit Maximum number of results to return.
-        * @param int $owner_guid Owner.
-        * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
-        * @param boolean $asc Whether to list in ascending or descending order (default: desc)
-        * @param boolean $fullview Whether to display the entities in full
-        * @param boolean $viewtypetoggle Determines whether or not the 'gallery' view can be displayed (default: no)
-        * @return string Formatted entity list
-        */
-       function list_entities_from_annotations($entity_type = "", $entity_subtype = "", $name = "", $value = "", $limit = 10, $owner_guid = 0, $group_guid = 0, $asc = false, $fullview = true, $viewtypetoggle = false) {
-               
-               if ($asc) {
-                       $asc = "asc";
+       if ($value != "") {
+               $value = get_metastring_id($value);
+       }
+       if (is_array($owner_guid)) {
+               if (sizeof($owner_guid) > 0) {
+                       foreach($owner_guid as $key => $val) {
+                               $owner_guid[$key] = (int) $val;
+                       }
                } else {
-                       $asc = "desc";
+                       $owner_guid = 0;
                }
-               $count = get_entities_from_annotations($entity_type, $entity_subtype, $name, $value, $owner_guid, $group_guid, null, null, $asc, true);
-               $offset = (int) get_input("offset",0);
-               $entities = get_entities_from_annotations($entity_type, $entity_subtype, $name, $value, $owner_guid, $group_guid, $limit, $offset, $asc);
+       } else {
+               $owner_guid = (int)$owner_guid;
+       }
+       $group_guid = (int)$group_guid;
 
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle);
-               
+       $limit = (int)$limit;
+       $offset = (int)$offset;
+       if($order_by == 'asc') {
+               $order_by = "maxtime asc";
        }
-       
-       /**
-        * Returns a human-readable list of annotations on a particular entity.
-        *
-        * @param int $entity_guid The entity GUID
-        * @param string $name The name of the kind of annotation
-        * @param int $limit The number of annotations to display at once
-        * @param true|false $asc Whether or not the annotations are displayed in ascending order. (Default: true)
-        * @return string HTML (etc) version of the annotation list
-        */
-       function list_annotations($entity_guid, $name = "", $limit = 25, $asc = true) {
-               
-               if ($asc) {
-                       $asc = "asc";
-               } else {
-                       $asc = "desc";
+
+       if($order_by == 'desc') {
+               $order_by = "maxtime desc";
+       }
+
+       $where = array();
+
+       if ($entity_type != "") {
+               $where[] = "e.type='$entity_type'";
+       }
+
+       if ($entity_subtype != "") {
+               $where[] = "e.subtype='$entity_subtype'";
+       }
+
+       if ($owner_guid != 0 && !is_array($owner_guid)) {
+               $where[] = "a.owner_guid=$owner_guid";
+       } else {
+               if (is_array($owner_guid)) {
+                       $where[] = "a.owner_guid in (" . implode(",",$owner_guid) . ")";
                }
-               $count = count_annotations($entity_guid, "", "", $name);
-               $offset = (int) get_input("annoff",0);
-               $annotations = get_annotations($entity_guid, "", "", $name, "", "", $limit, $offset, $asc);
-               
-               return elgg_view_annotation_list($annotations, $count, $offset, $limit);
-               
        }
 
-       /**
-        * Return the sum of a given integer annotation.
-        * 
-        * @param $entity_guid int
-        * @param $entity_type string
-        * @param $entity_subtype string
-        * @param $name string
-        */
-       function get_annotations_sum($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0)
-       {
-               return __get_annotations_calculate_x("sum", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+       if (($group_guid != 0) && ($entity_type=='object')) {
+               $where[] = "e.container_guid = $group_guid";
        }
-       
-       /**
-        * Return the max of a given integer annotation.
-        * 
-        * @param $entity_guid int
-        * @param $entity_type string
-        * @param $entity_subtype string
-        * @param $name string
-        */
-       function get_annotations_max($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0)
-       {
-               return __get_annotations_calculate_x("max", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+
+       if ($name !== "") {
+               $where[] = "a.name_id='$name'";
        }
-       
-       /**
-        * Return the minumum of a given integer annotation.
-        * 
-        * @param $entity_guid int
-        * @param $entity_type string
-        * @param $entity_subtype string
-        * @param $name string
-        */
-       function get_annotations_min($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0)
-       {
-               return __get_annotations_calculate_x("min", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+
+       if ($value != "") {
+               $where[] = "a.value_id='$value'";
        }
-       
-       /**
-        * Return the average of a given integer annotation.
-        * 
-        * @param $entity_guid int
-        * @param $entity_type string
-        * @param $entity_subtype string
-        * @param $name string
-        */
-       function get_annotations_avg($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0)
-       {
-               return __get_annotations_calculate_x("avg", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+
+       if ($timelower) {
+               $where[] = "a.time_created >= {$timelower}";
        }
-       
-       /**
-        * Count the number of annotations based on search parameters
-        *
-        * @param int $entity_guid
-        * @param string $entity_type
-        * @param string $entity_subtype
-        * @param string $name
-        */
-       function count_annotations($entity_guid = 0, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0, $timelower = 0, $timeupper = 0)
-       {
-               return __get_annotations_calculate_x("count", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid, $timelower, $timeupper);
+
+       if ($timeupper) {
+               $where[] = "a.time_created <= {$timeupper}";
        }
-       
-       /**
-        * Perform a mathmatical calculation on integer annotations.
-        * 
-        * @param $sum string
-        * @param $entity_id int
-        * @param $entity_type string
-        * @param $entity_subtype string
-        * @param $name string
-        */
-       function __get_annotations_calculate_x($sum = "avg", $entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0, $timelower = 0, $timeupper = 0)
-       {
-               global $CONFIG;
-               
-               $sum = sanitise_string($sum);
-               $entity_guid = (int)$entity_guid;
-               $entity_type = sanitise_string($entity_type);
-               $timeupper = (int)$timeupper;
-               $timelower = (int)$timelower;
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               if ($name != '' AND !$name = get_metastring_id($name))
-                       return 0;
-               if ($value != '' AND !$value = get_metastring_id($value))
-                       return 0;
-               $value_type = sanitise_string($value_type);
-               $owner_guid = (int)$owner_guid;
-               
-               // if (empty($name)) return 0;
-               
-               $where = array();
-               
-               if ($entity_guid)
-                       $where[] = "e.guid=$entity_guid";
-               if ($entity_type!="")
-                       $where[] = "e.type='$entity_type'";
-               if ($entity_subtype)
-                       $where[] = "e.subtype=$entity_subtype";
-               if ($name!="")
-                       $where[] = "a.name_id='$name'";
-               if ($value!="")
-                       $where[] = "a.value_id='$value'";
-               if ($value_type!="")
-                       $where[] = "a.value_type='$value_type'";
-               if ($owner_guid)
-                       $where[] = "a.owner_guid='$owner_guid'";
-               if ($timelower)
-                       $where[] = "a.time_created >= {$timelower}";
-               if ($timeupper)
-                       $where[] = "a.time_created <= {$timeupper}";
-                       
-               if ($sum != "count")
-                       $where[] = "a.value_type='integer'"; // Limit on integer types
-               
-               $query = "SELECT $sum(ms.string) as sum from {$CONFIG->dbprefix}annotations a JOIN {$CONFIG->dbprefix}entities e on a.entity_guid = e.guid JOIN {$CONFIG->dbprefix}metastrings ms on a.value_id=ms.id WHERE ";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("a"); // now add access
-               $query .= ' and ' . get_access_sql_suffix("e"); // now add access
-               
+
+       if ($count) {
+               $query = "SELECT count(distinct e.guid) as total ";
+       } else {
+               $query = "SELECT e.*, max(a.time_created) as maxtime ";
+       }
+
+       $query .= "FROM {$CONFIG->dbprefix}annotations a
+               JOIN {$CONFIG->dbprefix}entities e on e.guid = a.entity_guid ";
+
+       if ($value != "") {
+               $query .= " JOIN {$CONFIG->dbprefix}metastrings v on a.value_id=v.id ";
+       }
+
+       if (($group_guid != 0) && ($entity_type=='object')) {
+               $query .= "JOIN {$CONFIG->dbprefix}objects_entity o on o.guid = e.guid";
+       }
+       $query .= " where";
+
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+
+       $query .= get_access_sql_suffix("a"); // Add access controls
+       $query .= ' and ' . get_access_sql_suffix("e"); // Add access controls
+
+       if ($count) {
                $row = get_data_row($query);
-               if ($row)
-                       return $row->sum;
-                       
-               return false;
+               return $row->total;
+       } else {
+               $query .= " group by a.entity_guid order by $order_by limit $offset,$limit"; // Add order and limit
+               return get_data($query, "entity_row_to_elggstar");
        }
+}
 
-       /**
-        * Get entities ordered by a mathematical calculation
-        *
-        * @param $sum string
-        * @param $entity_type string
-        * @param $entity_subtype string
-        * @param $name string
-        * @param $mdname string
-        * @param $mdvalue string
-        * @param $limit int
-        * @param string $orderdir Default: asc - the sort order
-        * @return unknown
-        */
-       function __get_entities_from_annotations_calculate_x($sum = "sum", $entity_type = "", $entity_subtype = "", $name = "", $mdname = '', $mdvalue = '', $owner_guid = 0, $limit = 10, $offset = 0, $orderdir = 'desc', $count = false)
-       {
-               global $CONFIG;
-               
-               $sum = sanitise_string($sum);
-               $entity_type = sanitise_string($entity_type);
-               $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
-               $name = get_metastring_id($name);
-               $limit = (int) $limit;
-               $offset = (int) $offset;
-               $owner_guid = (int) $owner_guid;
-               if (!empty($mdname) && !empty($mdvalue)) {
-                       $meta_n = get_metastring_id($mdname);
-                       $meta_v = get_metastring_id($mdvalue);
-               }
-               
-               if (empty($name)) return 0;
-               
-               $where = array();
-               
-               if ($entity_type!="")
-                       $where[] = "e.type='$entity_type'";
-               if ($owner_guid > 0)
-                       $where[] = "e.container_guid = $owner_guid";
-               if ($entity_subtype)
-                       $where[] = "e.subtype=$entity_subtype";
-               if ($name!="")
-                       $where[] = "a.name_id='$name'";
-                       
-               if (!empty($mdname) && !empty($mdvalue)) {
-                       if ($mdname!="")
-                               $where[] = "m.name_id='$meta_n'";
-                       if ($mdvalue!="")
-                               $where[] = "m.value_id='$meta_v'";
-               }
-                       
-               if ($sum != "count")
-                       $where[] = "a.value_type='integer'"; // Limit on integer types
+/**
+ * Lists entities
+ *
+ * @see elgg_view_entity_list
+ *
+ * @param string $entity_type Type of entity.
+ * @param string $entity_subtype Subtype of entity.
+ * @param string $name Name of annotation.
+ * @param string $value Value of annotation.
+ * @param int $limit Maximum number of results to return.
+ * @param int $owner_guid Owner.
+ * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
+ * @param boolean $asc Whether to list in ascending or descending order (default: desc)
+ * @param boolean $fullview Whether to display the entities in full
+ * @param boolean $viewtypetoggle Determines whether or not the 'gallery' view can be displayed (default: no)
+ * @return string Formatted entity list
+ */
+function list_entities_from_annotations($entity_type = "", $entity_subtype = "", $name = "", $value = "", $limit = 10, $owner_guid = 0, $group_guid = 0, $asc = false, $fullview = true, $viewtypetoggle = false) {
+       if ($asc) {
+               $asc = "asc";
+       } else {
+               $asc = "desc";
+       }
+       $count = get_entities_from_annotations($entity_type, $entity_subtype, $name,
+               $value, $owner_guid, $group_guid, null, null, $asc, true);
+       $offset = (int) get_input("offset",0);
+       $entities = get_entities_from_annotations($entity_type, $entity_subtype, $name,
+               $value, $owner_guid, $group_guid, $limit, $offset, $asc);
 
-               if (!$count) {
-                       $query = "SELECT distinct e.*, $sum(ms.string) as sum ";
-               } else {
-                       $query = "SELECT count(distinct e.guid) as num, $sum(ms.string) as sum ";
-               }
-               $query .= " from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}annotations a on a.entity_guid = e.guid JOIN {$CONFIG->dbprefix}metastrings ms on a.value_id=ms.id ";
-               
-               if (!empty($mdname) && !empty($mdvalue)) {
-                       $query .= " JOIN {$CONFIG->dbprefix}metadata m on m.entity_guid = e.guid "; 
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle);
+}
+
+/**
+ * Returns a human-readable list of annotations on a particular entity.
+ *
+ * @param int $entity_guid The entity GUID
+ * @param string $name The name of the kind of annotation
+ * @param int $limit The number of annotations to display at once
+ * @param true|false $asc Whether or not the annotations are displayed in ascending order. (Default: true)
+ * @return string HTML (etc) version of the annotation list
+ */
+function list_annotations($entity_guid, $name = "", $limit = 25, $asc = true) {
+       if ($asc) {
+               $asc = "asc";
+       } else {
+               $asc = "desc";
+       }
+       $count = count_annotations($entity_guid, "", "", $name);
+       $offset = (int) get_input("annoff",0);
+       $annotations = get_annotations($entity_guid, "", "", $name, "", "", $limit, $offset, $asc);
+
+       return elgg_view_annotation_list($annotations, $count, $offset, $limit);
+}
+
+/**
+ * Return the sum of a given integer annotation.
+ *
+ * @param $entity_guid int
+ * @param $entity_type string
+ * @param $entity_subtype string
+ * @param $name string
+ */
+function get_annotations_sum($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0) {
+       return __get_annotations_calculate_x("sum", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+}
+
+/**
+ * Return the max of a given integer annotation.
+ *
+ * @param $entity_guid int
+ * @param $entity_type string
+ * @param $entity_subtype string
+ * @param $name string
+ */
+function get_annotations_max($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0) {
+       return __get_annotations_calculate_x("max", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+}
+
+/**
+ * Return the minumum of a given integer annotation.
+ *
+ * @param $entity_guid int
+ * @param $entity_type string
+ * @param $entity_subtype string
+ * @param $name string
+ */
+function get_annotations_min($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0) {
+       return __get_annotations_calculate_x("min", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+}
+
+/**
+ * Return the average of a given integer annotation.
+ *
+ * @param $entity_guid int
+ * @param $entity_type string
+ * @param $entity_subtype string
+ * @param $name string
+ */
+function get_annotations_avg($entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0) {
+       return __get_annotations_calculate_x("avg", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid);
+}
+
+/**
+ * Count the number of annotations based on search parameters
+ *
+ * @param int $entity_guid
+ * @param string $entity_type
+ * @param string $entity_subtype
+ * @param string $name
+ */
+function count_annotations($entity_guid = 0, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0, $timelower = 0, $timeupper = 0) {
+       return __get_annotations_calculate_x("count", $entity_guid, $entity_type, $entity_subtype, $name, $value, $value_type, $owner_guid, $timelower, $timeupper);
+}
+
+/**
+ * Perform a mathmatical calculation on integer annotations.
+ *
+ * @param $sum string
+ * @param $entity_id int
+ * @param $entity_type string
+ * @param $entity_subtype string
+ * @param $name string
+ */
+function __get_annotations_calculate_x($sum = "avg", $entity_guid, $entity_type = "", $entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0, $timelower = 0, $timeupper = 0) {
+       global $CONFIG;
+
+       $sum = sanitise_string($sum);
+       $entity_guid = (int)$entity_guid;
+       $entity_type = sanitise_string($entity_type);
+       $timeupper = (int)$timeupper;
+       $timelower = (int)$timelower;
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       if ($name != '' AND !$name = get_metastring_id($name)) {
+               return 0;
+       }
+
+       if ($value != '' AND !$value = get_metastring_id($value)) {
+               return 0;
+       }
+       $value_type = sanitise_string($value_type);
+       $owner_guid = (int)$owner_guid;
+
+       // if (empty($name)) return 0;
+
+       $where = array();
+
+       if ($entity_guid) {
+               $where[] = "e.guid=$entity_guid";
+       }
+
+       if ($entity_type!="") {
+               $where[] = "e.type='$entity_type'";
+       }
+
+       if ($entity_subtype) {
+               $where[] = "e.subtype=$entity_subtype";
+       }
+
+       if ($name!="") {
+               $where[] = "a.name_id='$name'";
+       }
+
+       if ($value!="") {
+               $where[] = "a.value_id='$value'";
+       }
+
+       if ($value_type!="") {
+               $where[] = "a.value_type='$value_type'";
+       }
+
+       if ($owner_guid) {
+               $where[] = "a.owner_guid='$owner_guid'";
+       }
+
+       if ($timelower) {
+               $where[] = "a.time_created >= {$timelower}";
+       }
+
+       if ($timeupper) {
+               $where[] = "a.time_created <= {$timeupper}";
+       }
+
+       if ($sum != "count") {
+               $where[] = "a.value_type='integer'"; // Limit on integer types
+       }
+
+       $query = "SELECT $sum(ms.string) as sum
+               FROM {$CONFIG->dbprefix}annotations a
+               JOIN {$CONFIG->dbprefix}entities e on a.entity_guid = e.guid
+               JOIN {$CONFIG->dbprefix}metastrings ms on a.value_id=ms.id WHERE ";
+
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+
+       $query .= get_access_sql_suffix("a"); // now add access
+       $query .= ' and ' . get_access_sql_suffix("e"); // now add access
+
+       $row = get_data_row($query);
+       if ($row) {
+               return $row->sum;
+       }
+
+       return false;
+}
+
+/**
+ * Get entities ordered by a mathematical calculation
+ *
+ * @param $sum string
+ * @param $entity_type string
+ * @param $entity_subtype string
+ * @param $name string
+ * @param $mdname string
+ * @param $mdvalue string
+ * @param $limit int
+ * @param string $orderdir Default: asc - the sort order
+ * @return unknown
+ */
+function __get_entities_from_annotations_calculate_x($sum = "sum", $entity_type = "", $entity_subtype = "", $name = "", $mdname = '', $mdvalue = '', $owner_guid = 0, $limit = 10, $offset = 0, $orderdir = 'desc', $count = false) {
+       global $CONFIG;
+
+       $sum = sanitise_string($sum);
+       $entity_type = sanitise_string($entity_type);
+       $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+       $name = get_metastring_id($name);
+       $limit = (int) $limit;
+       $offset = (int) $offset;
+       $owner_guid = (int) $owner_guid;
+       if (!empty($mdname) && !empty($mdvalue)) {
+               $meta_n = get_metastring_id($mdname);
+               $meta_v = get_metastring_id($mdvalue);
+       }
+
+       if (empty($name)) {
+               return 0;
+       }
+
+       $where = array();
+
+       if ($entity_type!="") {
+               $where[] = "e.type='$entity_type'";
+       }
+
+       if ($owner_guid > 0) {
+               $where[] = "e.container_guid = $owner_guid";
+       }
+
+       if ($entity_subtype) {
+               $where[] = "e.subtype=$entity_subtype";
+       }
+
+       if ($name!="") {
+               $where[] = "a.name_id='$name'";
+       }
+
+       if (!empty($mdname) && !empty($mdvalue)) {
+               if ($mdname!="") {
+                       $where[] = "m.name_id='$meta_n'";
                }
-               
-               $query .= " WHERE ";
-               foreach ($where as $w)
-                       $query .= " $w and ";
-               $query .= get_access_sql_suffix("a"); // now add access
-               $query .= ' and ' . get_access_sql_suffix("e"); // now add access
-               if (!$count) $query .= ' group by e.guid';
-               
-               if (!$count) {
-                       $query .= ' order by sum ' . $orderdir;
-                       $query .= ' limit ' . $offset . ' , ' . $limit;
-                       return get_data($query, "entity_row_to_elggstar");
-               } else {
-                       if ($row = get_data_row($query)) {
-                               return $row->num;
-                       }
+
+               if ($mdvalue!="") {
+                       $where[] = "m.value_id='$meta_v'";
                }
-               return false;
        }
 
-       /**
-        * Returns entities ordered by the sum of an annotation
-        *
-        * @param unknown_type $entity_type
-        * @param unknown_type $entity_subtype
-        * @param unknown_type $name
-        * @param string $mdname
-        * @param string $mdvalue
-        * @param unknown_type $owner_guid
-        * @param int $limit
-        * @param int $offset
-        * @param true|false $count
-        * @return unknown
-        */
-       function get_entities_from_annotation_count($entity_type = "", $entity_subtype = "", $name = "", $mdname = '', $mdvalue = '', $owner_guid = 0, $limit = 10, $offset = 0, $orderdir = 'desc', $count = false) {
-               return __get_entities_from_annotations_calculate_x('sum',$entity_type,$entity_subtype,$name,$mdname, $mdvalue, $owner_guid,$limit, $offset, $orderdir, $count);
+       if ($sum != "count") {
+               // Limit on integer types
+               $where[] = "a.value_type='integer'";
        }
 
-       /**
-        * Lists entities by the totals of a particular kind of annotation
-        *
-        * @param string $entity_type Type of entity.
-        * @param string $entity_subtype Subtype of entity.
-        * @param string $name Name of annotation.
-        * @param int $limit Maximum number of results to return.
-        * @param int $owner_guid Owner.
-        * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
-        * @param boolean $asc Whether to list in ascending or descending order (default: desc)
-        * @param boolean $fullview Whether to display the entities in full
-        * @param boolean $viewtypetoggle Determines whether or not the 'gallery' view can be displayed (default: no)
-        * @return string Formatted entity list
-        */
-       function list_entities_from_annotation_count($entity_type = "", $entity_subtype = "", $name = "", $limit = 10, $owner_guid = 0, $group_guid = 0, $asc = false, $fullview = true, $viewtypetoggle = false, $pagination = true, $orderdir = 'desc') {
-               
-               if ($asc) {
-                       $asc = "asc";
-               } else {
-                       $asc = "desc";
-               }
-               
-               $offset = (int) get_input("offset",0);
-               $count = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, '', '', $owner_guid, $limit, $offset, $orderdir, true); 
-               $entities = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, '', '', $owner_guid, $limit, $offset, $orderdir, false);
+       if (!$count) {
+               $query = "SELECT distinct e.*, $sum(ms.string) as sum ";
+       } else {
+               $query = "SELECT count(distinct e.guid) as num, $sum(ms.string) as sum ";
+       }
+       $query .= " from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}annotations a on a.entity_guid = e.guid JOIN {$CONFIG->dbprefix}metastrings ms on a.value_id=ms.id ";
 
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-               
+       if (!empty($mdname) && !empty($mdvalue)) {
+               $query .= " JOIN {$CONFIG->dbprefix}metadata m on m.entity_guid = e.guid ";
        }
-       
-       /**
-        * Lists entities by the totals of a particular kind of annotation AND the value of a piece of metadata
-        *
-        * @param string $entity_type Type of entity.
-        * @param string $entity_subtype Subtype of entity.
-        * @param string $name Name of annotation.
-        * @param string $mdname Metadata name
-        * @param string $mdvalue Metadata value
-        * @param int $limit Maximum number of results to return.
-        * @param int $owner_guid Owner.
-        * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
-        * @param boolean $asc Whether to list in ascending or descending order (default: desc)
-        * @param boolean $fullview Whether to display the entities in full
-        * @param boolean $viewtypetoggle Determines whether or not the 'gallery' view can be displayed (default: no)
-        * @return string Formatted entity list
-        */
-       function list_entities_from_annotation_count_by_metadata($entity_type = "", $entity_subtype = "", $name = "", $mdname = '', $mdvalue = '', $limit = 10, $owner_guid = 0, $group_guid = 0, $asc = false, $fullview = true, $viewtypetoggle = false, $pagination = true, $orderdir = 'desc') {
-               
-               if ($asc) {
-                       $asc = "asc";
-               } else {
-                       $asc = "desc";
+
+       $query .= " WHERE ";
+       foreach ($where as $w) {
+               $query .= " $w and ";
+       }
+
+       $query .= get_access_sql_suffix("a"); // now add access
+       $query .= ' and ' . get_access_sql_suffix("e"); // now add access
+       if (!$count) {
+               $query .= ' group by e.guid';
+       }
+
+       if (!$count) {
+               $query .= ' order by sum ' . $orderdir;
+               $query .= ' limit ' . $offset . ' , ' . $limit;
+               return get_data($query, "entity_row_to_elggstar");
+       } else {
+               if ($row = get_data_row($query)) {
+                       return $row->num;
                }
-               
-               $offset = (int) get_input("offset",0);
-               $count = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, $mdname, $mdvalue, $owner_guid, $limit, $offset, $orderdir, true); 
-               $entities = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, $mdname, $mdvalue, $owner_guid, $limit, $offset, $orderdir, false);
+       }
+       return false;
+}
 
-               return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
-               
+/**
+ * Returns entities ordered by the sum of an annotation
+ *
+ * @param unknown_type $entity_type
+ * @param unknown_type $entity_subtype
+ * @param unknown_type $name
+ * @param string $mdname
+ * @param string $mdvalue
+ * @param unknown_type $owner_guid
+ * @param int $limit
+ * @param int $offset
+ * @param true|false $count
+ * @return unknown
+ */
+function get_entities_from_annotation_count($entity_type = "", $entity_subtype = "", $name = "", $mdname = '', $mdvalue = '', $owner_guid = 0, $limit = 10, $offset = 0, $orderdir = 'desc', $count = false) {
+       return __get_entities_from_annotations_calculate_x('sum',$entity_type,$entity_subtype,$name,$mdname, $mdvalue, $owner_guid,$limit, $offset, $orderdir, $count);
+}
+
+/**
+ * Lists entities by the totals of a particular kind of annotation
+ *
+ * @param string $entity_type Type of entity.
+ * @param string $entity_subtype Subtype of entity.
+ * @param string $name Name of annotation.
+ * @param int $limit Maximum number of results to return.
+ * @param int $owner_guid Owner.
+ * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
+ * @param boolean $asc Whether to list in ascending or descending order (default: desc)
+ * @param boolean $fullview Whether to display the entities in full
+ * @param boolean $viewtypetoggle Determines whether or not the 'gallery' view can be displayed (default: no)
+ * @return string Formatted entity list
+ */
+function list_entities_from_annotation_count($entity_type = "", $entity_subtype = "", $name = "", $limit = 10, $owner_guid = 0, $group_guid = 0, $asc = false, $fullview = true, $viewtypetoggle = false, $pagination = true, $orderdir = 'desc') {
+       if ($asc) {
+               $asc = "asc";
+       } else {
+               $asc = "desc";
        }
-       
-       /**
-        * Delete a given annotation.
-        * 
-        * @param $id int The id
-        */
-       function delete_annotation($id)
-       {
-               global $CONFIG;
-
-               $id = (int)$id;
-               
-               $access = get_access_sql_suffix();
-               $annotation = get_annotation($id);
-               
-               if (trigger_elgg_event('delete', 'annotation', $annotation))
-                       return delete_data("DELETE from {$CONFIG->dbprefix}annotations  where id=$id and $access");
-                       
-               return false;
+
+       $offset = (int) get_input("offset",0);
+       $count = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, '', '', $owner_guid, $limit, $offset, $orderdir, true);
+       $entities = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, '', '', $owner_guid, $limit, $offset, $orderdir, false);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Lists entities by the totals of a particular kind of annotation AND the value of a piece of metadata
+ *
+ * @param string $entity_type Type of entity.
+ * @param string $entity_subtype Subtype of entity.
+ * @param string $name Name of annotation.
+ * @param string $mdname Metadata name
+ * @param string $mdvalue Metadata value
+ * @param int $limit Maximum number of results to return.
+ * @param int $owner_guid Owner.
+ * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object'
+ * @param boolean $asc Whether to list in ascending or descending order (default: desc)
+ * @param boolean $fullview Whether to display the entities in full
+ * @param boolean $viewtypetoggle Determines whether or not the 'gallery' view can be displayed (default: no)
+ * @return string Formatted entity list
+ */
+function list_entities_from_annotation_count_by_metadata($entity_type = "", $entity_subtype = "", $name = "", $mdname = '', $mdvalue = '', $limit = 10, $owner_guid = 0, $group_guid = 0, $asc = false, $fullview = true, $viewtypetoggle = false, $pagination = true, $orderdir = 'desc') {
+       if ($asc) {
+               $asc = "asc";
+       } else {
+               $asc = "desc";
        }
-       
-       /**
-        * Clear all the annotations for a given entity, assuming you have access to that metadata.
-        * 
-        * @param int $guid
-        */
-       function clear_annotations($guid, $name = "")
-       {
-               global $CONFIG;
-               
-               $guid = (int)$guid;
-               
-               if (!empty($name))
-                       $name = get_metastring_id($name);
-               
-               $entity_guid = (int) $guid;
-               if ($entity = get_entity($entity_guid)) {
-                       if ($entity->canEdit()) {
-               
-                               $where = array();
-                               
-                               if ($name != "")
-                                       $where[] = " name_id='$name'";
-                               
-                               $query = "DELETE from {$CONFIG->dbprefix}annotations where entity_guid=$guid "; 
-                               foreach ($where as $w)
-                                       $query .= " and $w";
-                               
-                               return delete_data($query);
-               
+
+       $offset = (int) get_input("offset",0);
+       $count = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, $mdname, $mdvalue, $owner_guid, $limit, $offset, $orderdir, true);
+       $entities = get_entities_from_annotation_count($entity_type, $entity_subtype, $name, $mdname, $mdvalue, $owner_guid, $limit, $offset, $orderdir, false);
+
+       return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
+}
+
+/**
+ * Delete a given annotation.
+ *
+ * @param $id int The id
+ */
+function delete_annotation($id) {
+       global $CONFIG;
+
+       $id = (int)$id;
+
+       $access = get_access_sql_suffix();
+       $annotation = get_annotation($id);
+
+       if (trigger_elgg_event('delete', 'annotation', $annotation)) {
+               return delete_data("DELETE from {$CONFIG->dbprefix}annotations  where id=$id and $access");
+       }
+
+       return false;
+}
+
+/**
+ * Clear all the annotations for a given entity, assuming you have access to that metadata.
+ *
+ * @param int $guid
+ */
+function clear_annotations($guid, $name = "") {
+       global $CONFIG;
+
+       $guid = (int)$guid;
+
+       if (!empty($name)) {
+               $name = get_metastring_id($name);
+       }
+
+       $entity_guid = (int) $guid;
+       if ($entity = get_entity($entity_guid)) {
+               if ($entity->canEdit()) {
+                       $where = array();
+
+                       if ($name != "") {
+                               $where[] = " name_id='$name'";
                        }
+
+                       $query = "DELETE from {$CONFIG->dbprefix}annotations where entity_guid=$guid ";
+                       foreach ($where as $w) {
+                               $query .= " and $w";
+                       }
+
+                       return delete_data($query);
                }
        }
-       
-       /**
-        * Clear all annotations belonging to a given owner_guid
-        *
-        * @param int $owner_guid The owner
-        */
-       function clear_annotations_by_owner($owner_guid)
-       {
-               global $CONFIG;
-               
-               $owner_guid = (int)$owner_guid;
-               
-               $annotations = get_data("SELECT id from {$CONFIG->dbprefix}annotations WHERE owner_guid=$owner_guid");
-               $deleted = 0;
-               
-               if (!$annotations)
-                       return 0;
-               
-               foreach ($annotations as $id)
-               {
-                       if (delete_annotation($id->id)) // Is this the best way?
-                               $deleted++;
-               }
-               
-               return $deleted;
+}
+
+/**
+ * Clear all annotations belonging to a given owner_guid
+ *
+ * @param int $owner_guid The owner
+ */
+function clear_annotations_by_owner($owner_guid) {
+       global $CONFIG;
+
+       $owner_guid = (int)$owner_guid;
+
+       $annotations = get_data("SELECT id from {$CONFIG->dbprefix}annotations WHERE owner_guid=$owner_guid");
+       $deleted = 0;
+
+       if (!$annotations) {
+               return 0;
        }
-       
-       /**
-        * Handler called by trigger_plugin_hook on the "export" event.
-        */
-       function export_annotation_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_annotations($guid); 
-                               
-               if ($result)
-               {
-                       foreach ($result as $r)
-                               $returnvalue[] = $r->export();
+
+       foreach ($annotations as $id) {
+               // Is this the best way?
+               if (delete_annotation($id->id)) {
+                       $deleted++;
                }
-               
-               return $returnvalue;
        }
-       
-       /**
-        * 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_annotation_url($id)
-       {
-               $id = (int)$id;
-               
-               if ($extender = get_annotation($id)) {
-                       return get_extender_url($extender);     
+
+       return $deleted;
+}
+
+/**
+ * Handler called by trigger_plugin_hook on the "export" event.
+ */
+function export_annotation_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_annotations($guid);
+
+       if ($result) {
+               foreach ($result as $r) {
+                       $returnvalue[] = $r->export();
                }
-               return false;
        }
-       
-       
-       /**
-        * Register an annotation url handler.
-        *
-        * @param string $function_name The function.
-        * @param string $extender_name The name, default 'all'.
-        */
-       function register_annotation_url_handler($function_name, $extender_name = "all") {
-               return register_extender_url_handler($function_name, 'annotation', $extender_name);
+
+       return $returnvalue;
+}
+
+/**
+ * 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_annotation_url($id) {
+       $id = (int)$id;
+
+       if ($extender = get_annotation($id)) {
+               return get_extender_url($extender);
        }
-       
-       /** Register the hook */
-       register_plugin_hook("export", "all", "export_annotation_plugin_hook", 2);
-?>
+       return false;
+}
+
+
+/**
+ * Register an annotation url handler.
+ *
+ * @param string $function_name The function.
+ * @param string $extender_name The name, default 'all'.
+ */
+function register_annotation_url_handler($function_name, $extender_name = "all") {
+       return register_extender_url_handler($function_name, 'annotation', $extender_name);
+}
+
+/** Register the hook */
+register_plugin_hook("export", "all", "export_annotation_plugin_hook", 2);
\ No newline at end of file