diff options
| -rw-r--r-- | engine/lib/metadata.php | 58 | ||||
| -rw-r--r-- | engine/tests/api/entity_getter_functions.php | 120 | 
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(); +			} +		} +	}  } | 
