]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Refs #2907. DRY'd up and abstracted out a lot of metadata / annotation functions...
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sun, 13 Feb 2011 22:59:36 +0000 (22:59 +0000)
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sun, 13 Feb 2011 22:59:36 +0000 (22:59 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@8207 36083f99-b078-4883-b0ff-0f9b5a30f544

engine/classes/ElggAnnotation.php
engine/classes/ElggEntity.php
engine/classes/ElggMetadata.php
engine/lib/annotations.php
engine/lib/deprecated-1.8.php
engine/lib/elgglib.php
engine/lib/entities.php
engine/lib/metadata.php
engine/lib/metastrings.php
engine/tests/api/metastrings.php [new file with mode: 0644]

index 10f4269cf51e60769e780b8b4b37c8bae7e6281c..274cbb923d4a610612177709caca60c5f0612246 100644 (file)
@@ -78,7 +78,27 @@ class ElggAnnotation extends ElggExtender {
         * @return bool
         */
        function delete() {
-               return delete_annotation($this->id);
+               return elgg_delete_metastring_based_object_by_id($this->id, 'annotations');
+       }
+
+       /**
+        * Disable the annotation.
+        *
+        * @return bool
+        * @since 1.8
+        */
+       function disable() {
+               return elgg_set_metastring_based_object_enabled_by_id($this->id, 'no', 'annotations');
+       }
+
+       /**
+        * Enable the annotation.
+        *
+        * @return bool
+        * @since 1.8
+        */
+       function enable() {
+               return elgg_set_metastring_based_object_enabled_by_id($this->id, 'yes', 'annotations');
        }
 
        /**
index ea2a329d9e011aba0f6468ab90fa8673ecf4431d..4e1bc586c8f08ea6e037f9d3589dc4b9705f02f7 100644 (file)
@@ -292,9 +292,9 @@ abstract class ElggEntity extends ElggData implements
        public function setMetaData($name, $value, $value_type = "", $multiple = false) {
                if (is_array($value)) {
                        unset($this->temp_metadata[$name]);
-                       remove_metadata($this->getGUID(), $name);
                        foreach ($value as $v) {
                                if ((int) $this->guid > 0) {
+                                       elgg_delete_metadata(array('guid' => $this->guid, 'metadata_name' => $name));
                                        $multiple = true;
                                        if (!create_metadata($this->getGUID(), $name, $v, $value_type,
                                        $this->getOwnerGUID(), $this->getAccessID(), $multiple)) {
@@ -349,7 +349,7 @@ abstract class ElggEntity extends ElggData implements
         *
         * @return mixed bool
         */
-       public function clearMetaData($name = "") {
+       public function clearMetaData($name = '') {
                if (empty($name)) {
                        return clear_metadata($this->getGUID());
                } else {
@@ -357,7 +357,6 @@ abstract class ElggEntity extends ElggData implements
                }
        }
 
-
        /**
         * Get a piece of volatile (non-persisted) data on this entity.
         *
index 9c13e936ede5d3c44a0d97307b860cdada63ed5f..f85bac6ceeb0c5acfc75da3378a01dde3ecd8de9 100644 (file)
@@ -75,12 +75,32 @@ class ElggMetadata extends ElggExtender {
        }
 
        /**
-        * Delete a given metadata.
+        * Delete the metadata
         *
         * @return bool
         */
        function delete() {
-               return delete_metadata($this->id);
+               return elgg_delete_metastring_based_object_by_id($this->id, 'metadata');
+       }
+
+       /**
+        * Disable the metadata
+        *
+        * @return bool
+        * @since 1.8
+        */
+       function disable() {
+               return elgg_set_metastring_based_object_enabled_by_id($this->id, 'no', 'metadata');
+       }
+
+       /**
+        * Disable the metadata
+        *
+        * @return bool
+        * @since 1.8
+        */
+       function enable() {
+               return elgg_set_metastring_based_object_enabled_by_id($this->id, 'yes', 'metadata');
        }
 
        /**
index a148533596f72384f814b6c315ef29abe312e481..9b3b4962674c15cc1214c8a2d3ff00995ed69e87 100644 (file)
@@ -23,25 +23,16 @@ function row_to_elggannotation($row) {
 }
 
 /**
- * Get a specific annotation.
+ * Get a specific annotation by its id.
+ * If you want multiple annotation objects, use
+ * {@link elgg_get_annotations()}.
  *
- * @param int $annotation_id Annotation ID
+ * @param int $id The id of the annotation object being retrieved.
  *
- * @return ElggAnnotation
+ * @return false|ElggAnnotation
  */
-function get_annotation($annotation_id) {
-       global $CONFIG;
-
-       $annotation_id = (int) $annotation_id;
-       $access = get_access_sql_suffix("a");
-
-       $query = "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";
-
-       return row_to_elggannotation(get_data_row($query));
+function elgg_get_annotation_from_id($id) {
+       return elgg_get_metastring_based_object_by_id($id, 'annotations');
 }
 
 /**
@@ -195,29 +186,87 @@ function update_annotation($annotation_id, $name, $value, $value_type, $owner_gu
  * @since 1.8.0
  */
 function elgg_get_annotations(array $options = array()) {
-       // map the annotation_* options to metastring_* options
-       $map = array(
-               'annotation_names' => 'metastring_names',
-               'annotation_values' => 'metastring_values',
-               'annotation_case_sensitive' => 'metastring_case_sensitive',
-               'annotation_owner_guids' => 'metastring_owner_guids',
-               'annotation_created_time_lower' => 'metastring_created_time_lower',
-               'annotation_created_time_upper' => 'metastring_created_time_upper',
-               'annotation_calculation' => 'metastring_calculation'
-       );
+       $options['metastring_type'] = 'annotations';
+       return elgg_get_metastring_based_objects($options);
+}
 
-       $singulars = array('annotation_name', 'annotation_value');
-       $options = elgg_normalise_plural_options_array($options, $singulars);
+/**
+ * Deletes annotations based on $options.
+ *
+ * @warning Unlike elgg_get_annotations() this will not accept an empty options array!
+ *
+ * @param array $options An options array. {@See elgg_get_annotations()}
+ * @return mixed
+ * @since 1.8
+ */
+function elgg_delete_annotations(array $options) {
+       if (!$options || !is_array($options)) {
+               return false;
+       }
 
-       foreach ($map as $ann => $ms) {
-               if (isset($options[$ann])) {
-                       $options[$ms] = $options[$ann];
-               }
+       $options['metastring_type'] = 'annotations';
+       return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback');
+}
+
+/**
+ * Disables annotations based on $options.
+ *
+ * @warning Unlike elgg_get_annotations() this will not accept an empty options array!
+ *
+ * @param array $options An options array. {@See elgg_get_annotations()}
+ * @return mixed
+ * @since 1.8
+ */
+function elgg_disable_annotations(array $options) {
+       if (!$options || !is_array($options)) {
+               return false;
+       }
+
+       $options['metastrings_type'] = 'annotations';
+       return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback');
+}
+
+/**
+ * Enables annotations based on $options.
+ *
+ * @warning Unlike elgg_get_annotations() this will not accept an empty options array!
+ *
+ * @param array $options An options array. {@See elgg_get_annotations()}
+ * @return mixed
+ * @since 1.8
+ */
+function elgg_enable_annotations(array $options) {
+       if (!$options || !is_array($options)) {
+               return false;
        }
 
-       return elgg_get_metastring_based_objects($options, 'annotations');
+       $options['metastring_type'] = 'annotations';
+       return elgg_batch_metastring_based_objects($options, 'elgg_batch_enable_callback');
+}
+
+/**
+ * Returns a rendered list of annotations with pagination.
+ *
+ * @param array $options Annotation getter and display options.
+ * {@see elgg_get_annotations()} and {@see elgg_list_entities()}.
+ *
+ * @return string The list of entities
+ * @since 1.8
+ */
+function elgg_list_annotations($options) {
+       $defaults = array(
+               'limit' => 25,
+               'offset' => (int) max(get_input('annoff', 0), 0),
+       );
+
+       $options = array_merge($defaults, $options);
+
+       return elgg_list_entities($options, 'elgg_get_annotations', 'elgg_view_annotation_list');
 }
 
+/**
+ * Entities interfaces
+ */
 
 /**
  * Returns entities based upon annotations.  Accepts the same values as
@@ -254,6 +303,8 @@ function elgg_get_annotations(array $options = array()) {
  *
  *  annotation_owner_guids => NULL|ARR guids for annotaiton owners
  *
+ *  annotation_ids => NULL|ARR Annotation IDs
+ *
  * @return array
  * @since 1.7.0
  */
@@ -272,6 +323,8 @@ function elgg_get_entities_from_annotations(array $options = array()) {
 
                'annotation_owner_guids'                                =>      ELGG_ENTITIES_ANY_VALUE,
 
+               'annotation_ids'                                                =>      ELGG_ENTITIES_ANY_VALUE,
+
                'order_by'                                                              =>      'maxtime desc',
                'group_by'                                                              =>      'a.entity_guid'
        );
@@ -279,7 +332,7 @@ function elgg_get_entities_from_annotations(array $options = array()) {
        $options = array_merge($defaults, $options);
 
        $singulars = array('annotation_name', 'annotation_value',
-       'annotation_name_value_pair', 'annotation_owner_guid');
+       'annotation_name_value_pair', 'annotation_owner_guid', 'annotation_id');
 
        $options = elgg_normalise_plural_options_array($options, $singulars);
 
@@ -316,26 +369,6 @@ function elgg_list_entities_from_annotations($options = array()) {
        return elgg_list_entities($options, 'elgg_get_entities_from_annotations');
 }
 
-/**
- * Returns a rendered list of annotations with pagination.
- *
- * @param array $options Annotation getter and display options.
- * {@see elgg_get_annotations()} and {@see elgg_list_entities()}.
- *
- * @return string The list of entities
- * @since 1.8
- */
-function elgg_list_annotations($options) {
-       $defaults = array(
-               'limit' => 25,
-               'offset' => (int) max(get_input('annoff', 0), 0),
-       );
-
-       $options = array_merge($defaults, $options);
-
-       return elgg_list_entities($options, 'elgg_get_annotations', 'elgg_view_annotation_list');
-}
-
 /**
  * Get entities ordered by a mathematical calculation
  *
@@ -385,103 +418,6 @@ function elgg_list_entities_from_annotation_calculation($options) {
        return elgg_list_entities($options, 'elgg_get_entities_from_annotation_calculation');
 }
 
-
-/**
- * Delete a given annotation.
- *
- * @param int $id The annotation id
- *
- * @return bool
- */
-function delete_annotation($id) {
-       global $CONFIG;
-
-       $id = (int)$id;
-
-       $access = get_access_sql_suffix();
-       $annotation = get_annotation($id);
-
-       if (elgg_trigger_event('delete', 'annotation', $annotation)) {
-               remove_from_river_by_annotation($id);
-               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 The entity guid
- * @param string $name The name of the annotation to delete.
- *
- * @return int Number of annotations deleted or false if an error
- */
-function clear_annotations($guid, $name = "") {
-       global $CONFIG;
-
-       $guid = (int)$guid;
-
-       if (!empty($name)) {
-               $name = get_metastring_id($name);
-               if ($name === false) {
-                       // name doesn't exist so 0 rows were deleted
-                       return 0;
-               }
-       }
-
-       $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);
-               }
-       }
-
-       return FALSE;
-}
-
-/**
- * Clear all annotations belonging to a given owner_guid
- *
- * @param int $owner_guid The owner
- *
- * @return int Number of annotations deleted
- */
-function clear_annotations_by_owner($owner_guid) {
-       global $CONFIG;
-
-       $owner_guid = (int)$owner_guid;
-
-       $query = "SELECT id from {$CONFIG->dbprefix}annotations WHERE owner_guid=$owner_guid";
-
-       $annotations = get_data($query);
-       $deleted = 0;
-
-       if (!$annotations) {
-               return 0;
-       }
-
-       foreach ($annotations as $id) {
-               // Is this the best way?
-               if (delete_annotation($id->id)) {
-                       $deleted++;
-               }
-       }
-
-       return $deleted;
-}
-
 /**
  * Handler called by trigger_plugin_hook on the "export" event.
  *
index 9bca873c5da7533d91619c98285bfce2ce4bd06d..f86d946212538bdf32b4bccfd1def25f8f460721 100644 (file)
@@ -3534,7 +3534,6 @@ function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $en
        return elgg_get_metadata($options);
 }
 
-
 /**
  * Get metadata objects by name.
  *
@@ -3547,6 +3546,10 @@ function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $en
 function get_metadata_byname($entity_guid, $meta_name) {
        elgg_deprecated_notice('get_metadata_byname() is deprecated by elgg_get_metadata()', 1.8);
 
+       if (!$entity_guid || !$meta_name) {
+               return false;
+       }
+
        $options = array(
                'guid' => $entity_guid,
                'metadata_name' => $meta_name,
@@ -3573,6 +3576,10 @@ function get_metadata_byname($entity_guid, $meta_name) {
 function get_metadata_for_entity($entity_guid) {
        elgg_deprecated_notice('get_metadata_for_entity() is deprecated by elgg_get_metadata()', 1.8);
 
+       if (!$entity_guid) {
+               return false;
+       }
+
        $options = array(
                'guid' => $entity_guid,
                'limit' => 0
@@ -3590,5 +3597,165 @@ function get_metadata_for_entity($entity_guid) {
  * @deprecated 1.8 Use elgg_get_metadata_from_id()
  */
 function get_metadata($id) {
+       elgg_deprecated_notice('get_metadata() is deprecated by elgg_get_metadata_from_id()', 1.8);
        return elgg_get_metadata_from_id($id);
 }
+
+/**
+ * Clear all the metadata for a given entity, assuming you have access to that entity.
+ *
+ * @param int $guid Entity GUID
+ *
+ * @return bool
+ * @deprecated 1.8 Use elgg_delete_metadata()
+ */
+function clear_metadata($guid) {
+       elgg_deprecated_notice('clear_metadata() is deprecated by elgg_delete_metadata()', 1.8);
+       if (!$guid) {
+               return false;
+       }
+       return elgg_delete_metadata(array('guid' => $guid, 'limit' => 0));
+}
+
+/**
+ * Clear all metadata belonging to a given owner_guid
+ *
+ * @param int $owner_guid The owner
+ *
+ * @return bool
+ * @deprecated 1.8 Use elgg_delete_metadata()
+ */
+function clear_metadata_by_owner($owner_guid) {
+       elgg_deprecated_notice('clear_metadata() is deprecated by elgg_delete_metadata()', 1.8);
+       if (!$owner_guid) {
+               return false;
+       }
+       return elgg_delete_metadata(array('metadata_owner' => $owner_guid, 'limit' => 0));
+}
+
+/**
+ * Delete a piece of metadata, where the current user has access.
+ *
+ * @param int $id The id of metadata to delete.
+ *
+ * @return bool
+ * @deprecated 1.8 Use elgg_delete_metadata()
+ */
+function delete_metadata($id) {
+       elgg_deprecated_notice('delete_metadata() is deprecated by elgg_delete_metadata()', 1.8);
+       if (!$id) {
+               return false;
+       }
+       return elgg_delete_metadata(array('metadata_id' => $id));
+}
+
+/**
+ * Removes metadata on an entity with a particular name, optionally with a given value.
+ *
+ * @param int    $guid  The entity GUID
+ * @param string $name  The name of the metadata
+ * @param string $value The value of the metadata (useful to remove a single item of a set)
+ *
+ * @return bool Depending on success
+ * @deprecated 1.8 Use elgg_delete_metadata()
+ */
+function remove_metadata($guid, $name, $value = "") {
+       elgg_deprecated_notice('delete_metadata() is deprecated by elgg_delete_metadata()', 1.8);
+
+       // prevent them from deleting everything
+       if (!$guid) {
+               return false;
+       }
+
+       $options = array(
+               'guid' => $guid,
+               'metadata_name' => $name,
+               'limit' => 0
+       );
+
+       if ($value) {
+               $options['metadata_value'] = $value;
+       }
+
+       return elgg_delete_metadata($options);
+}
+
+/**
+ * Get a specific annotation.
+ *
+ * @param int $annotation_id Annotation ID
+ *
+ * @return ElggAnnotation
+ * @deprecated 1.8 Use elgg_get_annotation_from_id()
+ */
+function get_annotation($annotation_id) {
+       elgg_deprecated_notice('get_annotation() is deprecated by elgg_get_annotation_from_id()', 1.8);
+       return elgg_get_annotation_from_id($annotation_id);
+}
+
+/**
+ * Delete a given annotation.
+ *
+ * @param int $id The annotation id
+ *
+ * @return bool
+ * @deprecated 1.8 Use elgg_delete_annotations()
+ */
+function delete_annotation($id) {
+       elgg_deprecated_notice('delete_annotation() is deprecated by elgg_delete_annotations()', 1.8);
+       if (!$id) {
+               return false;
+       }
+       return elgg_delete_annotations(array('annotation_id' => $annotation_id));
+}
+
+/**
+ * Clear all the annotations for a given entity, assuming you have access to that metadata.
+ *
+ * @param int    $guid The entity guid
+ * @param string $name The name of the annotation to delete.
+ *
+ * @return int Number of annotations deleted or false if an error
+ * @deprecated 1.8 Use elgg_delete_annotations()
+ */
+function clear_annotations($guid, $name = "") {
+       elgg_deprecated_notice('clear_annotations() is deprecated by elgg_delete_annotations()', 1.8);
+
+       if (!$guid) {
+               return false;
+       }
+
+       $options = array(
+               'guid' => $guid,
+               'limit' => 0
+       );
+
+       if ($name) {
+               $options['annotation_name'] = $name;
+       }
+
+       return elgg_delete_annotations($options);
+}
+
+/**
+ * Clear all annotations belonging to a given owner_guid
+ *
+ * @param int $owner_guid The owner
+ *
+ * @return int Number of annotations deleted
+ * @deprecated 1.8 Use elgg_delete_annotations()
+ */
+function clear_annotations_by_owner($owner_guid) {
+       elgg_deprecated_notice('clear_annotations_by_owner() is deprecated by elgg_delete_annotations()', 1.8);
+
+       if (!$owner_guid) {
+               return false;
+       }
+
+       $options = array(
+               'annotation_owner_guid' => $guid,
+               'limit' => 0
+       );
+
+       return elgg_delete_annotations($options);
+}
index 7ebf918b78328545258b275abfe71d78f20647eb..a00b21c5289490a063c0c89657ded2cf799ac210 100644 (file)
@@ -1664,8 +1664,9 @@ function css_page_handler($page) {
  *
  * This is used mostly for elgg_get_entities() and other similar functions.
  *
- * @access private
  * @param string $order_by An order by clause
+ * @access private
+ * @return string
  */
 function elgg_sql_reverse_order_by_clause($order_by) {
        $order_by = strtolower($order_by);
@@ -1682,6 +1683,48 @@ function elgg_sql_reverse_order_by_clause($order_by) {
        return $return;
 }
 
+/**
+ * Enable objects with an enable() method.
+ *
+ * Used as a callback for ElggBatch.
+ *
+ * @param object $object The object to enable
+ * @access private
+ * @return bool
+ */
+function elgg_batch_enable_callback($object) {
+       // our db functions return the number of rows affected...
+       return $object->enable() ? true : false;
+}
+
+/**
+ * Disable objects with a disable() method.
+ *
+ * Used as a callback for ElggBatch.
+ *
+ * @param object $object The object to disable
+ * @access private
+ * @return bool
+ */
+function elgg_batch_disable_callback($object) {
+       // our db functions return the number of rows affected...
+       return $object->disable() ? true : false;
+}
+
+/**
+ * Delete objects with a delete() method.
+ *
+ * Used as a callback for ElggBatch.
+ *
+ * @param object $object The object to disable
+ * @access private
+ * @return bool
+ */
+function elgg_batch_delete_callback($object) {
+       // our db functions return the number of rows affected...
+       return $object->delete() ? true : false;
+}
+
 /**
  * Intercepts the index page when Walled Garden mode is enabled.
  *
index 781a744ad81ec2c1a61731b9ddc64b4750642357..4f58e96a8fc1d079e2a861cfeb11bf42d9d29633 100644 (file)
@@ -1345,6 +1345,17 @@ function disable_entity($guid, $reason = "", $recursive = true) {
                                                }
                                        }
 
+                                       // disable annotations
+                                       // Now delete the entity itself
+//                                     $entity->clearMetadata();
+//                                     $entity->clearAnnotations();
+//                                     $entity->clearRelationships();
+//
+//                                     $res = delete_data("DELETE from {$CONFIG->dbprefix}entities where guid={$guid}");
+//                                     if ($res) {
+//                                             $sub_table = "";
+//                                     }
+
                                        $__RECURSIVE_DELETE_TOKEN = null;
                                }
 
index 6724bcb7079b3d6feb9c760f57c22f7ef82cc184..8a62929d5856985af4800f7681322694cbd17e4d 100644 (file)
@@ -32,56 +32,7 @@ function row_to_elggmetadata($row) {
  * @return false|ElggMetadata
  */
 function elgg_get_metadata_from_id($id) {
-       $db_prefix = elgg_get_config('dbprefix');
-
-       $id = (int)$id;
-       $access = get_access_sql_suffix("e");
-       $md_access = get_access_sql_suffix("m");
-
-       $query = "SELECT m.*, n.string as name, v.string as value from {$db_prefix}metadata m"
-               . " JOIN {$db_prefix}entities e on e.guid = m.entity_guid"
-               . " JOIN {$db_prefix}metastrings v on m.value_id = v.id"
-               . " JOIN {$db_prefix}metastrings n on m.name_id = n.id"
-               . " where m.id=$id and $access and $md_access";
-
-       return row_to_elggmetadata(get_data_row($query));
-}
-
-/**
- * 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 value of the metadata (useful to remove a single item of a set)
- *
- * @return bool Depending on success
- */
-function remove_metadata($entity_guid, $name, $value = "") {
-       global $CONFIG;
-       $entity_guid = (int) $entity_guid;
-
-       $name_id = get_metastring_id($name);
-       if ($name_id === FALSE) {
-               // name doesn't exist
-               return FALSE;
-       }
-
-       $query = "SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = '$entity_guid' and name_id = '$name_id'";
-       if ($value != "") {
-               $value_id = get_metastring_id($value);
-               if ($value_id !== FALSE) {
-                       $query .= " AND value_id = '$value_id'";
-               }
-       }
-
-       if ($existing = get_data($query)) {
-               foreach ($existing as $ex) {
-                       delete_metadata($ex->id);
-               }
-               return true;
-       }
-
-       return false;
+       return elgg_get_metastring_based_object_by_id($id, 'metadata');
 }
 
 /**
@@ -290,38 +241,6 @@ $access_id = ACCESS_PRIVATE, $allow_multiple = false) {
        return true;
 }
 
-/**
- * Delete a piece of metadata, where the current user has access.
- *
- * @param int $id The id of metadata to delete.
- *
- * @return bool
- */
-function delete_metadata($id) {
-       global $CONFIG;
-
-       $id = (int)$id;
-       $metadata = elgg_get_metadata_from_id($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()) && (elgg_trigger_event('delete', 'metadata', $metadata))) {
-                       return delete_data("DELETE from {$CONFIG->dbprefix}metadata where id=$id");
-               }
-       }
-
-       return false;
-}
-
 /**
  * Returns metadata.  Accepts all elgg_get_entities() options for entity
  * restraints.
@@ -353,30 +272,69 @@ function delete_metadata($id) {
  * @return mixed
  * @since 1.8.0
  */
-function elgg_get_metadata($options) {
-       // map the metadata_* options to metastring_* options
-       $map = array(
-               'metadata_names' => 'metastring_names',
-               'metadata_values' => 'metastring_values',
-               'metadata_case_sensitive' => 'metastring_case_sensitive',
-               'metadata_owner_guids' => 'metastring_owner_guids',
-               'metadata_created_time_lower' => 'metastring_created_time_lower',
-               'metadata_created_time_upper' => 'metastring_created_time_upper',
-               'metadata_calculation' => 'metastring_calculation'
-       );
+function elgg_get_metadata(array $options = array()) {
+       $options['metastring_type'] = 'metadata';
+       return elgg_get_metastring_based_objects($options);
+}
 
-       $singulars = array('metadata_name', 'metadata_value');
-       $options = elgg_normalise_plural_options_array($options, $singulars);
+/**
+ * Deletes metadata based on $options.
+ *
+ * @warning Unlike elgg_get_metadata() this will not accept an empty options array!
+ *
+ * @param array $options An options array. {@See elgg_get_metadata()}
+ * @return mixed
+ * @since 1.8
+ */
+function elgg_delete_metadata(array $options) {
+       if (!$options || !is_array($options)) {
+               return false;
+       }
 
-       foreach ($map as $ann => $ms) {
-               if (isset($options[$ann])) {
-                       $options[$ms] = $options[$ann];
-               }
+       $options['metastring_type'] = 'metadata';
+       return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback');
+}
+
+/**
+ * Disables metadata based on $options.
+ *
+ * @warning Unlike elgg_get_metadata() this will not accept an empty options array!
+ *
+ * @param array $options An options array. {@See elgg_get_metadata()}
+ * @return mixed
+ * @since 1.8
+ */
+function elgg_disable_metadata(array $options) {
+       if (!$options || !is_array($options)) {
+               return false;
        }
 
-       return elgg_get_metastring_based_objects($options, 'metadata');
+       $options['metastrings_type'] = 'metadata';
+       return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback');
 }
 
+/**
+ * Enables metadata based on $options.
+ *
+ * @warning Unlike elgg_get_metadata() this will not accept an empty options array!
+ *
+ * @param array $options An options array. {@See elgg_get_metadata()}
+ * @return mixed
+ * @since 1.8
+ */
+function elgg_enable_metadata(array $options) {
+       if (!$options || !is_array($options)) {
+               return false;
+       }
+
+       $options['metastring_type'] = 'metadata';
+       return elgg_batch_metastring_based_objects($options, 'elgg_batch_enable_callback');
+}
+
+/**
+ * ElggEntities interfaces
+ */
+
 /**
  * Returns entities based upon metadata.  Also accepts all
  * options available to elgg_get_entities().  Supports
@@ -452,66 +410,6 @@ function elgg_get_entities_from_metadata(array $options = array()) {
        return elgg_get_entities($options);
 }
 
-/**
- * Returns options to pass to elgg_get_entities() for metastrings operations.
- *
- * @param string $type    Metastring type: annotations or metadata
- * @param array  $options Options
- *
- * @return array
- * @since 1.7.0
- */
-function elgg_entities_get_metastrings_options($type, $options) {
-       $valid_types = array('metadata', 'annotation');
-       if (!in_array($type, $valid_types)) {
-               return FALSE;
-       }
-
-       // the options for annotations are singular (annotation_name) but the table
-       // is plural (elgg_annotations) so rewrite for the table name.
-       $n_table = ($type == 'annotation') ? 'annotations' : $type;
-
-       $singulars = array("{$type}_name", "{$type}_value",
-               "{$type}_name_value_pair", "{$type}_owner_guid");
-       $options = elgg_normalise_plural_options_array($options, $singulars);
-
-       $clauses = elgg_get_entity_metadata_where_sql('e', $n_table, $options["{$type}_names"],
-               $options["{$type}_values"], $options["{$type}_name_value_pairs"],
-               $options["{$type}_name_value_pairs_operator"], $options["{$type}_case_sensitive"],
-               $options["order_by_{$type}"], $options["{$type}_owner_guids"]);
-
-       if ($clauses) {
-               // merge wheres to pass to get_entities()
-               if (isset($options['wheres']) && !is_array($options['wheres'])) {
-                       $options['wheres'] = array($options['wheres']);
-               } elseif (!isset($options['wheres'])) {
-                       $options['wheres'] = array();
-               }
-
-               $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']);
-
-               // merge joins to pass to get_entities()
-               if (isset($options['joins']) && !is_array($options['joins'])) {
-                       $options['joins'] = array($options['joins']);
-               } elseif (!isset($options['joins'])) {
-                       $options['joins'] = array();
-               }
-
-               $options['joins'] = array_merge($options['joins'], $clauses['joins']);
-
-               if ($clauses['orders']) {
-                       $order_by_metadata = implode(", ", $clauses['orders']);
-                       if (isset($options['order_by']) && $options['order_by']) {
-                               $options['order_by'] = "$order_by_metadata, {$options['order_by']}";
-                       } else {
-                               $options['order_by'] = "$order_by_metadata, e.time_created DESC";
-                       }
-               }
-       }
-
-       return $options;
-}
-
 /**
  * Returns metadata name and value SQL where for entities.
  * NB: $names and $values are not paired. Use $pairs for this.
@@ -789,50 +687,8 @@ function elgg_list_entities_from_metadata($options) {
 }
 
 /**
- * Clear all the metadata for a given entity, assuming you have access to that metadata.
- *
- * @param int $entity_guid Entity GUID
- *
- * @return bool
+ * Other functions
  */
-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;
-}
-
-/**
- * Clear all annotations belonging to a given owner_guid
- *
- * @param int $owner_guid The owner
- *
- * @return bool
- */
-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;
-
-       if (is_array($metas)) {
-               foreach ($metas as $id) {
-                       // Is this the best way?
-                       if (delete_metadata($id->id)) {
-                               $deleted++;
-                       }
-               }
-       }
-
-       return $deleted;
-}
 
 /**
  * Handler called by trigger_plugin_hook on the "export" event.
@@ -983,10 +839,10 @@ function is_metadata_independent($type, $subtype) {
 function metadata_update($event, $object_type, $object) {
        if ($object instanceof ElggEntity) {
                if (!is_metadata_independent($object->getType(), $object->getSubtype())) {
-                       global $CONFIG;
+                       $db_prefix = elgg_get_config('dbprefix');
                        $access_id = (int) $object->access_id;
                        $guid = (int) $object->getGUID();
-                       $query = "update {$CONFIG->dbprefix}metadata set access_id = {$access_id} where entity_guid = {$guid}";
+                       $query = "update {$db_prefix}metadata set access_id = {$access_id} where entity_guid = {$guid}";
                        update_data($query);
                }
        }
@@ -1028,4 +884,4 @@ function metadata_test($hook, $type, $value, $params) {
        global $CONFIG;
        $value[] = $CONFIG->path . 'engine/tests/objects/metadata.php';
        return $value;
-}
+}
\ No newline at end of file
index 23724b979bd9525021cbeb74aaf0b2a90350213b..bcb15c338c3fe996f38999bad3a0735d81edf28b 100644 (file)
@@ -15,6 +15,8 @@ $METASTRINGS_CACHE = array();
 global $METASTRINGS_DEADNAME_CACHE;
 $METASTRINGS_DEADNAME_CACHE = array();
 
+
+
 /**
  * Return the meta string id for a given tag, or false.
  *
@@ -201,14 +203,13 @@ function delete_orphaned_metastrings() {
        return delete_data($query);
 }
 
-
 /**
  * Returns an array of either ElggAnnotation or ElggMetadata objects.
  * Accepts all elgg_get_entities() options for entity restraints.
  *
  * @see elgg_get_entities
  *
- * @param array  $options Array in format:
+ * @param array $options Array in format:
  *
  *     metastring_names => NULL|ARR metastring names
  *
@@ -224,16 +225,35 @@ function delete_orphaned_metastrings() {
  *
  *  metastring_calculation => STR Perform the MySQL function on the metastring values returned.
  *
- * @param string $type    Either metadata or annotations
+ *  metastring_type => STR metadata or annotation(s)
+ *
  * @return mixed
  * @access private
  */
-function elgg_get_metastring_based_objects($options, $type = 'metadata') {
+function elgg_get_metastring_based_objects($options) {
 
-       if ($type != 'metadata' && $type != 'annotations') {
+       if (!isset($options['metastring_type'])) {
                return false;
        }
 
+       switch ($options['metastring_type']) {
+               case 'metadata':
+                       $type = 'metadata';
+                       $callback = 'row_to_elggmetadata';
+                       break;
+
+               case 'annotations':
+               case 'annotation':
+                       $type = 'annotations';
+                       $callback = 'row_to_elggannotation';
+                       break;
+
+               default:
+                       return false;
+       }
+
+       $options = elgg_normalize_metastrings_options($options);
+
        $defaults = array(
                // entities
                'types'                                 =>      ELGG_ENTITIES_ANY_VALUE,
@@ -265,6 +285,8 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
 
                'metastring_owner_guids'                                        =>      ELGG_ENTITIES_ANY_VALUE,
 
+               'metastring_ids'                                                        =>      ELGG_ENTITIES_ANY_VALUE,
+
                // sql
                'order_by'      =>      'n_table.time_created asc',
                'limit'         =>      10,
@@ -274,9 +296,12 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
                'wheres'        =>      array(),
                'joins'         =>      array(),
 
-               'callback'      => ($type == 'annotations') ? 'row_to_elggannotation' : 'row_to_elggmetadata'
+               'callback'      => $callback
        );
 
+       // @todo Ignore site_guid right now because of #2910
+       $options['site_guid'] = ELGG_ENTITIES_ANY_VALUE;
+
        $options = array_merge($defaults, $options);
 
        // can't use helper function with type_subtype_pair because
@@ -291,7 +316,7 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
        }
 
        $singulars = array('type', 'subtype', 'guid', 'owner_guid', 'container_guid', 'site_guid',
-                                               'metastring_name', 'metastring_value'
+                                               'metastring_name', 'metastring_value', 'metastring_id'
                                        );
        $options = elgg_normalise_plural_options_array($options, $singulars);
 
@@ -324,7 +349,8 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
        $wheres[] = elgg_get_entity_time_where_sql('n_table', $options['metastring_created_time_upper'],
                $options['metastring_created_time_lower'], null, null);
 
-       $wheres[] = elgg_get_guid_based_where_sql('n_table.owner_guid', $options['metastring_owner_guids']);
+       $wheres[] = elgg_get_guid_based_where_sql('n_table.owner_guid',
+               $options['metastring_owner_guids']);
 
        // remove identical where clauses
        $wheres = array_unique($wheres);
@@ -364,7 +390,8 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
 
        // metastrings
        $metastring_clauses = elgg_get_metastring_sql('n_table', $options['metastring_names'],
-               $options['metastring_values'], $options['metastring_case_sensitive']);
+               $options['metastring_values'], null, $options['metastring_ids'],
+               $options['metastring_case_sensitive']);
 
        if ($metastring_clauses) {
                $wheres = array_merge($wheres, $metastring_clauses['wheres']);
@@ -377,9 +404,11 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
        }
 
        if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) {
-               $query = "SELECT DISTINCT n_table.*, n.string as name, v.string as value FROM {$db_prefix}$type n_table";
+               $query = "SELECT DISTINCT n_table.*, n.string as name,
+                       v.string as value FROM {$db_prefix}$type n_table";
        } else {
-               $query = "SELECT DISTINCT v.string as value, {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table";
+               $query = "SELECT DISTINCT v.string as value,
+                       {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table";
        }
 
        // add joins
@@ -399,7 +428,8 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
 
        // reverse order by
        if ($options['reverse_order_by']) {
-               $options['order_by'] = elgg_sql_reverse_order_by_clause($options['order_by'], $defaults['order_by']);
+               $options['order_by'] = elgg_sql_reverse_order_by_clause($options['order_by'],
+                       $defaults['order_by']);
        }
 
        if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) {
@@ -425,7 +455,6 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
        }
 }
 
-
 /**
  * Returns an array of joins and wheres for use in metastrings.
  *
@@ -435,15 +464,17 @@ function elgg_get_metastring_based_objects($options, $type = 'metadata') {
  * @param array  $names          An array of names
  * @param array  $values         An array of values
  * @param array  $pairs          Name / value pairs. Not currently used.
+ * @param array  $ids            Metastring IDs
  * @param bool   $case_sensitive Should name and values be case sensitive?
  *
  * @return array
  */
 function elgg_get_metastring_sql($table, $names = null, $values = null,
-       $pairs = null, $case_sensitive = false) {
+       $pairs = null, $ids = null, $case_sensitive = false) {
 
        if ((!$names && $names !== 0)
                && (!$values && $values !== 0)
+               && !$ids
                && (!$pairs && $pairs !== 0)) {
 
                return '';
@@ -512,6 +543,18 @@ function elgg_get_metastring_sql($table, $names = null, $values = null,
                }
        }
 
+       if ($ids !== NULL) {
+               if (!is_array($ids)) {
+                       $ids = array($ids);
+               }
+
+               $ids_str = implode(',', $ids);
+
+               if ($ids_str) {
+                       $wheres[] = "n_table.id IN ($ids_str)";
+               }
+       }
+
        if ($names_where && $values_where) {
                $wheres[] = "($names_where AND $values_where AND $access)";
        } elseif ($names_where) {
@@ -526,3 +569,355 @@ function elgg_get_metastring_sql($table, $names = null, $values = null,
 
        return $return;
 }
+
+/**
+ * Normalizes metadata / annotation option names to their
+ * corresponding metastrings name.
+ *
+ * @param array $options An options array
+ * @since 1.8
+ * @access private
+ * @return array
+ */
+function elgg_normalize_metastrings_options(array $options = array()) {
+       $prefixes = array('metadata_', 'annotation_');
+
+       // map the metadata_* options to metastring_* options
+       $map = array(
+               'names'                                 =>      'metastring_names',
+               'values'                                =>      'metastring_values',
+               'case_sensitive'                =>      'metastring_case_sensitive',
+               'owner_guids'                   =>      'metastring_owner_guids',
+               'created_time_lower'    =>      'metastring_created_time_lower',
+               'created_time_upper'    =>      'metastring_created_time_upper',
+               'calculation'                   =>      'metastring_calculation'
+       );
+
+       foreach ($prefixes as $prefix) {
+               $singulars = array("{$prefix}name", "{$prefix}value", "{$prefix}owner_guid");
+               $options = elgg_normalise_plural_options_array($options, $singulars);
+
+               foreach ($map as $specific => $normalized) {
+                       $key = $prefix . $specific;
+                       if (isset($options[$key])) {
+                               $options[$normalized] = $options[$key];
+                       }
+               }
+       }
+
+       return $options;
+}
+
+/**
+ * Enables or disables a metastrings-based object by its id.
+ *
+ * @warning To enable disabled metastrings you must first use
+ * {@link access_show_hidden_entities()}.
+ *
+ * @param int    $id      The object's ID
+ * @param string $enabled Value to set to: yes or no
+ * @param string $type    The type of table to use: metadata or anntations
+ *
+ * @return bool
+ * @since 1.8
+ * @access private
+ */
+function elgg_set_metastring_based_object_enabled_by_id($id, $enabled, $type) {
+       $id = (int)$id;
+       $db_prefix = elgg_get_config('dbprefix');
+
+       $object = elgg_get_metastring_based_object_by_id($id, $type);
+
+       switch($type) {
+               case 'annotation':
+               case 'annotations':
+                       $table = "{$db_prefix}annotations";
+                       break;
+
+               case 'metadata':
+                       $table = "{$db_prefix}metadata";
+                       break;
+       }
+
+       if ($enabled === 'yes' || $enabled === 1 || $enabled === true) {
+               $enabled = 'yes';
+               $event = 'enable';
+       } elseif ($enabled === 'no' || $enabled === 0 || $enabled === false) {
+               $enabled = 'no';
+               $event = 'disable';
+       } else {
+               return false;
+       }
+
+       $return = false;
+
+       if ($object) {
+               // don't set it if it's already set.
+               if ($object->enabled == $enabled) {
+                       $return = false;
+               } elseif ($object->canEdit() && (elgg_trigger_event($event, $type, $object))) {
+                       $return = update_data("UPDATE $table SET enabled = '$enabled' where id = $id");
+               }
+       }
+
+       return $return;
+}
+
+/**
+ * Enables or disables a metastrings-based objects by their entity_guid.
+ *
+ * @param int    $guid    The object's ID
+ * @param string $enabled Value to set to: yes or no
+ * @param string $type    The type of table to use: metadata or anntations
+ * @param string $name    Optional metastring name. If not set, affects all metadata.
+ *
+ * @return bool
+ */
+function elgg_set_metastring_based_object_enabled_by_guid($guid, $enabled, $type, $name = null) {
+       $valid_types = array('annotations', 'annotation', 'metadata');
+       $guid = (int)$guid;
+       $entity = get_entity($guid);
+
+       if (!in_array($type, $valid_types)) {
+               return false;
+       }
+
+       if (!$entity || !$entity->canEdit()) {
+               return false;
+       }
+
+       switch($enabled) {
+               case true:
+               case 1:
+               case 'yes':
+                       $callback = 'elgg_batch_enable_callback';
+                       break;
+
+               case false:
+               case 0:
+               case 'no':
+                       $callback = 'elgg_batch_disable_callback';
+                       break;
+       }
+
+       $ashe = access_get_show_hidden_status();
+       access_show_hidden_entities(true);
+
+       switch($type) {
+               case 'annotation':
+               case 'annotations':
+                       $getter = 'elgg_get_annotations';
+                       if ($name) {
+                               $options['annotation_name'] = $name;
+                       }
+                       break;
+
+               case 'metadata':
+                       $getter = 'elgg_get_metadata';
+                       if ($name) {
+                               $options['metadata_name'] = $name;
+                       }
+                       break;
+       }
+
+       $options = array(
+               'guid' => $guid,
+               'limit' => 0
+       );
+
+       $batch = new ElggBatch('elgg_get_metadata', $options, 'elgg_batch_disable_callback');
+       $r = $batch->callbackResult;
+
+       access_show_hidden_entities($ashe);
+
+       return $r;
+}
+
+/**
+ * Runs metastrings-based objects found using $options through $callback
+ *
+ * @warning Unlike elgg_get_metastring_based_objects() this will not accept an
+ * empty options array!
+ *
+ * @param array  $options  An options array. {@See elgg_get_metastring_based_objects()}
+ * @param string $callback The callback to pass each result through
+ * @return mixed
+ * @access private
+ * @since 1.8
+ */
+function elgg_batch_metastring_based_objects(array $options, $callback) {
+       if (!$options || !is_array($options)) {
+               return false;
+       }
+
+       $batch = new ElggBatch('elgg_get_metastring_based_objects', $options, $callback);
+       $r = $batch->callbackResult;
+
+       return $r;
+}
+
+/**
+ * Returns a singular metastring-based object by its ID.
+ *
+ * @param int    $id   The metastring-based object's ID
+ * @param string $type The type: annotation or metadata
+ * @return mixed
+ *
+ * @since 1.8
+ * @access private
+ */
+function elgg_get_metastring_based_object_by_id($id, $type) {
+       $id = (int)$id;
+       if (!$id) {
+               return false;
+       }
+
+       $options = array(
+               'metastring_type' => $type,
+               'metastring_id' => $id
+       );
+
+       $obj = elgg_get_metastring_based_objects($options);
+
+       if ($obj && count($obj) == 1) {
+               return $obj[0];
+       }
+
+       return false;
+}
+
+/**
+ * Deletes a metastring-based object by its id
+ *
+ * @param int    $id   The object's ID
+ * @param string $type The object's metastring type: annotation or metadata
+ * @return bool
+ *
+ * @since 1.8
+ * @access private
+ */
+function elgg_delete_metastring_based_object_by_id($id, $type) {
+       $id = (int)$id;
+       $db_prefix = elgg_get_config('dbprefix');
+
+       switch ($type) {
+               case 'annotation':
+               case 'annotations':
+                       $type = 'annotations';
+                       break;
+
+               case 'metadata':
+                       $type = 'metadata';
+                       break;
+
+               default:
+                       return false;
+       }
+
+       $obj = elgg_get_metastring_based_object_by_id($id, $type);
+       $table = $db_prefix . $type;
+
+       if ($obj) {
+               // Tidy up if memcache is enabled.
+               // @todo only metadata is supported
+               if ($type == 'metadata') {
+                       static $metabyname_memcache;
+                       if ((!$metabyname_memcache) && (is_memcache_available())) {
+                               $metabyname_memcache = new ElggMemcache('metabyname_memcache');
+                       }
+
+                       if ($metabyname_memcache) {
+                               $metabyname_memcache->delete("{$obj->entity_guid}:{$obj->name_id}");
+                       }
+               }
+
+               if (($obj->canEdit()) && (elgg_trigger_event('delete', $type, $obj))) {
+                       return delete_data("DELETE from $table where id=$id");
+               }
+       }
+
+       return false;
+}
+
+/**
+ * Entities interface helpers
+ */
+
+/**
+ * Returns options to pass to elgg_get_entities() for metastrings operations.
+ *
+ * @param string $type    Metastring type: annotations or metadata
+ * @param array  $options Options
+ *
+ * @return array
+ * @since 1.7.0
+ */
+function elgg_entities_get_metastrings_options($type, $options) {
+       $valid_types = array('metadata', 'annotation');
+       if (!in_array($type, $valid_types)) {
+               return FALSE;
+       }
+
+       // the options for annotations are singular (annotation_name) but the table
+       // is plural (elgg_annotations) so rewrite for the table name.
+       $n_table = ($type == 'annotation') ? 'annotations' : $type;
+
+       $singulars = array("{$type}_name", "{$type}_value",
+               "{$type}_name_value_pair", "{$type}_owner_guid");
+       $options = elgg_normalise_plural_options_array($options, $singulars);
+
+       $clauses = elgg_get_entity_metadata_where_sql('e', $n_table, $options["{$type}_names"],
+               $options["{$type}_values"], $options["{$type}_name_value_pairs"],
+               $options["{$type}_name_value_pairs_operator"], $options["{$type}_case_sensitive"],
+               $options["order_by_{$type}"], $options["{$type}_owner_guids"]);
+
+       if ($clauses) {
+               // merge wheres to pass to get_entities()
+               if (isset($options['wheres']) && !is_array($options['wheres'])) {
+                       $options['wheres'] = array($options['wheres']);
+               } elseif (!isset($options['wheres'])) {
+                       $options['wheres'] = array();
+               }
+
+               $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']);
+
+               // merge joins to pass to get_entities()
+               if (isset($options['joins']) && !is_array($options['joins'])) {
+                       $options['joins'] = array($options['joins']);
+               } elseif (!isset($options['joins'])) {
+                       $options['joins'] = array();
+               }
+
+               $options['joins'] = array_merge($options['joins'], $clauses['joins']);
+
+               if ($clauses['orders']) {
+                       $order_by_metadata = implode(", ", $clauses['orders']);
+                       if (isset($options['order_by']) && $options['order_by']) {
+                               $options['order_by'] = "$order_by_metadata, {$options['order_by']}";
+                       } else {
+                               $options['order_by'] = "$order_by_metadata, e.time_created DESC";
+                       }
+               }
+       }
+
+       return $options;
+}
+
+// unit testing
+elgg_register_plugin_hook_handler('unit_test', 'system', 'metastrings_test');
+
+/**
+ * Metadata unit test
+ *
+ * @param string $hook   unit_test
+ * @param string $type   system
+ * @param mixed  $value  Array of other tests
+ * @param mixed  $params Params
+ *
+ * @return array
+ */
+function metastrings_test($hook, $type, $value, $params) {
+       global $CONFIG;
+       $value[] = $CONFIG->path . 'engine/tests/api/metastrings.php';
+       return $value;
+}
diff --git a/engine/tests/api/metastrings.php b/engine/tests/api/metastrings.php
new file mode 100644 (file)
index 0000000..c18e42e
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Elgg Metastrings test
+ *
+ * @package Elgg.Core
+ * @subpackage Metastrings.Test
+ */
+class ElggCoreMetastringsTest extends ElggCoreUnitTest {
+
+       public $metastringTypes = array('metadata', 'annotations');
+
+       /**
+        * Called before each test object.
+        */
+       public function __construct() {
+               parent::__construct();
+
+               $this->metastrings = array();
+               $this->object = new ElggObject();
+               $this->object->save();
+       }
+
+       public function createAnnotations($max = 1) {
+               $annotations = array();
+               for ($i=0; $i<$max; $i++) {
+                       $name = 'test_annotation_name' . rand();
+                       $value = 'test_annotation_value' . rand();
+                       $id = create_annotation($this->object->guid, $name, $value);
+                       $annotations[] = $id;
+               }
+
+               return $annotations;
+       }
+
+       public function createMetadata($max = 1) {
+               $metadata = array();
+               for ($i=0; $i<$max; $i++) {
+                       $name = 'test_metadata_name' . rand();
+                       $value = 'test_metadata_value' . rand();
+                       $id = create_metadata($this->object->guid, $name, $value);
+                       $metadata[] = $id;
+               }
+
+               return $metadata;
+       }
+
+       /**
+        * Called before each test method.
+        */
+       public function setUp() {
+
+       }
+
+       /**
+        * Called after each test method.
+        */
+       public function tearDown() {
+               // do not allow SimpleTest to interpret Elgg notices as exceptions
+               $this->swallowErrors();
+       }
+
+       /**
+        * Called after each test object.
+        */
+       public function __destruct() {
+               $this->object->delete();
+
+               parent::__destruct();
+       }
+
+       /**
+        * A basic test that will be called and fail.
+        */
+       public function testDeleteByID() {
+               $db_prefix = elgg_get_config('dbprefix');
+               $annotations = $this->createAnnotations(1);
+               $metadata = $this->createMetadata(1);
+
+               foreach ($this->metastringTypes as $type) {
+                       $id = ${$type}[0];
+                       $table = $db_prefix . $type;
+                       $q = "SELECT * FROM $table WHERE id = $id";
+                       $test = get_data($q);
+
+                       $this->assertEqual($test[0]->id, $id);
+                       $this->assertTrue(elgg_delete_metastring_based_object_by_id($id, $type));
+                       $this->assertFalse(get_data($q));
+               }
+       }
+
+       public function testGetMetastringObjectByID() {
+               $db_prefix = elgg_get_config('dbprefix');
+               $annotations = $this->createAnnotations(1);
+               $metadata = $this->createMetadata(1);
+
+               foreach ($this->metastringTypes as $type) {
+                       $id = ${$type}[0];
+                       $test = elgg_get_metastring_based_object_by_id($id, $type);
+
+                       $this->assertEqual($id, $test->id);
+               }
+       }
+
+       /**
+        * A basic test that will be called and fail.
+        */
+       public function testEnableDisableByID() {
+               $db_prefix = elgg_get_config('dbprefix');
+               $annotations = $this->createAnnotations(1);
+               $metadata = $this->createMetadata(1);
+
+               foreach ($this->metastringTypes as $type) {
+                       $id = ${$type}[0];
+                       $table = $db_prefix . $type;
+                       $q = "SELECT * FROM $table WHERE id = $id";
+                       $test = get_data($q);
+
+                       // disable
+                       $this->assertEqual($test[0]->enabled, 'yes');
+                       $this->assertTrue(elgg_set_metastring_based_object_enabled_by_id($id, 'no', $type));
+
+                       $test = get_data($q);
+                       $this->assertEqual($test[0]->enabled, 'no');
+
+                       // enable
+                       $ashe = access_get_show_hidden_status();
+                       access_show_hidden_entities(true);
+                       flush();
+                       $this->assertTrue(elgg_set_metastring_based_object_enabled_by_id($id, 'yes', $type));
+
+                       $test = get_data($q);
+                       $this->assertEqual($test[0]->enabled, 'yes');
+
+                       access_show_hidden_entities($ashe);
+               }
+       }
+
+
+}