Пример #1
0
function members_extended_search($options = array())
{
    $db_prefix = elgg_get_config('dbprefix');
    $query = sanitise_string($options['query']);
    $options['joins'] = array("JOIN {$db_prefix}users_entity ue ON e.guid = ue.guid", "JOIN {$db_prefix}metadata md on e.guid = md.entity_guid", "JOIN {$db_prefix}metastrings msv ON n_table.value_id = msv.id");
    $r_where = "";
    $group_guid = $options['group_guid'];
    if ($group_guid) {
        $group = get_entity($group_guid);
        if (elgg_instanceof($group, 'group')) {
            elgg_set_page_owner_guid($group_guid);
            $options['joins'][] = "JOIN {$db_prefix}entity_relationships r ON e.guid = r.guid_one";
            $r_where = "AND (r.relationship = 'member' AND r.guid_two = '{$group_guid}')";
        }
    }
    // username and display name
    $fields = array('username', 'name');
    $where = search_get_where_sql('ue', $fields, $options, FALSE);
    // get the where clauses for the md names
    // can't use egef_metadata() because the n_table join comes too late.
    $clauses = _elgg_entities_get_metastrings_options('metadata', array('metadata_names' => $options['metadata_names']));
    $options['joins'] = array_merge($clauses['joins'], $options['joins']);
    // no fulltext index, can't disable fulltext search in this function.
    // $md_where .= " AND " . search_get_where_sql('msv', array('string'), $options, FALSE);
    $md_where = "(({$clauses['wheres'][0]}) AND msv.string LIKE '%{$query}%')";
    $options['wheres'] = array("(({$where}) OR ({$md_where}) {$r_where})");
    // override subtype -- All users should be returned regardless of subtype.
    $options['subtype'] = ELGG_ENTITIES_ANY_VALUE;
    $options['count'] = true;
    $count = elgg_get_entities($options);
    // no need to continue if nothing here.
    if (!$count) {
        return array('entities' => array(), 'count' => $count);
    }
    $options['count'] = FALSE;
    $options['order_by'] = search_get_order_by_sql('e', 'ue', $options['sort'], $options['order']);
    $entities = elgg_get_entities($options);
    return array('entities' => $entities, 'count' => $count);
}
Пример #2
0
/**
 * Get users that match the search parameters.
 *
 * Searches on username, display name, and profile fields
 * 
 * @param string $hook   Hook name
 * @param string $type   Hook type
 * @param array  $value  Empty array
 * @param array  $params Search parameters
 * @return array
 */
