]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Fixes #1542: Pulled in Kevin's patch to add ability to sort by metadata. Added unit...
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Wed, 24 Feb 2010 02:20:15 +0000 (02:20 +0000)
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Wed, 24 Feb 2010 02:20:15 +0000 (02:20 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@3970 36083f99-b078-4883-b0ff-0f9b5a30f544

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

index 67a135d75bfb8269c58dab0c83512d05d2d1a4dc..1795116c0f1610b3d06ba75951b61854d01f3dff 100644 (file)
@@ -569,7 +569,8 @@ function elgg_get_entities_from_metadata(array $options = array()) {
                'metadata_name_value_pairs'     =>      ELGG_ENTITIES_ANY_VALUE,
 
                'metadata_name_value_pairs_operator' => 'AND',
-               'metadata_case_sensitive' => TRUE
+               'metadata_case_sensitive' => TRUE,
+               'order_by_metadata' => array(),
        );
 
        $options = array_merge($defaults, $options);
@@ -578,7 +579,8 @@ function elgg_get_entities_from_metadata(array $options = array()) {
        $options = elgg_normalise_plural_options_array($options, $singulars);
 
        $clauses = elgg_get_entity_metadata_where_sql('e', $options['metadata_names'], $options['metadata_values'],
-               $options['metadata_name_value_pairs'], $options['metadata_name_value_pairs_operator'], $options['metadata_case_sensitive']);
+               $options['metadata_name_value_pairs'], $options['metadata_name_value_pairs_operator'], $options['metadata_case_sensitive'],
+               $options['order_by_metadata']);
 
        if ($clauses) {
                // merge wheres to pass to get_entities()
@@ -598,6 +600,15 @@ function elgg_get_entities_from_metadata(array $options = 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 elgg_get_entities($options);
@@ -614,9 +625,10 @@ function elgg_get_entities_from_metadata(array $options = array()) {
  * @param ARR|NULL $pairs array of names / values / operands
  * @param AND|OR $pair_operator Operator to use to join the where clauses for pairs
  * @param BOOL $case_sensitive
+ * @param ARR|NULL $order_by_metadata array of names / direction
  * @return FALSE|array False on fail, array('joins', 'wheres')
  */
-function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NULL, $pairs = NULL, $pair_operator = 'AND', $case_sensitive = TRUE) {
+function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NULL, $pairs = NULL, $pair_operator = 'AND', $case_sensitive = TRUE, $order_by_metadata = NULL) {
        global $CONFIG;
 
        // short circuit if nothing requested
@@ -624,7 +636,8 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL
        // 0 is also a valid metadata value for FALSE, NULL, or 0
        if ((!$names && $names !== 0)
                && (!$values && $values !== 0)
-               && (!$pairs && $pairs !== 0)) {
+               && (!$pairs && $pairs !== 0)
+               && !isset($order_by_metadata)) {
                return '';
        }
 
@@ -637,7 +650,8 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL
 
        $return = array (
                'joins' => array (),
-               'wheres' => array()
+               'wheres' => array(),
+               'orders' => array()
        );
 
        $wheres = array();
@@ -697,6 +711,8 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL
                $wheres[] = "($values_where AND $access)";
        }
 
+       $i = 1;
+
        // add pairs
        // pairs must be in arrays.
        if (is_array($pairs)) {
@@ -709,7 +725,7 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL
 
                // @todo when the pairs are > 3 should probably split the query up to
                // denormalize the strings table.
-               $i = 1;
+
                foreach ($pairs as $index => $pair) {
                        // @todo move this elsewhere?
                        // support shortcut 'n' => 'v' method.
@@ -789,6 +805,36 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL
                $return['wheres'][] = "($where)";
        }
 
+       if (is_array($order_by_metadata)) {
+               if ((count($order_by_metadata) > 0) && !is_array($order_by_metadata[0])) {
+                       // singleton, so fix
+                       $order_by_metadata = array($order_by_metadata);
+               }
+               foreach ($order_by_metadata as $order_by) {
+                       if (is_array($order_by) && isset($order_by['name'])) {
+                               $name = sanitise_string($order_by['name']);
+                               if (isset($order_by['direction'])) {
+                                       $direction = sanitise_string($order_by['direction']);
+                               } else {
+                                       $direction = 'ASC';
+                               }
+                               $return['joins'][] = "JOIN {$CONFIG->dbprefix}metadata md{$i} on {$table}.guid = md{$i}.entity_guid";
+                               $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn{$i} on md{$i}.name_id = msn{$i}.id";
+                               $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv{$i} on md{$i}.value_id = msv{$i}.id";
+
+                               $access = get_access_sql_suffix("md{$i}");
+
+                               $return['wheres'][] = "(msn{$i}.string = '$name' AND $access)";
+                               if (isset($order_by['as']) && $order_by['as'] == 'integer') {
+                                       $return['orders'][] = "CAST(msv{$i}.string AS SIGNED) $direction";
+                               } else {
+                                       $return['orders'][] = "msv{$i}.string $direction";
+                               }
+                               $i++;
+                       }
+               }
+       }
+
        return $return;
 }
 
index 04fa3e4e5f08e64783e5fb2775aeb341b1364e41..49fd4ec0df5af11a7dfb059581504ee88370d2ad 100644 (file)
@@ -1610,4 +1610,124 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest {
                        }
                }
        }
+
+       function testElggApiGettersEntityMetadataNVPOrderByMDText() {
+               $subtypes = $this->getRandomValidSubtypes(array('object'), 1);
+               $subtype = $subtypes[0];
+               $md_name = 'test_metadata_name_' . rand();
+               $md_value = 2;
+               $guids = array();
+               $valid_guids = array();
+
+               // our targets
+               $valid = new ElggObject();
+               $valid->subtype = $subtype;
+               $valid->$md_name = $md_value;
+               $valid->save();
+               $guids[] = $valid->getGUID();
+               $valid_guids[] = $valid->getGUID();
+
+               $valid2 = new ElggObject();
+               $valid2->subtype = $subtype;
+               $valid2->$md_name = 3;
+               $valid2->save();
+               $guids[] = $valid->getGUID();
+               $valid_guids[] = $valid2->getGUID();
+
+               $valid3 = new ElggObject();
+               $valid3->subtype = $subtype;
+               $valid3->$md_name = 1;
+               $valid3->save();
+               $guids[] = $valid->getGUID();
+               $valid_guids[] = $valid3->getGUID();
+
+               $md_valid_values = array($md_value, $md_value2);
+
+               $options = array(
+                       'type' => 'object',
+                       'subtype' => $subtype,
+                       //'metadata_name' => $md_name,
+                       'order_by_metadata' => array('name' => $md_name, 'as' => 'integer')
+               );
+
+               $entities = elgg_get_entities_from_metadata($options);
+
+               $this->assertIsa($entities, 'array');
+               $this->assertEqual(count($entities), 3);
+
+               $i = 1;
+               foreach ($entities as $entity) {
+                       $this->assertTrue(in_array($entity->getGUID(), $valid_guids));
+                       $this->assertEqual($entity->$md_name, $i);
+                       $i++;
+                       $entity->delete();
+               }
+
+               foreach ($guids as $guid) {
+                       if ($e = get_entity($guid)) {
+                               $e->delete();
+                       }
+               }
+       }
+
+       function testElggApiGettersEntityMetadataNVPOrderByMDString() {
+               $subtypes = $this->getRandomValidSubtypes(array('object'), 1);
+               $subtype = $subtypes[0];
+               $md_name = 'test_metadata_name_' . rand();
+               $md_value = 'b';
+               $guids = array();
+               $valid_guids = array();
+
+               // our targets
+               $valid = new ElggObject();
+               $valid->subtype = $subtype;
+               $valid->$md_name = $md_value;
+               $valid->save();
+               $guids[] = $valid->getGUID();
+               $valid_guids[] = $valid->getGUID();
+
+               $valid2 = new ElggObject();
+               $valid2->subtype = $subtype;
+               $valid2->$md_name = 'c';
+               $valid2->save();
+               $guids[] = $valid->getGUID();
+               $valid_guids[] = $valid2->getGUID();
+
+               $valid3 = new ElggObject();
+               $valid3->subtype = $subtype;
+               $valid3->$md_name = 'a';
+               $valid3->save();
+               $guids[] = $valid->getGUID();
+               $valid_guids[] = $valid3->getGUID();
+
+               $md_valid_values = array($md_value, $md_value2);
+
+               $options = array(
+                       'type' => 'object',
+                       'subtype' => $subtype,
+                       'metadata_name' => $md_name,
+                       'order_by_metadata' => array('name' => $md_name, 'as' => 'text')
+               );
+
+               $entities = elgg_get_entities_from_metadata($options);
+
+               $this->assertIsa($entities, 'array');
+               $this->assertEqual(count($entities), 3);
+
+               $alpha = array('a', 'b', 'c');
+
+               $i = 0;
+               foreach ($entities as $entity) {
+                       $this->assertTrue(in_array($entity->getGUID(), $valid_guids));
+                       $this->assertEqual($entity->$md_name, $alpha[$i]);
+                       $i++;
+                       $entity->delete();
+               }
+
+               foreach ($guids as $guid) {
+                       if ($e = get_entity($guid)) {
+                               $e->delete();
+                       }
+               }
+       }
 }