aboutsummaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2010-02-24 02:20:15 +0000
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2010-02-24 02:20:15 +0000
commitd15b5098d14bb2a3f8f887b5e68f174928f0d0a4 (patch)
tree61afe6d9ae4b73458a22b3c51e9cbfe419e1d8fa /engine
parent66d12dbe4e14e36f8ab1c8014be0665cf8ee17c7 (diff)
downloadelgg-d15b5098d14bb2a3f8f887b5e68f174928f0d0a4.tar.gz
elgg-d15b5098d14bb2a3f8f887b5e68f174928f0d0a4.tar.bz2
Fixes #1542: Pulled in Kevin's patch to add ability to sort by metadata. Added unit tests for this.
git-svn-id: http://code.elgg.org/elgg/trunk@3970 36083f99-b078-4883-b0ff-0f9b5a30f544
Diffstat (limited to 'engine')
-rw-r--r--engine/lib/metadata.php58
-rw-r--r--engine/tests/api/entity_getter_functions.php120
2 files changed, 172 insertions, 6 deletions
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php
index 67a135d75..1795116c0 100644
--- a/engine/lib/metadata.php
+++ b/engine/lib/metadata.php
@@ -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;
}
diff --git a/engine/tests/api/entity_getter_functions.php b/engine/tests/api/entity_getter_functions.php
index 04fa3e4e5..49fd4ec0d 100644
--- a/engine/tests/api/entity_getter_functions.php
+++ b/engine/tests/api/entity_getter_functions.php
@@ -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();
+ }
+ }
+ }
}