function search_users_hook($hook, $type, $value, $params)
{
    $params['joins'] = (array) elgg_extract('joins', $params, array());
    $params['wheres'] = (array) elgg_extract('wheres', $params, array());
    $db_prefix = elgg_get_config('dbprefix');
    $query = sanitise_string($params['query']);
    $join = "JOIN {$db_prefix}users_entity ue ON e.guid = ue.guid";
    array_unshift($params['joins'], $join);
    // username and display name
    $fields = array('username', 'name');
    $where = search_get_where_sql('ue', $fields, $params, FALSE);
    // profile fields
    $profile_fields = array_keys(elgg_get_config('profile_fields'));
    if (!empty($profile_fields)) {
        $params['joins'][] = "JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
        $params['joins'][] = "JOIN {$db_prefix}metastrings msv ON n_table.value_id = msv.id";
        // get the where clauses for the md names
        // can't use egef_metadata() because the n_table join comes too late.
        $clauses = _elgg_entities_get_metastrings_options('metadata', array('metadata_names' => $profile_fields, 'metadata_values' => null, 'metadata_name_value_pairs' => null, 'metadata_name_value_pairs_operator' => null, 'metadata_case_sensitive' => null, 'order_by_metadata' => null, 'metadata_owner_guids' => null));
        $params['joins'] = array_merge($clauses['joins'], $params['joins']);
        // no fulltext index, can't disable fulltext search in this function.
        // $md_where .= " AND " . search_get_where_sql('msv', array('string'), $params, FALSE);
        $md_where = "(({$clauses['wheres'][0]}) AND msv.string LIKE '%{$query}%')";
        $params['wheres'][] = "(({$where}) OR ({$md_where}))";
    } else {
        $params['wheres'][] = "{$where}";
    }
    // override subtype -- All users should be returned regardless of subtype.
    $params['subtype'] = ELGG_ENTITIES_ANY_VALUE;
    $params['count'] = true;
    $count = elgg_get_entities($params);
    // no need to continue if nothing here.
    if (!$count) {
        return array('entities' => array(), 'count' => $count);
    }
    $params['count'] = FALSE;
    if (isset($params['sort']) || !isset($params['order_by'])) {
        $params['order_by'] = search_get_order_by_sql('e', 'ue', $params['sort'], $params['order']);
    }
    $entities = elgg_get_entities($params);
    // add the volatile data for why these entities have been returned.
    foreach ($entities as $entity) {
        $title = search_get_highlighted_relevant_substrings($entity->name, $query);
        // include the username if it matches but the display name doesn't.
        if (false !== strpos($entity->username, $query)) {
            $username = search_get_highlighted_relevant_substrings($entity->username, $query);
            $title .= " ({$username})";
        }
        $entity->setVolatileData('search_matched_title', $title);
        if (!empty($profile_fields)) {
            $matched = '';
            foreach ($profile_fields as $md_name) {
                $metadata = $entity->{$md_name};
                if (is_array($metadata)) {
                    foreach ($metadata as $text) {
                        if (stristr($text, $query)) {
                            $matched .= elgg_echo("profile:{$md_name}") . ': ' . search_get_highlighted_relevant_substrings($text, $query);
                        }
                    }
                } else {
                    if (stristr($metadata, $query)) {
                        $matched .= elgg_echo("profile:{$md_name}") . ': ' . search_get_highlighted_relevant_substrings($metadata, $query);
                    }
                }
            }
            $entity->setVolatileData('search_matched_description', $matched);
        }
    }
    return array('entities' => $entities, 'count' => $count);
}
/**
 * Returns entities based upon metadata.  Also accepts all
 * options available to elgg_get_entities().  Supports
 * the singular option shortcut.
 *
 * @note Using metadata_names and metadata_values results in a
 * "names IN (...) AND values IN (...)" clause.  This is subtly
 * differently than default multiple metadata_name_value_pairs, which use
 * "(name = value) AND (name = value)" clauses.
 *
 * When in doubt, use name_value_pairs.
 *
 * To ask for entities that do not have a metadata value, use a custom
 * where clause like this:
 *
 * 	$options['wheres'][] = "NOT EXISTS (
 *			SELECT 1 FROM {$dbprefix}metadata md
 *			WHERE md.entity_guid = e.guid
 *				AND md.name_id = $name_metastring_id
 *				AND md.value_id = $value_metastring_id)";
 *
 * Note the metadata name and value has been denormalized in the above example.
 *
 * @see elgg_get_entities
 *
 * @param array $options Array in format:
 *
 * 	metadata_names => null|ARR metadata names
 *
 * 	metadata_values => null|ARR metadata values
 *
 * 	metadata_name_value_pairs => null|ARR (
 *                                         name => 'name',
 *                                         value => 'value',
 *                                         'operand' => '=',
 *                                         'case_sensitive' => true
 *                                        )
 *                               Currently if multiple values are sent via
 *                               an array (value => array('value1', 'value2')
 *                               the pair's operand will be forced to "IN".
 *                               If passing "IN" as the operand and a string as the value, 
 *                               the value must be a properly quoted and escaped string.
 *
 * 	metadata_name_value_pairs_operator => null|STR The operator to use for combining
 *                                        (name = value) OPERATOR (name = value); default AND
 *
 * 	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')
 *
 *  metadata_owner_guids => null|ARR guids for metadata owners
 *
 * @return ElggEntity[]|mixed If count, int. If not count, array. false on errors.
 * @since 1.7.0
 */
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_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', 'metadata_owner_guid');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    if (!($options = _elgg_entities_get_metastrings_options('metadata', $options))) {
        return false;
    }
    return elgg_get_entities($options);
}
Пример #4
0
/**
 * Returns entities based upon annotations.  Also accepts all options available
 * to elgg_get_entities() and elgg_get_entities_from_metadata().
 *
 * Entity creation time is selected as maxtime. To sort based upon
 * this, pass 'order_by' => 'maxtime asc' || 'maxtime desc'
 *
 * @see elgg_get_entities
 * @see elgg_get_entities_from_metadata
 *
 * @param array $options Array in format:
 *
 * 	annotation_names => null|ARR annotations names
 *
 * 	annotation_values => null|ARR annotations values
 *
 * 	annotation_name_value_pairs => null|ARR (name = 'name', value => 'value',
 * 	'operator' => '=', 'case_sensitive' => true) entries.
 * 	Currently if multiple values are sent via an array (value => array('value1', 'value2')
 * 	the pair's operator 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 mixed If count, int. If not count, array. false on errors.
 * @since 1.7.0
 */
