From 36ef345eb6425106f061fb866d9fa66d051e16df Mon Sep 17 00:00:00 2001 From: brettp Date: Mon, 5 Apr 2010 16:08:42 +0000 Subject: Merged 5530:5604 from 1.7 to trunk. git-svn-id: http://code.elgg.org/elgg/trunk@5622 36083f99-b078-4883-b0ff-0f9b5a30f544 --- engine/lib/annotations.php | 292 +++++++-------------------------------------- 1 file changed, 40 insertions(+), 252 deletions(-) (limited to 'engine/lib/annotations.php') diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php index c545682d5..6fdb69dc0 100644 --- a/engine/lib/annotations.php +++ b/engine/lib/annotations.php @@ -409,273 +409,61 @@ $value = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "asc", $time /** + * Returns entities based upon annotations. Accepts the same values as + * elgg_get_entities_from_metadata() but uses the annotations table. * - * @todo Add support for arrays of names and values + * @see elgg_get_entities + * @see elgg_get_entities_from_metadata + * @param array $options Array in format: * - * @param $options - * @return unknown_type + * annotation_names => NULL|ARR annotations names + * + * annotation_values => NULL|ARR annotations values + * + * annotation_name_value_pairs => NULL|ARR (name = 'name', value => 'value', 'operand' => '=', 'case_sensitive' => TRUE) entries. + * Currently if multiple values are sent via an array (value => array('value1', 'value2') the pair's operand will be forced to "IN". + * + * annotation_name_value_pairs_operator => NULL|STR The operator to use for combining (name = value) OPERATOR (name = value); default AND + * + * annotation_case_sensitive => BOOL Overall Case sensitive + * + * order_by_annotation => NULL|ARR (array('name' => 'annotation_text1', 'direction' => ASC|DESC, 'as' => text|integer), + * Also supports array('name' => 'annotation_text1') + * + * annotation_owner_guids => NULL|ARR guids for annotaiton owners + * + * @return array */ function elgg_get_entities_from_annotations(array $options = array()) { $defaults = array( - 'annotation_names' => NULL, - 'annotation_name' => NULL, - 'annotation_values' => NULL, - 'annotation_value' => NULL, - 'annotation_name_value_pair' => NULL, - 'annotation_name_value_pairs' => NULL, - 'annotation_name_value_pairs_operator' => 'AND', - 'annotation_case_sensitive' => TRUE, - 'order_by' => 'maxtime desc', - 'group_by' => 'a.entity_guid' - ); - - $options = array_merge($defaults, $options); - - $singulars = array('annotation_name', 'annotation_value', 'annotation_name_value_pair'); - $options = elgg_normalise_plural_options_array($options, $singulars); - - $clauses = elgg_get_entity_annotation_where_sql('e', $options['annotation_names'], $options['annotation_values'], - $options['annotation_name_value_pairs'], $options['annotation_name_value_pairs_operator'], $options['annotation_case_sensitive']); - - 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(); - } - - $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']); - - // merge selects to pass to get_entities() - if (isset($options['selects']) && !is_array($options['selects'])) { - $options['selects'] = array($options['selects']); - } elseif (!isset($options['selects'])) { - $options['selects'] = array(); - } - - $options['selects'] = array_merge($options['selects'], $clauses['selects']); - - /* @todo overwrites the current order and group bys - if ($clauses['order_by']) { - $options['order_by'] = $clauses['order_by']; - } - if ($clauses['group_by']) { - $options['group_by'] = $clauses['group_by']; - } - */ - } - - return elgg_get_entities($options); -} + 'annotation_names' => ELGG_ENTITIES_ANY_VALUE, + 'annotation_values' => ELGG_ENTITIES_ANY_VALUE, + 'annotation_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, -/** - * Returns annotation name and value SQL where for entities. - * nb: $names and $values are not paired. Use $pairs for this. - * Pairs default to '=' operand. - * - * @param $prefix - * @param ARR|NULL $names - * @param ARR|NULL $values - * @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 - * @return FALSE|array False on fail, array('joins', 'wheres') - */ -function elgg_get_entity_annotation_where_sql($table, $names = NULL, $values = NULL, $pairs = NULL, $pair_operator = 'AND', $case_sensitive = TRUE) { - global $CONFIG; - - // short circuit if nothing requested - // 0 is a valid (if not ill-conceived) annotation name. - // 0 is also a valid annotation value for FALSE, NULL, or 0 - if ((!$names && $names !== 0) - && (!$values && $values !== 0) - && (!$pairs && $pairs !== 0)) { - return ''; - } + 'annotation_name_value_pairs_operator' => 'AND', + 'annotation_case_sensitive' => TRUE, + 'order_by_annotation' => array(), - // binary forces byte-to-byte comparision of strings, making - // it case- and diacritical-mark- sensitive. - // only supported on values. - $binary = ($case_sensitive) ? ' BINARY ' : ''; + 'annotation_owner_guids' => ELGG_ENTITIES_ANY_VALUE, - $access = get_access_sql_suffix('a'); - - $return = array ( - 'joins' => array (), - 'wheres' => array(), - 'selects' => array() + 'order_by' => 'maxtime desc', + 'group_by' => 'a.entity_guid' ); - $wheres = array(); - - // get names wheres and joins - $names_where = ''; - if ($names !== NULL) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}annotations a on {$table}.guid = a.entity_guid"; - if (!is_array($names)) { - $names = array($names); - } - - $sanitised_names = array(); - foreach ($names as $name) { - // normalise to 0. - if (!$name) { - $name = '0'; - } - $sanitised_names[] = "'$name'"; - } - - if ($names_str = implode(',', $sanitised_names)) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn on a.name_id = msn.id"; - $names_where = "(msn.string IN ($names_str))"; - } - } - - // get values wheres and joins - $values_where = ''; - if ($values !== NULL) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}annotations a on {$table}.guid = a.entity_guid"; - - if (!is_array($values)) { - $values = array($values); - } - - $sanitised_values = array(); - foreach ($values as $value) { - // normalize to 0 - if (!$value) { - $value = 0; - } - $sanitised_values[] = "'$value'"; - } - - if ($values_str = implode(',', $sanitised_values)) { - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv on a.value_id = msv.id"; - $values_where = "({$binary}msv.string IN ($values_str))"; - } - } - - if ($names_where && $values_where) { - $wheres[] = "($names_where AND $values_where AND $access)"; - } elseif ($names_where) { - $wheres[] = "($names_where AND $access)"; - } elseif ($values_where) { - $wheres[] = "($values_where AND $access)"; - } - - // add pairs - // pairs must be in arrays. - if (is_array($pairs)) { - $array = array( - 'name' => 'test', - 'value' => 5 - ); - - $array = array('test' => 5); - - // 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(); - - // @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. - if (!is_array($pair)) { - $pair = array( - 'name' => $index, - 'value' => $pair - ); - } - - // @todo The multiple joins are only needed when the operator is AND - $return['joins'][] = "JOIN {$CONFIG->dbprefix}annotations a{$i} on {$table}.guid = a{$i}.entity_guid"; - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn{$i} on a{$i}.name_id = msn{$i}.id"; - $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv{$i} on a{$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. - continue; - } - - // case sensitivity can be specified per pair. - // default to higher level setting. - if (isset($pair['case_sensitive'])) { - $pair_binary = ($pair['case_sensitive']) ? ' BINARY ' : ''; - } else { - $pair_binary = $binary; - } - - if (isset($pair['operand'])) { - $operand = sanitise_string($pair['operand']); - } else { - $operand = ' = '; - } - - // 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. - //$value = trim(strtolower($operand)) == 'in' ? $pair['value'] : "'{$pair['value']}'"; - if (trim(strtolower($operand)) == 'in' || sanitise_int($pair['value'])) { - $value = $pair['value']; - } else { - $value = "'{$pair['value']}'"; - } - - $access = get_access_sql_suffix("a{$i}"); - $pair_wheres[] = "(msn{$i}.string = '{$pair['name']}' AND {$pair_binary}msv{$i}.string $operand $value AND $access)"; - $i++; - } + $options = array_merge($defaults, $options); - if ($where = implode (" $pair_operator ", $pair_wheres)) { - $wheres[] = "($where)"; - } + if (!$options = elgg_entities_get_metastrings_options('annotation', $options)) { + return FALSE; } - if ($where = implode(' OR ', $wheres)) { - $return['selects'][] = "max(a.time_created) as maxtime"; - $return['wheres'][] = "($where)"; - $return['group_by'] = 'a.entity_guid'; - $return['order_by'] = 'maxtime asc'; - } + // special sorting for annotations + //@todo overrides other sorting + $options['selects'][] = "max(n_table.time_created) as maxtime"; + $options['group_by'] = 'n_table.entity_guid'; - return $return; + return elgg_get_entities($options); } -/** - * Return a list of entities which are annotated with a specific annotation. - * These can be ordered by when the annotation was created/updated. - * - * @param string $entity_type Type of entity. - * @param string $entity_subtype Subtype of entity. - * @param string $name Name of annotation. - * @param string $value Value of annotation. - * @param int $owner_guid Owner. - * @param int $group_guid Group container. Currently this is only supported if $entity_type == 'object' - * @param int $limit Maximum number of results to return. - * @param int $offset Place to start. - * @param string $order_by How to order results. - * @param boolean $count Whether to count entities rather than return them - * @param int $timelower The earliest time the annotation can have been created. Default: all - * @param int $timeupper The latest time the annotation can have been created. Default: all - */ - - /** * @deprecated 1.7 Use elgg_get_entities_from_annotations() * @param $entity_type @@ -714,7 +502,7 @@ $timelower = 0, $timeupper = 0) { } if ($owner_guid) { - $options['owner_guid'] = $owner_guid; + $options['annotation_owner_guid'] = $owner_guid; } if ($group_guid) { -- cgit v1.2.3