diff options
author | brettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-04-05 16:08:42 +0000 |
---|---|---|
committer | brettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-04-05 16:08:42 +0000 |
commit | 36ef345eb6425106f061fb866d9fa66d051e16df (patch) | |
tree | 53fb2bd05f8b5e2010f9e3d1e93075ad7071ec1e /engine/lib/metadata.php | |
parent | 5571ca5b350fd1735f13af7ddfbb88afa6befb0c (diff) | |
download | elgg-36ef345eb6425106f061fb866d9fa66d051e16df.tar.gz elgg-36ef345eb6425106f061fb866d9fa66d051e16df.tar.bz2 |
Merged 5530:5604 from 1.7 to trunk.
git-svn-id: http://code.elgg.org/elgg/trunk@5622 36083f99-b078-4883-b0ff-0f9b5a30f544
Diffstat (limited to 'engine/lib/metadata.php')
-rw-r--r-- | engine/lib/metadata.php | 133 |
1 files changed, 92 insertions, 41 deletions
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php index 5c248e0f6..bab919ca2 100644 --- a/engine/lib/metadata.php +++ b/engine/lib/metadata.php @@ -532,8 +532,6 @@ function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $en return get_data($query, "row_to_elggmetadata"); } - - /** * Returns entities based upon metadata. Also accepts all * options available to elgg_get_entities(). Supports @@ -547,6 +545,7 @@ function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $en * When in doubt, use name_value_pairs. * * @see elgg_get_entities + * @see elgg_get_entities_from_annotations * @param array $options Array in format: * * metadata_names => NULL|ARR metadata names @@ -560,30 +559,59 @@ function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $en * * metadata_case_sensitive => BOOL Overall Case sensitive * - * order_by_metadata => NULL|ARR (array('name' => 'metadata_text1', 'direction' => ASC|DESC, 'as' => text|integer), - * Also supports array('name' => 'metadata_text1') + * order_by_metadata => NULL|ARR (array('name' => 'metadata_text1', 'direction' => ASC|DESC, 'as' => text|integer), + * Also supports array('name' => 'metadata_text1') + * + * metadata_owner_guids => NULL|ARR guids for metadata owners * * @return array */ function elgg_get_entities_from_metadata(array $options = array()) { $defaults = array( - 'metadata_names' => ELGG_ENTITIES_ANY_VALUE, - 'metadata_values' => ELGG_ENTITIES_ANY_VALUE, - 'metadata_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, + 'metadata_names' => ELGG_ENTITIES_ANY_VALUE, + 'metadata_values' => ELGG_ENTITIES_ANY_VALUE, + 'metadata_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, - 'metadata_name_value_pairs_operator' => 'AND', - 'metadata_case_sensitive' => TRUE, - 'order_by_metadata' => array(), + 'metadata_name_value_pairs_operator'=> 'AND', + 'metadata_case_sensitive' => TRUE, + 'order_by_metadata' => array(), + + 'metadata_owner_guids' => ELGG_ENTITIES_ANY_VALUE, ); $options = array_merge($defaults, $options); - $singulars = array('metadata_name', 'metadata_value', 'metadata_name_value_pair'); + if (!$options = elgg_entities_get_metastrings_options('metadata', $options)) { + return FALSE; + } + + 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 + */ +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', $options['metadata_names'], $options['metadata_values'], - $options['metadata_name_value_pairs'], $options['metadata_name_value_pairs_operator'], $options['metadata_case_sensitive'], - $options['order_by_metadata']); + $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() @@ -614,15 +642,19 @@ function elgg_get_entities_from_metadata(array $options = array()) { } } - return elgg_get_entities($options); + return $options; } /** * Returns metadata name and value SQL where for entities. - * nb: $names and $values are not paired. Use $pairs for this. + * NB: $names and $values are not paired. Use $pairs for this. * Pairs default to '=' operand. * - * @param $prefix + * This function is reused for annotations because the tables are + * exactly the same. + * + * @param string $e_table Entities table name + * @param string $n_table Normalized metastrings table name (Where entities, values, and names are joined. annotations / metadata) * @param ARR|NULL $names * @param ARR|NULL $values * @param ARR|NULL $pairs array of names / values / operands @@ -631,25 +663,30 @@ function elgg_get_entities_from_metadata(array $options = array()) { * @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, $order_by_metadata = NULL) { +function elgg_get_entity_metadata_where_sql($e_table, $n_table, $names = NULL, $values = NULL, $pairs = NULL, $pair_operator = 'AND', $case_sensitive = TRUE, $order_by_metadata = NULL, $owner_guids = NULL) { global $CONFIG; // short circuit if nothing requested // 0 is a valid (if not ill-conceived) metadata name. // 0 is also a valid metadata value for FALSE, NULL, or 0 + // 0 is also a valid(ish) owner_guid if ((!$names && $names !== 0) && (!$values && $values !== 0) && (!$pairs && $pairs !== 0) + && (!$owner_guids && $owner_guids !== 0) && !isset($order_by_metadata)) { return ''; } + // join counter for incremental joins. + $i = 1; + // binary forces byte-to-byte comparision of strings, making // it case- and diacritical-mark- sensitive. // only supported on values. $binary = ($case_sensitive) ? ' BINARY ' : ''; - $access = get_access_sql_suffix('md'); + $access = get_access_sql_suffix('n_table'); $return = array ( 'joins' => array (), @@ -657,12 +694,14 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL 'orders' => array() ); + // will always want to join these tables if pulling metastrings. + $return['joins'][] = "JOIN {$CONFIG->dbprefix}{$n_table} n_table on {$e_table}.guid = n_table.entity_guid"; + $wheres = array(); // get names wheres and joins $names_where = ''; if ($names !== NULL) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metadata md on {$table}.guid = md.entity_guid"; if (!is_array($names)) { $names = array($names); } @@ -677,7 +716,7 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL } if ($names_str = implode(',', $sanitised_names)) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn on md.name_id = msn.id"; + $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn on n_table.name_id = msn.id"; $names_where = "(msn.string IN ($names_str))"; } } @@ -685,8 +724,6 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL // get values wheres and joins $values_where = ''; if ($values !== NULL) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metadata md on {$table}.guid = md.entity_guid"; - if (!is_array($values)) { $values = array($values); } @@ -701,7 +738,7 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL } if ($values_str = implode(',', $sanitised_values)) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv on md.value_id = msv.id"; + $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv on n_table.value_id = msv.id"; $values_where = "({$binary}msv.string IN ($values_str))"; } } @@ -714,8 +751,6 @@ 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)) { @@ -739,11 +774,6 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL ); } - // @todo The multiple joins are only needed when the operator is AND - $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"; - // must have at least a name and value if (!isset($pair['name']) || !isset($pair['value'])) { // @todo should probably return false. @@ -764,6 +794,10 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL $operand = ' = '; } + // for comparing + $trimmed_operand = trim(strtolower($operand)); + + $access = get_access_sql_suffix("n_table{$i}"); // 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'])) { @@ -772,10 +806,10 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL $values_array = array(); foreach ($pair['value'] as $pair_value) { - if (is_numeric($v)) { + if (is_numeric($pair_value)) { $values_array[] = sanitise_string($pair_value); } else { - $values_array[] = '\'' . sanitise_string($pair_value) . '\''; + $values_array[] = "'" . sanitise_string($pair_value) . "'"; } } @@ -786,16 +820,21 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL // @todo allow support for non IN operands with array of values. // will have to do more silly joins. $operand = 'IN'; - } else if (trim(strtolower($operand)) == 'in') { + } else if ($trimmed_operand == 'in') { $value = "({$pair['value']})"; } else { - $value = '\'' . sanitise_string($pair['value']) . '\''; + $value = "'" . sanitise_string($pair['value']) . "'"; } $name = sanitise_string($pair['name']); - $access = get_access_sql_suffix("md{$i}"); + // @todo The multiple joins are only needed when the operator is AND + $return['joins'][] = "JOIN {$CONFIG->dbprefix}{$n_table} n_table{$i} on {$e_table}.guid = n_table{$i}.entity_guid"; + $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn{$i} on n_table{$i}.name_id = msn{$i}.id"; + $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv{$i} on n_table{$i}.value_id = msv{$i}.id"; + $pair_wheres[] = "(msn{$i}.string = '$name' AND {$pair_binary}msv{$i}.string $operand $value AND $access)"; + $i++; } @@ -804,7 +843,19 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL } } - if ($where = implode(' OR ', $wheres)) { + // add owner_guids + if ($owner_guids) { + if (is_array($owner_guids)) { + $sanitised = array_map('sanitise_int', $owner_guids); + $owner_str = implode(',', $sanitised); + } else { + $owner_str = sanitise_int($owner_guids); + } + + $wheres[] = "(n_table.owner_guid IN ($owner_str))"; + } + + if ($where = implode(' AND ', $wheres)) { $return['wheres'][] = "($where)"; } @@ -821,11 +872,11 @@ function elgg_get_entity_metadata_where_sql($table, $names = NULL, $values = NUL } 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"; + $return['joins'][] = "JOIN {$CONFIG->dbprefix}{$n_table} n_table{$i} on {$e_table}.guid = n_table{$i}.entity_guid"; + $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn{$i} on n_table{$i}.name_id = msn{$i}.id"; + $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv{$i} on n_table{$i}.value_id = msv{$i}.id"; - $access = get_access_sql_suffix("md{$i}"); + $access = get_access_sql_suffix("n_table{$i}"); $return['wheres'][] = "(msn{$i}.string = '$name' AND $access)"; if (isset($order_by['as']) && $order_by['as'] == 'integer') { |