]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Refs #2165 added elgg_get_entities_from_private_settings()
authorcash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 18 Nov 2010 02:08:05 +0000 (02:08 +0000)
committercash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 18 Nov 2010 02:08:05 +0000 (02:08 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@7335 36083f99-b078-4883-b0ff-0f9b5a30f544

engine/lib/private_settings.php
engine/tests/api/entity_getter_functions.php

index 3f6a10e3d05d7a49b197abaacf23ea56a0854980..0d86b93a156a4ac60e4b8515a668c669ef7bffcc 100644 (file)
  * @param mixed   $container_guid The container(s) GUIDs
  *
  * @return array A list of entities.
- * @todo deprecate
+ * @deprecated 1.8
  */
 function get_entities_from_private_setting($name = "", $value = "", $type = "", $subtype = "",
 $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0,
 $container_guid = null) {
+       elgg_deprecated_notice('get_entities_from_private_setting() was deprecated by elgg_get_entities_from_private_setting()!', 1.8);
 
-       global $CONFIG;
-
-       if ($subtype === false || $subtype === null || $subtype === 0) {
-               return false;
-       }
-
-       $name = sanitise_string($name);
-       $value = sanitise_string($value);
+       $options = array();
 
-       if ($order_by == "") {
-               $order_by = "e.time_created desc";
-       }
-       $order_by = sanitise_string($order_by);
-       $limit = (int)$limit;
-       $offset = (int)$offset;
-       $site_guid = (int) $site_guid;
-       if ($site_guid == 0) {
-               $site_guid = $CONFIG->site_guid;
-       }
+       $options['private_setting_name'] = $name;
+       $options['private_setting_value'] = $value;
 
-       $where = array();
-
-       if (is_array($type)) {
-               $tempwhere = "";
-               if (sizeof($type)) {
-                       foreach ($type as $typekey => $subtypearray) {
-                               foreach ($subtypearray as $subtypeval) {
-                                       $typekey = sanitise_string($typekey);
-                                       if (!empty($subtypeval)) {
-                                               if (!$subtypeval = (int) get_subtype_id($typekey, $subtypeval)) {
-                                                       return false;
-                                               }
-                                       } else {
-                                               $subtypeval = 0;
-                                       }
-                                       if (!empty($tempwhere)) {
-                                               $tempwhere .= " or ";
-                                       }
-                                       $tempwhere .= "(e.type = '{$typekey}' and e.subtype = {$subtypeval})";
-                               }
-                       }
-               }
-               if (!empty($tempwhere)) {
-                       $where[] = "({$tempwhere})";
-               }
-       } else {
-               $type = sanitise_string($type);
-               if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) {
-                       return false;
+       // set container_guid to owner_guid to emulate old functionality
+       if ($owner_guid != "") {
+               if (is_null($container_guid)) {
+                       $container_guid = $owner_guid;
                }
+       }
 
-               if ($type != "") {
-                       $where[] = "e.type='$type'";
-               }
-               if ($subtype !== "") {
-                       $where[] = "e.subtype=$subtype";
-               }
+       if ($type) {
+               $options['types'] = $type;
        }
 
-       if ($owner_guid != "") {
-               if (!is_array($owner_guid)) {
-                       $owner_array = array($owner_guid);
-                       $owner_guid = (int) $owner_guid;
-               } else if (sizeof($owner_guid) > 0) {
-                       $owner_array = array_map('sanitise_int', $owner_guid);
-               }
-               if (is_null($container_guid)) {
-                       $container_guid = $owner_array;
-               }
+       if ($subtype) {
+               $options['subtypes'] = $subtype;
        }
 
-       if ($site_guid > 0) {
-               $where[] = "e.site_guid = {$site_guid}";
+       if ($owner_guid) {
+               if (is_array($owner_guid)) {
+                       $options['owner_guids'] = $owner_guid;
+               } else {
+                       $options['owner_guid'] = $owner_guid;
+               }
        }
 
-       if (!is_null($container_guid)) {
+       if ($container_guid) {
                if (is_array($container_guid)) {
-                       foreach ($container_guid as $key => $val) {
-                               $container_guid[$key] = (int) $val;
-                       }
-                       $where[] = "e.container_guid in (" . implode(",", $container_guid) . ")";
+                       $options['container_guids'] = $container_guid;
                } else {
-                       $container_guid = (int) $container_guid;
-                       $where[] = "e.container_guid = {$container_guid}";
+                       $options['container_guid'] = $container_guid;
                }
        }
 
-       if ($name != "") {
-               $where[] = "s.name = '$name'";
-       }
+       $options['limit'] = $limit;
 
-       if ($value != "") {
-               $where[] = "s.value='$value'";
+       if ($offset) {
+               $options['offset'] = $offset;
        }
 
-       if (!$count) {
-               $query = "SELECT distinct e.*
-                       from {$CONFIG->dbprefix}entities e
-                       JOIN {$CONFIG->dbprefix}private_settings s ON e.guid=s.entity_guid where ";
-       } else {
-               $query = "SELECT count(distinct e.guid) as total
-                       from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}private_settings s
-                       ON e.guid=s.entity_guid where ";
+       if ($order_by) {
+               $options['order_by'];
        }
-       foreach ($where as $w) {
-               $query .= " $w and ";
+
+       if ($site_guid) {
+               $options['site_guid'];
        }
-       // Add access controls
-       $query .= get_access_sql_suffix('e');
-       if (!$count) {
-               $query .= " order by $order_by";
-               if ($limit) {
-                       // Add order and limit
-                       $query .= " limit $offset, $limit";
-               }
 
-               $dt = get_data($query, "entity_row_to_elggstar");
-               return $dt;
-       } else {
-               $total = get_data_row($query);
-               return $total->total;
+       if ($count) {
+               $options['count'] = $count;
        }
+
+       return elgg_get_entities_from_private_settings($options);
 }
 
 /**
@@ -169,137 +103,310 @@ $container_guid = null) {
  * @param mixed  $container_guid Container GUID
  *
  * @return array A list of entities.
- * @todo deprecate
+ * @deprecated 1.8
  */
 function get_entities_from_private_setting_multi(array $name, $type = "", $subtype = "",
 $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false,
 $site_guid = 0, $container_guid = null) {
 
-       global $CONFIG;
+       elgg_deprecated_notice('get_entities_from_private_setting_multi() was deprecated by elgg_get_entities_from_private_setting()!', 1.8);
+
+       $options = array();
 
-       if ($subtype === false || $subtype === null || $subtype === 0) {
-               return false;
+       $pairs = array();
+       foreach ($name as $setting_name => $setting_value) {
+               $pairs[] = array('name' => $setting_name, 'value' => $setting_value);
        }
+       $options['private_setting_name_value_pairs'] = $pairs;
 
-       if ($order_by == "") {
-               $order_by = "e.time_created desc";
+       // set container_guid to owner_guid to emulate old functionality
+       if ($owner_guid != "") {
+               if (is_null($container_guid)) {
+                       $container_guid = $owner_guid;
+               }
        }
-       $order_by = sanitise_string($order_by);
-       $limit = (int)$limit;
-       $offset = (int)$offset;
-       $site_guid = (int) $site_guid;
-       if ($site_guid == 0) {
-               $site_guid = $CONFIG->site_guid;
+
+       if ($type) {
+               $options['types'] = $type;
        }
 
-       $where = array();
-
-       if (is_array($type)) {
-               $tempwhere = "";
-               if (sizeof($type)) {
-                       foreach ($type as $typekey => $subtypearray) {
-                               foreach ($subtypearray as $subtypeval) {
-                                       $typekey = sanitise_string($typekey);
-                                       if (!empty($subtypeval)) {
-                                               if (!$subtypeval = (int) get_subtype_id($typekey, $subtypeval)) {
-                                                       return false;
-                                               }
-                                       } else {
-                                               $subtypeval = 0;
-                                       }
-                                       if (!empty($tempwhere)) {
-                                               $tempwhere .= " or ";
-                                       }
-                                       $tempwhere .= "(e.type = '{$typekey}' and e.subtype = {$subtypeval})";
-                               }
-                       }
-               }
-               if (!empty($tempwhere)) {
-                       $where[] = "({$tempwhere})";
+       if ($subtype) {
+               $options['subtypes'] = $subtype;
+       }
+
+       if ($owner_guid) {
+               if (is_array($owner_guid)) {
+                       $options['owner_guids'] = $owner_guid;
+               } else {
+                       $options['owner_guid'] = $owner_guid;
                }
+       }
 
-       } else {
-               $type = sanitise_string($type);
-               if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) {
-                       return false;
+       if ($container_guid) {
+               if (is_array($container_guid)) {
+                       $options['container_guids'] = $container_guid;
+               } else {
+                       $options['container_guid'] = $container_guid;
                }
+       }
+
+       $options['limit'] = $limit;
+
+       if ($offset) {
+               $options['offset'] = $offset;
+       }
+
+       if ($order_by) {
+               $options['order_by'];
+       }
 
-               if ($type != "") {
-                       $where[] = "e.type='$type'";
+       if ($site_guid) {
+               $options['site_guid'];
+       }
+
+       if ($count) {
+               $options['count'] = $count;
+       }
+
+       return elgg_get_entities_from_private_settings($options);
+}
+
+/**
+ * Returns entities based upon private settings.  Also accepts all
+ * options available to elgg_get_entities().  Supports
+ * the singular option shortcut.
+ *
+ * @see elgg_get_entities
+ *
+ * @param array $options Array in format:
+ *
+ *     private_setting_names => NULL|ARR private setting names
+ *
+ *     private_setting_values => NULL|ARR metadata values
+ *
+ *     private_setting_name_value_pairs => NULL|ARR (
+ *                                         name => 'name',
+ *                                         value => 'value',
+ *                                         'operand' => '=',
+ *                                        )
+ *                                  Currently if multiple values are sent via
+ *                               an array (value => array('value1', 'value2')
+ *                               the pair's operand will be forced to "IN".
+ *
+ *     private_setting_name_value_pairs_operator => NULL|STR The operator to use for combining
+ *                                        (name = value) OPERATOR (name = value); default AND
+ *
+ *
+ * @return array
+ * @since 1.8.0
+ */
+function elgg_get_entities_from_private_settings(array $options = array()) {
+       $defaults = array(
+               'private_setting_names'                     =>  ELGG_ENTITIES_ANY_VALUE,
+               'private_setting_values'                    =>  ELGG_ENTITIES_ANY_VALUE,
+               'private_setting_name_value_pairs'          =>  ELGG_ENTITIES_ANY_VALUE,
+               'private_setting_name_value_pairs_operator' => 'AND',
+       );
+
+       $options = array_merge($defaults, $options);
+
+       $singulars = array('private_setting_name', 'private_setting_value',
+               'private_setting_name_value_pair');
+
+       $options = elgg_normalise_plural_options_array($options, $singulars);
+
+       $clauses = elgg_get_entity_private_settings_where_sql('e', $options['private_setting_names'],
+               $options['private_setting_values'], $options['private_setting_name_value_pairs'],
+               $options['private_setting_name_value_pairs_operator']);
+
+       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();
                }
 
-               if ($subtype !== "") {
-                       $where[] = "e.subtype=$subtype";
+               $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 ($owner_guid != "") {
-               if (!is_array($owner_guid)) {
-                       $owner_array = array($owner_guid);
-                       $owner_guid = (int) $owner_guid;
-               } else if (sizeof($owner_guid) > 0) {
-                       $owner_array = array_map('sanitise_int', $owner_guid);
+       return elgg_get_entities($options);
+}
+
+/**
+ * Returns private setting name and value SQL where/join clauses for entities.
+ *
+ * @param string     $table         Entities table name
+ * @param array|null $names         Array of names
+ * @param array|null $values        Array of values
+ * @param array|null $pairs         Array of names / values / operands
+ * @param string     $pair_operator Operator for joining pairs where clauses
+ * @return array
+ * @since 1.8.0
+ */
+function elgg_get_entity_private_settings_where_sql($table, $names = NULL, $values = NULL,
+$pairs = NULL, $pair_operator = 'AND') {
+
+       global $CONFIG;
+
+       // @todo short circuit test
+
+       $return = array (
+               'joins' => array (),
+               'wheres' => array(),
+       );
+
+       $return['joins'][] = "JOIN {$CONFIG->dbprefix}private_settings ps on
+               {$table}.guid = ps.entity_guid";
+
+       $wheres = array();
+
+       // get names wheres
+       $names_where = '';
+       if ($names !== NULL) {
+               if (!is_array($names)) {
+                       $names = array($names);
                }
-               if (is_null($container_guid)) {
-                       $container_guid = $owner_array;
+
+               $sanitised_names = array();
+               foreach ($names as $name) {
+                       $sanitised_names[] = '\'' . sanitise_string($name) . '\'';
+               }
+
+               $names_str = implode(',', $sanitised_names);
+               if ($names_str) {
+                       $names_where = "(ps.name IN ($names_str))";
                }
-       }
-       if ($site_guid > 0) {
-               $where[] = "e.site_guid = {$site_guid}";
        }
 
-       if (!is_null($container_guid)) {
-               if (is_array($container_guid)) {
-                       foreach ($container_guid as $key => $val) {
-                               $container_guid[$key] = (int) $val;
+       // get values wheres
+       $values_where = '';
+       if ($values !== NULL) {
+               if (!is_array($values)) {
+                       $values = array($values);
+               }
+
+               $sanitised_values = array();
+               foreach ($values as $value) {
+                       // normalize to 0
+                       if (!$value) {
+                               $value = 0;
                        }
-                       $where[] = "e.container_guid in (" . implode(",", $container_guid) . ")";
-               } else {
-                       $container_guid = (int) $container_guid;
-                       $where[] = "e.container_guid = {$container_guid}";
+                       $sanitised_values[] = '\'' . sanitise_string($value) . '\'';
                }
-       }
 
-       if ($name) {
-               $s_join = "";
-               $i = 1;
-               foreach ($name as $k => $n) {
-                       $k = sanitise_string($k);
-                       $n = sanitise_string($n);
-                       $s_join .= " JOIN {$CONFIG->dbprefix}private_settings s$i ON e.guid=s$i.entity_guid";
-                       $where[] = "s$i.name = '$k'";
-                       $where[] = "s$i.value = '$n'";
-                       $i++;
+               $values_str = implode(',', $sanitised_values);
+               if ($values_str) {
+                       $values_where = "(ps.value IN ($values_str))";
                }
        }
 
-       if (!$count) {
-               $query = "SELECT distinct e.* from {$CONFIG->dbprefix}entities e $s_join where ";
-       } else {
-               $query = "SELECT count(distinct e.guid) as total
-               from {$CONFIG->dbprefix}entities e $s_join where ";
+       if ($names_where && $values_where) {
+               $wheres[] = "($names_where AND $values_where)";
+       } elseif ($names_where) {
+               $wheres[] = "($names_where)";
+       } elseif ($values_where) {
+               $wheres[] = "($values_where)";
        }
 
-       foreach ($where as $w) {
-               $query .= " $w and ";
-       }
+       // add pairs which must be in arrays.
+       if (is_array($pairs)) {
+               // join counter for incremental joins in pairs
+               $i = 1;
+               
+               // check if this is an array of pairs or just a single pair.
+               if (isset($pairs['name']) || isset($pairs['value'])) {
+                       $pairs = array($pairs);
+               }
+
+               $pair_wheres = array();
+
+               foreach ($pairs as $index => $pair) {
+                       // @todo move this elsewhere?
+                       // support shortcut 'n' => 'v' method.
+                       if (!is_array($pair)) {
+                               $pair = array(
+                                       'name' => $index,
+                                       'value' => $pair
+                               );
+                       }
+
+                       // must have at least a name and value
+                       if (!isset($pair['name']) || !isset($pair['value'])) {
+                               // @todo should probably return false.
+                               continue;
+                       }
+
+                       if (isset($pair['operand'])) {
+                               $operand = sanitise_string($pair['operand']);
+                       } else {
+                               $operand = ' = ';
+                       }
+
+                       // for comparing
+                       $trimmed_operand = trim(strtolower($operand));
 
-       // Add access controls
-       $query .= get_access_sql_suffix('e');
+                       // if the value is an int, don't quote it because str '15' < str '5'
+                       // if the operand is IN don't quote it because quoting should be done already.
+                       if (is_numeric($pair['value'])) {
+                               $value = sanitise_string($pair['value']);
+                       } else if (is_array($pair['value'])) {
+                               $values_array = array();
 
-       if (!$count) {
-               $query .= " order by $order_by";
-               // Add order and limit
-               if ($limit) {
-                       $query .= " limit $offset, $limit";
+                               foreach ($pair['value'] as $pair_value) {
+                                       if (is_numeric($pair_value)) {
+                                               $values_array[] = sanitise_string($pair_value);
+                                       } else {
+                                               $values_array[] = "'" . sanitise_string($pair_value) . "'";
+                                       }
+                               }
+
+                               if ($values_array) {
+                                       $value = '(' . implode(', ', $values_array) . ')';
+                               }
+
+                               // @todo allow support for non IN operands with array of values.
+                               // will have to do more silly joins.
+                               $operand = 'IN';
+                       } else if ($trimmed_operand == 'in') {
+                               $value = "({$pair['value']})";
+                       } else {
+                               $value = "'" . sanitise_string($pair['value']) . "'";
+                       }
+
+                       $name = sanitise_string($pair['name']);
+
+                       // @todo The multiple joins are only needed when the operator is AND
+                       $return['joins'][] = "JOIN {$CONFIG->dbprefix}private_settings ps{$i}
+                               on {$table}.guid = ps{$i}.entity_guid";
+
+                       $pair_wheres[] = "(ps{$i}.name = '$name' AND ps{$i}.value
+                               $operand $value)";
+
+                       $i++;
                }
 
-               $dt = get_data($query, "entity_row_to_elggstar");
-               return $dt;
-       } else {
-               $total = get_data_row($query);
-               return $total->total;
+               $where = implode (" $pair_operator ", $pair_wheres);
+               if ($where) {
+                       $wheres[] = "($where)";
+               }
+       }
+
+       $where = implode(' AND ', $wheres);
+       if ($where) {
+               $return['wheres'][] = "($where)";
        }
+       
+       return $return;
 }
 
 /**
index ce14bd4ee6f1da12b7c8c1cbe6f34bb7e36b52a7..07fb1fd8c5c29dc6b236c280269f9455f9cb9607 100644 (file)
@@ -2361,4 +2361,89 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest {
                        get_entity($guid)->delete();
                }
        }
+
+       /**
+        * Private settings
+        */
+       public function testElggApiGettersEntitiesFromPrivateSettings() {
+
+               // create some test private settings
+               $setting_name = 'test_setting_name_' . rand();
+               $setting_value = rand(1000, 9999);
+               $setting_name2 = 'test_setting_name_' . rand();
+               $setting_value2 = rand(1000, 9999);
+               
+               $subtypes = $this->getRandomValidSubtypes(array('object'), 1);
+               $subtype = $subtypes[0];
+               $guids = array();
+
+               // our targets
+               $valid = new ElggObject();
+               $valid->subtype = $subtype;
+               $valid->save();
+               $guids[] = $valid->getGUID();
+               set_private_setting($valid->getGUID(), $setting_name, $setting_value);
+               set_private_setting($valid->getGUID(), $setting_name2, $setting_value2);
+
+               $valid2 = new ElggObject();
+               $valid2->subtype = $subtype;
+               $valid2->save();
+               $guids[] = $valid2->getGUID();
+               set_private_setting($valid2->getGUID(), $setting_name, $setting_value);
+               set_private_setting($valid2->getGUID(), $setting_name2, $setting_value2);
+
+               // simple test with name
+               $options = array(
+                       'private_setting_name' => $setting_name
+               );
+
+               $entities = elgg_get_entities_from_private_settings($options);
+
+               foreach ($entities as $entity) {
+                       $this->assertTrue(in_array($entity->getGUID(), $guids));
+                       $value = get_private_setting($entity->getGUID(), $setting_name);
+                       $this->assertEqual($value, $setting_value);
+               }
+
+               // simple test with value
+               $options = array(
+                       'private_setting_value' => $setting_value
+               );
+
+               $entities = elgg_get_entities_from_private_settings($options);
+
+               foreach ($entities as $entity) {
+                       $this->assertTrue(in_array($entity->getGUID(), $guids));
+                       $value = get_private_setting($entity->getGUID(), $setting_name);
+                       $this->assertEqual($value, $setting_value);
+               }
+
+               // test pairs
+               $options = array(
+                       'type' => 'object',
+                       'subtype' => $subtype,
+                       'private_setting_name_value_pairs' => array(
+                               array(
+                                       'name' => $setting_name,
+                                       'value' => $setting_value
+                               ),
+                               array(
+                                       'name' => $setting_name2,
+                                       'value' => $setting_value2
+                               )
+                       )
+               );
+               
+               $entities = elgg_get_entities_from_private_settings($options);
+               $this->assertEqual(2, count($entities));
+               foreach ($entities as $entity) {
+                       $this->assertTrue(in_array($entity->getGUID(), $guids));
+               }
+
+               foreach ($guids as $guid) {
+                       if ($e = get_entity($guid)) {
+                               $e->delete();
+                       }
+               }
+       }
 }