function elgg_get_entities_from_annotations(array $options = array())
{
    $defaults = array('annotation_names' => ELGG_ENTITIES_ANY_VALUE, 'annotation_values' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs_operator' => 'AND', 'annotation_case_sensitive' => true, 'order_by_annotation' => array(), 'annotation_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'annotation_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'annotation_owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'order_by' => 'maxtime DESC', 'group_by' => 'a.entity_guid');
    $options = array_merge($defaults, $options);
    $singulars = array('annotation_name', 'annotation_value', 'annotation_name_value_pair', 'annotation_owner_guid');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $options = _elgg_entities_get_metastrings_options('annotation', $options);
    if (!$options) {
        return false;
    }
    // special sorting for annotations
    //@todo overrides other sorting
    $options['selects'][] = "MAX(n_table.time_created) AS maxtime";
    $options['group_by'] = 'n_table.entity_guid';
    $time_wheres = _elgg_get_entity_time_where_sql('a', $options['annotation_created_time_upper'], $options['annotation_created_time_lower']);
    if ($time_wheres) {
        $options['wheres'] = array_merge($options['wheres'], $time_wheres);
    }
    return elgg_get_entities_from_metadata($options);
}
Пример #5
0
 /**
  * Returns entities based upon annotations.  Also accepts all options available
  * to elgg_get_entities() and elgg_get_entities_from_metadata().
  *
  * @see elgg_get_entities
  * @see elgg_get_entities_from_metadata
  *
  * @param array $options Array in format:
  *
  * 	annotation_names => null|ARR annotations names
  *
  * 	annotation_values => null|ARR annotations values
  *
  * 	annotation_name_value_pairs => null|ARR (name = 'name', value => 'value',
  * 	'operator' => '=', 'case_sensitive' => true) entries.
  * 	Currently if multiple values are sent via an array (value => array('value1', 'value2')
  * 	the pair's operator 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 mixed If count, int. If not count, array. false on errors.
  */
 function getEntities(array $options = array())
 {
     $defaults = array('annotation_names' => ELGG_ENTITIES_ANY_VALUE, 'annotation_values' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs_operator' => 'AND', 'annotation_case_sensitive' => true, 'order_by_annotation' => array(), 'annotation_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'annotation_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'annotation_owner_guids' => ELGG_ENTITIES_ANY_VALUE);
     $options = array_merge($defaults, $options);
     $singulars = array('annotation_name', 'annotation_value', 'annotation_name_value_pair', 'annotation_owner_guid');
     $options = _elgg_normalize_plural_options_array($options, $singulars);
     $options = _elgg_entities_get_metastrings_options('annotation', $options);
     if (!$options) {
         return false;
     }
     // because of performance issues support for ordering by maxtime has been dropped
     // @see https://github.com/Elgg/Elgg/issues/6638
     if (isset($options['order_by']) && preg_match('~\\bmaxtime\\b~i', $options['order_by'])) {
         // check if the user provided maxtime
         $deprecated = true;
         if (isset($options['selects'])) {
             $selects = $options['selects'];
             if (!is_array($selects)) {
                 $selects = array($selects);
             }
             foreach ($selects as $select) {
                 if (preg_match('~\\bmaxtime\\b~i', $options['order_by'])) {
                     $deprecated = false;
                     break;
                 }
             }
         }
         // the user didn't provide maxtime
         if ($deprecated) {
             // special sorting for annotations
             elgg_deprecated_notice(__FUNCTION__ . ": no longer orders by annotations by default. If you order" . " by maxtime, you must provide that column via \$options['selects']. See" . " https://github.com/Elgg/Elgg/issues/6638#issuecomment-41562034", "1.10");
             $options['selects'][] = "MAX(n_table.time_created) AS maxtime";
             $options['group_by'] = 'n_table.entity_guid';
         }
     }
     $time_wheres = _elgg_get_entity_time_where_sql('a', $options['annotation_created_time_upper'], $options['annotation_created_time_lower']);
     if ($time_wheres) {
         $options['wheres'] = array_merge($options['wheres'], $time_wheres);
     }
     return elgg_get_entities_from_metadata($options);
 }
Пример #6
0
 /**
  * {@inheritdoc}
  */
 public static function addSearchQuery(array $options = [], $query = '', array $search_options = [])
 {
     if (!$query) {
         return $options;
     }
     $query = sanitize_string(stripslashes($query));
     $dbprefix = elgg_get_config('dbprefix');
     $options['joins']['objects_entity'] = "\n\t\t\tJOIN {$dbprefix}objects_entity objects_entity\n\t\t\t\tON objects_entity.guid = e.guid\n\t\t\t";
     $advanced = elgg_extract('search_tags', $search_options, false);
     $attribute_names = ['title', 'description'];
     if (isset($search_options['fields'])) {
         $search_fields = elgg_extract('fields', $search_options);
         $attribute_fields = [];
         $metadata_fields = [];
         foreach ($search_fields as $search_field) {
             if (in_array($search_field, $attribute_names)) {
                 $attribute_fields[] = $search_field;
             } else {
                 $metadata_fields[] = $search_field;
                 $advanced = true;
             }
         }
     } else {
         $attribute_fields = $attribute_names;
         $metadata_fields = array_keys((array) elgg_get_registered_tag_metadata_names());
         $metadata_fields = array_diff($metadata_fields, $attribute_fields);
         $advanced = elgg_extract('advanced', $search_options, $advanced);
     }
     if (empty($attribute_fields)) {
         $attribute_fields = ['name'];
     }
     $where = self::getFieldSearchWhereClause('objects_entity', $attribute_fields, ['query' => $query], false);
     if ($advanced && !empty($metadata_fields)) {
         $options['joins']['metadata_fields_md'] = "\n\t\t\t\tJOIN {$dbprefix}metadata metadata_fields_md\n\t\t\t\t\tON e.guid = metadata_fields_md.entity_guid\n\t\t\t\t";
         $options['joins']['metadata_fields_msv'] = "\n\t\t\t\tJOIN {$dbprefix}metastrings metadata_fields_msv\n\t\t\t\t\tON n_table.value_id = metadata_fields_msv.id\n\t\t\t\t";
         $clauses = _elgg_entities_get_metastrings_options('metadata', array('metadata_names' => $metadata_fields, 'metadata_values' => null, 'metadata_name_value_pairs' => null, 'metadata_name_value_pairs_operator' => null, 'metadata_case_sensitive' => null, 'order_by_metadata' => null, 'metadata_owner_guids' => null));
         $options['joins'] = array_merge($clauses['joins'], $options['joins']);
         $metadata_fields_md_where = "(({$clauses['wheres'][0]}) AND metadata_fields_msv.string='{$query}')";
         $options['wheres'][] = "(({$where}) OR ({$metadata_fields_md_where}))";
     } else {
         $options['wheres'][] = "{$where}";
     }
     return $options;
 }
Пример #7
0
 /**
  * Returns entities based upon annotations.  Also accepts all options available
  * to elgg_get_entities() and elgg_get_entities_from_metadata().
  *
  * @see elgg_get_entities
  * @see elgg_get_entities_from_metadata
  *
  * @param array $options Array in format:
  *
  * 	annotation_names => null|ARR annotations names
  *
  * 	annotation_values => null|ARR annotations values
  *
  * 	annotation_name_value_pairs => null|ARR (name = 'name', value => 'value',
  * 	'operator' => '=', 'case_sensitive' => true) entries.
  * 	Currently if multiple values are sent via an array (value => array('value1', 'value2')
  * 	the pair's operator 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 mixed If count, int. If not count, array. false on errors.
  */
 function getEntities(array $options = array())
 {
     $defaults = array('annotation_names' => ELGG_ENTITIES_ANY_VALUE, 'annotation_values' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs_operator' => 'AND', 'annotation_case_sensitive' => true, 'order_by_annotation' => array(), 'annotation_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'annotation_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'annotation_owner_guids' => ELGG_ENTITIES_ANY_VALUE);
     $options = array_merge($defaults, $options);
     $singulars = array('annotation_name', 'annotation_value', 'annotation_name_value_pair', 'annotation_owner_guid');
     $options = _elgg_normalize_plural_options_array($options, $singulars);
     $options = _elgg_entities_get_metastrings_options('annotation', $options);
     if (!$options) {
         return false;
     }
     $time_wheres = _elgg_get_entity_time_where_sql('n_table', $options['annotation_created_time_upper'], $options['annotation_created_time_lower']);
     if ($time_wheres) {
         $options['wheres'][] = $time_wheres;
     }
     return elgg_get_entities_from_metadata($options);
 }
Пример #8
0
/**
 * Adds search query options to the ege* options array
 *
 * @param array  $options   ege* options
 * @param string $query     Query
 * @return array
 */
function user_sort_add_search_query_options(array $options = array(), $query = '')
{
    if (!elgg_is_active_plugin('search') || !$query) {
        return $options;
    }
    $query = sanitize_string($query);
    $advanced = elgg_extract('advanced_search', $options, false);
    $dbprefix = elgg_get_config('dbprefix');
    $options['joins']['users_entity'] = "JOIN {$dbprefix}users_entity users_entity ON users_entity.guid = e.guid";
    $fields = array('name');
    if (elgg_get_plugin_setting('username', 'user_sort', true)) {
        $fields[] = 'username';
    }
    $where = search_get_where_sql('users_entity', $fields, ['query' => $query], false);
    $profile_fields = array_keys((array) elgg_get_config('profile_fields'));
    $profile_fields = array_diff($profile_fields, $fields);
    if ($advanced && !empty($profile_fields)) {
        $options['joins']['profile_fields_md'] = "JOIN {$dbprefix}metadata profile_fields_md on e.guid = profile_fields_md.entity_guid";
        $options['joins']['profile_fields_msv'] = "JOIN {$dbprefix}metastrings profile_fields_msv ON n_table.value_id = profile_fields_msv.id";
        $clauses = _elgg_entities_get_metastrings_options('metadata', array('metadata_names' => $profile_fields, 'metadata_values' => null, 'metadata_name_value_pairs' => null, 'metadata_name_value_pairs_operator' => null, 'metadata_case_sensitive' => null, 'order_by_metadata' => null, 'metadata_owner_guids' => null));
        $options['joins'] = array_merge($clauses['joins'], $options['joins']);
        $profile_fields_md_where = "(({$clauses['wheres'][0]}) AND profile_fields_msv.string LIKE '%{$query}%')";
        $options['wheres'][] = "(({$where}) OR ({$profile_fields_md_where}))";
    } else {
        $options['wheres'][] = "{$where}";
    }
    return $options;
}