Example #1
0
 /**
  * Returns tags for this entity.
  *
  * @warning Tags must be registered by {@link elgg_register_tag_metadata_name()}.
  *
  * @param array $tag_names Optionally restrict by tag metadata names.
  *
  * @return array
  */
 public function getTags($tag_names = null)
 {
     if ($tag_names && !is_array($tag_names)) {
         $tag_names = array($tag_names);
     }
     $valid_tags = elgg_get_registered_tag_metadata_names();
     $entity_tags = array();
     foreach ($valid_tags as $tag_name) {
         if (is_array($tag_names) && !in_array($tag_name, $tag_names)) {
             continue;
         }
         if ($tags = $this->{$tag_name}) {
             // if a single tag, metadata returns a string.
             // if multiple tags, metadata returns an array.
             if (is_array($tags)) {
                 $entity_tags = array_merge($entity_tags, $tags);
             } else {
                 $entity_tags[] = $tags;
             }
         }
     }
     return $entity_tags;
 }
Example #2
0
function elgg_solr_add_tags($doc, $entity)
{
    if (!elgg_instanceof($entity)) {
        return $doc;
    }
    // store tags the old way - lumped together in $doc->tags as $name . '%%' . $value'
    $doc->tags = elgg_solr_get_tags_array($entity);
    // also store them separately with magick fields
    // store in different field types for different search types
    $valid_tag_names = elgg_get_registered_tag_metadata_names();
    if ($valid_tag_names && is_array($valid_tag_names)) {
        foreach ($valid_tag_names as $tagname) {
            $tags = $entity->{$tagname};
            if ($tags && !is_array($tags)) {
                $tags = array($tags);
            }
            $name = 'tag_' . $tagname . '_ss';
            // multivalued string
            $doc->{$name} = $tags;
        }
    }
    return $doc;
}
Example #3
0
/**
 * Returns suggested groups
 *
 * @param ElggUser $user  (optional) the user to get the groups for, defaults to the current user
 * @param int      $limit (optional) the number of suggested groups to return, default = 10
 *
 * @return ElggGroup[] all the suggested groups
 */
function group_tools_get_suggested_groups($user = null, $limit = null)
{
    $result = array();
    if (!elgg_instanceof($user, "user")) {
        $user = elgg_get_logged_in_user_entity();
    }
    if (is_null($limit)) {
        $limit = get_input("limit", 10);
    }
    $limit = sanitize_int($limit, false);
    if ($user && $limit > 0) {
        $dbprefix = elgg_get_config("dbprefix");
        $group_membership_where = "e.guid NOT IN (SELECT er.guid_two FROM {$dbprefix}entity_relationships er where er.guid_one = {$user->getGUID()} and er.relationship IN ('member', 'membership_request'))";
        if (elgg_get_plugin_setting("auto_suggest_groups", "group_tools") !== "no") {
            $tag_names = elgg_get_registered_tag_metadata_names();
            if (!empty($tag_names)) {
                $user_metadata_options = array("guid" => $user->getGUID(), "limit" => false, "metadata_names" => $tag_names);
                // get metadata
                $user_values = elgg_get_metadata($user_metadata_options);
                if (!empty($user_values)) {
                    // transform to values
                    $user_values = metadata_array_to_values($user_values);
                    // find group with these metadatavalues
                    $group_options = array("type" => "group", "metadata_names" => $tag_names, "metadata_values" => $user_values, "wheres" => $group_membership_where, "group_by" => "e.guid", "order_by" => "count(msn.id) DESC", "limit" => $limit);
                    $groups = elgg_get_entities_from_metadata($group_options);
                    if (!empty($groups)) {
                        foreach ($groups as $group) {
                            $result[$group->getGUID()] = $group;
                            $limit--;
                        }
                    }
                }
            }
        }
        // get admin defined suggested groups
        $group_guids = string_to_tag_array(elgg_get_plugin_setting("suggested_groups", "group_tools"));
        if (!empty($group_guids) && $limit > 0) {
            $group_options = array("guids" => $group_guids, "type" => "group", "wheres" => array($group_membership_where), "limit" => $limit);
            if (!empty($result)) {
                $suggested_guids = array_keys($result);
                $group_options["wheres"][] = "e.guid NOT IN (" . implode(",", $suggested_guids) . ")";
            }
            $groups = elgg_get_entities($group_options);
            if (!empty($groups)) {
                foreach ($groups as $group) {
                    $result[$group->getGUID()] = $group;
                }
            }
        }
    }
    return $result;
}
Example #4
0
/**
 * Get entities with tags that match the search parameters.
 *
 * @param string $hook   Hook name
 * @param string $type   Hook type
 * @param array  $value  Empty array
 * @param array  $params Search parameters
 * @return array
 */
function search_tags_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');
    $valid_tag_names = elgg_get_registered_tag_metadata_names();
    // @todo will need to split this up to support searching multiple tags at once.
    $query = sanitise_string($params['query']);
    // if passed a tag metadata name, only search on that tag name.
    // tag_name isn't included in the params because it's specific to
    // tag searches.
    if ($tag_names = get_input('tag_names')) {
        if (is_array($tag_names)) {
            $search_tag_names = $tag_names;
        } else {
            $search_tag_names = array($tag_names);
        }
        // check these are valid to avoid arbitrary metadata searches.
        foreach ($search_tag_names as $i => $tag_name) {
            if (!in_array($tag_name, $valid_tag_names)) {
                unset($search_tag_names[$i]);
            }
        }
    } else {
        $search_tag_names = $valid_tag_names;
    }
    if (!$search_tag_names) {
        return array('entities' => array(), 'count' => $count);
    }
    // don't use elgg_get_entities_from_metadata() here because of
    // performance issues.  since we don't care what matches at this point
    // use an IN clause to grab everything that matches at once and sort
    // out the matches later.
    $params['joins'][] = "JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
    $params['joins'][] = "JOIN {$db_prefix}metastrings msn on md.name_id = msn.id";
    $params['joins'][] = "JOIN {$db_prefix}metastrings msv on md.value_id = msv.id";
    $access = _elgg_get_access_where_sql(array('table_alias' => 'md'));
    $sanitised_tags = array();
    foreach ($search_tag_names as $tag) {
        $sanitised_tags[] = '"' . sanitise_string($tag) . '"';
    }
    $tags_in = implode(',', $sanitised_tags);
    $params['wheres'][] = "(msn.string IN ({$tags_in}) AND msv.string = '{$query}' AND {$access})";
    $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', null, $params['sort'], $params['order']);
    }
    $entities = elgg_get_entities($params);
    // add the volatile data for why these entities have been returned.
    foreach ($entities as $entity) {
        $matched_tags_strs = array();
        // get tags for each tag name requested to find which ones matched.
        foreach ($search_tag_names as $tag_name) {
            $tags = $entity->getTags($tag_name);
            // @todo make one long tag string and run this through the highlight
            // function.  This might be confusing as it could chop off
            // the tag labels.
            if (in_array(strtolower($query), array_map('strtolower', $tags))) {
                if (is_array($tags)) {
                    $tag_name_str = elgg_echo("tag_names:{$tag_name}");
                    $matched_tags_strs[] = "{$tag_name_str}: " . implode(', ', $tags);
                }
            }
        }
        // different entities have different titles
        switch ($entity->type) {
            case 'site':
            case 'user':
            case 'group':
                $title_tmp = $entity->name;
                break;
            case 'object':
                $title_tmp = $entity->title;
                break;
        }
        // Nick told me my idea was dirty, so I'm hard coding the numbers.
        $title_tmp = strip_tags($title_tmp);
        if (elgg_strlen($title_tmp) > 297) {
            $title_str = elgg_substr($title_tmp, 0, 297) . '...';
        } else {
            $title_str = $title_tmp;
        }
        $desc_tmp = strip_tags($entity->description);
        if (elgg_strlen($desc_tmp) > 297) {
            $desc_str = elgg_substr($desc_tmp, 0, 297) . '...';
        } else {
            $desc_str = $desc_tmp;
        }
        $tags_str = implode('. ', $matched_tags_strs);
        $tags_str = search_get_highlighted_relevant_substrings($tags_str, $params['query'], 30, 300, true);
        $entity->setVolatileData('search_matched_title', $title_str);
        $entity->setVolatileData('search_matched_description', $desc_str);
        $entity->setVolatileData('search_matched_extra', $tags_str);
    }
    return array('entities' => $entities, 'count' => $count);
}
Example #5
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;
 }
/**
 * Get popular tags and their frequencies
 *
 * Supports similar arguments as elgg_get_entities()
 *
 * @param array $options Array in format:
 *
 * 	threshold => INT minimum tag count
 *
 * 	tag_names => array() metadata tag names - must be registered tags
 *
 * 	limit => INT number of tags to return
 *
 *  types => null|STR entity type (SQL: type = '$type')
 *
 * 	subtypes => null|STR entity subtype (SQL: subtype = '$subtype')
 *
 * 	type_subtype_pairs => null|ARR (array('type' => 'subtype'))
 *  (SQL: type = '$type' AND subtype = '$subtype') pairs
 *
 * 	owner_guids => null|INT entity guid
 *
 * 	container_guids => null|INT container_guid
 *
 * 	site_guids => null (current_site)|INT site_guid
 *
 * 	created_time_lower => null|INT Created time lower boundary in epoch time
 *
 * 	created_time_upper => null|INT Created time upper boundary in epoch time
 *
 * 	modified_time_lower => null|INT Modified time lower boundary in epoch time
 *
 * 	modified_time_upper => null|INT Modified time upper boundary in epoch time
 *
 * 	wheres => array() Additional where clauses to AND together
 *
 * 	joins => array() Additional joins
 *
 * @return 	object[]|false If no tags or error, false
 * 						   otherwise, array of objects with ->tag and ->total values
 * @since 1.7.1
 */
function elgg_get_tags(array $options = array())
{
    global $CONFIG;
    $defaults = array('threshold' => 1, 'tag_names' => array(), 'limit' => 10, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'container_guids' => ELGG_ENTITIES_ANY_VALUE, 'site_guids' => $CONFIG->site_guid, 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'joins' => array(), 'wheres' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('type', 'subtype', 'owner_guid', 'container_guid', 'site_guid', 'tag_name');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $registered_tags = elgg_get_registered_tag_metadata_names();
    if (!is_array($options['tag_names'])) {
        return false;
    }
    // empty array so use all registered tag names
    if (count($options['tag_names']) == 0) {
        $options['tag_names'] = $registered_tags;
    }
    $diff = array_diff($options['tag_names'], $registered_tags);
    if (count($diff) > 0) {
        elgg_deprecated_notice('Tag metadata names must be registered by elgg_register_tag_metadata_name()', 1.7);
        // return false;
    }
    $wheres = $options['wheres'];
    // catch for tags that were spaces
    $wheres[] = "msv.string != ''";
    $sanitised_tags = array();
    foreach ($options['tag_names'] as $tag) {
        $sanitised_tags[] = '"' . sanitise_string($tag) . '"';
    }
    $tags_in = implode(',', $sanitised_tags);
    $wheres[] = "(msn.string IN ({$tags_in}))";
    $wheres[] = _elgg_get_entity_type_subtype_where_sql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']);
    $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']);
    // see if any functions failed
    // remove empty strings on successful functions
    foreach ($wheres as $i => $where) {
        if ($where === false) {
            return false;
        } elseif (empty($where)) {
            unset($wheres[$i]);
        }
    }
    // remove identical where clauses
    $wheres = array_unique($wheres);
    $joins = $options['joins'];
    $joins[] = "JOIN {$CONFIG->dbprefix}metadata md on md.entity_guid = e.guid";
    $joins[] = "JOIN {$CONFIG->dbprefix}metastrings msv on msv.id = md.value_id";
    $joins[] = "JOIN {$CONFIG->dbprefix}metastrings msn on md.name_id = msn.id";
    // remove identical join clauses
    $joins = array_unique($joins);
    foreach ($joins as $i => $join) {
        if ($join === false) {
            return false;
        } elseif (empty($join)) {
            unset($joins[$i]);
        }
    }
    $query = "SELECT msv.string as tag, count(msv.id) as total ";
    $query .= "FROM {$CONFIG->dbprefix}entities e ";
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    // Add access controls
    $query .= _elgg_get_access_where_sql();
    $threshold = sanitise_int($options['threshold']);
    $query .= " GROUP BY msv.string HAVING total >= {$threshold} ";
    $query .= " ORDER BY total DESC ";
    $limit = sanitise_int($options['limit']);
    $query .= " LIMIT {$limit} ";
    return get_data($query);
}
Example #7
0
 /**
  * Add tags search clauses
  * @return ElggListQuery
  */
 private function sqlAddTagsSearchQuery($query = '')
 {
     $this->sqlJoinMetadataTable('md')->sqlJoinMetadataValueTable('msv', 'md');
     $tag_names = elgg_get_registered_tag_metadata_names();
     if ($tag_names) {
         $map = self::getMetaMap($tag_names);
         $where_md[] = $this->sqlGetWhereInClause('md', array('name_id'), $map);
         $where_md[] = $this->sqlGetWhereLikeClause('msv', array('string'), $query);
         $where_md[] = $this->sqlGetAccessSuffix('md');
         $where = '(' . implode(' AND ', $where_md) . ')';
     }
     if ($where) {
         $this->sqlAddOption('wheres', $where, 'tags_query');
     }
     return $this;
 }
         $results_html .= elgg_view($view, array('results' => $results, 'params' => $current_params));
         if ($combined_count > $current_params['limit']) {
             $results_html .= '<hr /><div class="elgg-subtext">' . elgg_echo('theme_haarlem_intranet:search:more') . '</div><hr />';
         }
     }
 }
 // determine menu counters
 $db_prefix = elgg_get_config('dbprefix');
 $count_query = "SELECT es.subtype, count(distinct e.guid) as total";
 $count_query .= " FROM {$db_prefix}entities e";
 $count_query .= " JOIN {$db_prefix}objects_entity oe ON e.guid = oe.guid";
 $count_query .= " JOIN {$db_prefix}entity_subtypes es ON e.subtype = es.id";
 $fields = array('title', 'description');
 $where = search_advanced_get_where_sql('oe', $fields, $params);
 // add tags search
 if ($valid_tag_names = elgg_get_registered_tag_metadata_names()) {
     $tag_name_ids = array();
     foreach ($valid_tag_names as $tag_name) {
         $tag_name_ids[] = add_metastring($tag_name);
     }
     $count_query .= " JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
     $count_query .= " JOIN {$db_prefix}metastrings msv ON md.value_id = msv.id";
     $md_where = "((md.name_id IN (" . implode(",", $tag_name_ids) . ")) AND msv.string = '" . sanitise_string($params["query"]) . "')";
 }
 // add wheres
 $count_query .= " WHERE e.type = 'object' AND es.subtype IN ('" . implode("', '", $current_params['subtype']) . "') AND ";
 if ($container_guid) {
     $count_query .= "e.container_guid = " . $container_guid . " AND ";
 }
 if ($md_where) {
     $count_query .= "((" . $where . ") OR (" . $md_where . "))";
/**
 * Loads and displays a tagcloud given particular criteria.
 *
 * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances)
 * @param int $limit Number of tags to return
 * @param string $metadata_name Optionally, the name of the field you want to grab for
 * @param string $entity_type Optionally, the entity type ('object' etc)
 * @param string $entity_subtype The entity subtype, optionally
 * @param int $owner_guid The GUID of the tags owner, optionally
 * @param int $site_guid Optionally, the site to restrict to (default is the current site)
 * @param int $start_ts Optionally specify a start timestamp for tags used to generate cloud.
 * @param int $ent_ts Optionally specify an end timestamp for tags used to generate cloud.
 * @return string THe HTML (or other, depending on view type) of the tagcloud.
 */
function display_tagcloud($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1, $start_ts = "", $end_ts = "")
{
    $registered_tags = elgg_get_registered_tag_metadata_names();
    if (!in_array($metadata_name, $registered_tags)) {
        elgg_deprecated_notice('Tag metadata names must be registered by elgg_register_tag_metadata_name()', 1.7);
    }
    return elgg_view("output/tagcloud", array('value' => get_tags($threshold, $limit, $metadata_name, $entity_type, $entity_subtype, $owner_guid, $site_guid, $start_ts, $end_ts), 'object' => $entity_type, 'subtype' => $entity_subtype));
}
Example #10
0
function elgg_solr_tag_search($hook, $type, $return, $params)
{
    $valid_tag_names = elgg_get_registered_tag_metadata_names();
    if (!$valid_tag_names || !is_array($valid_tag_names)) {
        return array('entities' => array(), 'count' => 0);
    }
    // if passed a tag metadata name, only search on that tag name.
    // tag_name isn't included in the params because it's specific to
    // tag searches.
    if ($tag_names = get_input('tag_names')) {
        if (is_array($tag_names)) {
            $search_tag_names = $tag_names;
        } else {
            $search_tag_names = array($tag_names);
        }
        // check these are valid to avoid arbitrary metadata searches.
        foreach ($search_tag_names as $i => $tag_name) {
            if (!in_array($tag_name, $valid_tag_names)) {
                unset($search_tag_names[$i]);
            }
        }
    } else {
        $search_tag_names = $valid_tag_names;
    }
    $query_parts = array();
    foreach ($search_tag_names as $tagname) {
        // @note - these need to be treated as literal exact matches, so encapsulate in double-quotes
        $query_parts[] = 'tags:"' . elgg_solr_escape_special_chars($tagname . '%%' . $params['query']) . '"';
    }
    if (!$query_parts) {
        return array('entities' => array(), 'count' => 0);
    }
    $q = implode(' OR ', $query_parts);
    $select = array('query' => $q, 'start' => $params['offset'], 'rows' => $params['limit'], 'fields' => array('id', 'title', 'description', 'score'));
    if ($params['select'] && is_array($params['select'])) {
        $select = array_merge($select, $params['select']);
    }
    $client = elgg_solr_get_client();
    // get an update query instance
    $query = $client->createSelect($select);
    $default_sorts = array('score' => 'desc', 'time_created' => 'desc');
    $sorts = $params['sorts'] ? $params['sorts'] : $default_sorts;
    $query->addSorts($sorts);
    $default_fq = elgg_solr_get_default_fq($params);
    if ($params['fq']) {
        $filter_queries = array_merge($default_fq, $params['fq']);
    } else {
        $filter_queries = $default_fq;
    }
    if (!empty($filter_queries)) {
        foreach ($filter_queries as $key => $value) {
            $query->createFilterQuery($key)->setQuery($value);
        }
    }
    // get highlighting component and apply settings
    $hl = $query->getHighlighting();
    $hl->setFields(array('tags'));
    $hl->setSimplePrefix('<span data-hl="elgg-solr">');
    $hl->setSimplePostfix('</span>');
    // this executes the query and returns the result
    try {
        $resultset = $client->select($query);
    } catch (Exception $e) {
        error_log($e->getMessage());
        return null;
    }
    // Get the highlighted snippet
    try {
        $highlighting = $resultset->getHighlighting();
    } catch (Exception $e) {
        error_log($e->getMessage());
        return null;
    }
    // Count the total number of documents found by solr
    $count = $resultset->getNumFound();
    $hl_prefix = elgg_solr_get_hl_prefix();
    $hl_suffix = elgg_solr_get_hl_suffix();
    $search_results = array();
    $config = HTMLPurifier_Config::createDefault();
    $purifier = new HTMLPurifier($config);
    foreach ($resultset as $document) {
        $search_results[$document->id] = array();
        $snippet = '';
        // highlighting results can be fetched by document id (the field defined as uniquekey in this schema)
        $highlightedDoc = $highlighting->getResult($document->id);
        if ($highlightedDoc) {
            foreach ($highlightedDoc as $field => $highlight) {
                // a little hackery for matched tags
                $snippet = array();
                foreach ($highlight as $key => $h) {
                    $matched = $hl_prefix;
                    $matched .= substr(strstr(elgg_strip_tags($h), '%%'), 2);
                    $matched .= $hl_suffix;
                    $snippet[] = $purifier->purify($matched);
                }
                $display = implode(', ', $snippet);
                $search_results[$document->id][$field] = $display;
            }
        }
        $search_results[$document->id]['score'] = $document->score;
    }
    // get the entities
    $entities = array();
    $entities_unsorted = array();
    if ($search_results) {
        $entities_unsorted = elgg_get_entities(array('guids' => array_keys($search_results), 'limit' => false));
    }
    $show_score = elgg_get_plugin_setting('show_score', 'elgg_solr');
    foreach ($search_results as $guid => $matches) {
        foreach ($entities_unsorted as $e) {
            if ($e->guid == $guid) {
                $desc_suffix = '';
                if ($show_score == 'yes' && elgg_is_admin_logged_in()) {
                    $desc_suffix .= elgg_view('output/longtext', array('value' => elgg_echo('elgg_solr:relevancy', array($matches['score'])), 'class' => 'elgg-subtext'));
                }
                $title = $e->title ? $e->title : $e->name;
                $description = $e->description;
                $e->setVolatileData('search_matched_title', $title);
                $e->setVolatileData('search_matched_description', elgg_get_excerpt($description) . $desc_suffix);
                $e->setVolatileData('search_matched_extra', $matches['tags']);
                $entities[] = $e;
            }
        }
    }
    return array('entities' => $entities, 'count' => $count);
}
Example #11
0
function plugin_index($h, $t, $doc, $p)
{
    if (!$doc) {
        return $doc;
        // something else prevented this index
    }
    if (!elgg_instanceof($p['entity'], 'object', 'plugin_project')) {
        return $doc;
    }
    $entity = $p['entity'];
    // add brief description to the full description
    $description = trim($entity->summary . ' ' . $entity->description);
    $doc->description = $description;
    // use generic fields for some filter queries
    // eg.
    $releases = $entity->getReleases(array('limit' => false));
    $elgg_versions = array();
    if ($releases) {
        foreach ($releases as $release) {
            if (is_array($release->elgg_version)) {
                foreach ($release->elgg_version as $version) {
                    $elgg_versions[] = $version;
                }
            } else {
                $elgg_versions[] = $release->elgg_version;
            }
        }
    }
    $screenshots = $entity->getScreenshots();
    $doc->version_ss = array_unique($elgg_versions);
    $doc->plugin_type_s = $entity->plugin_type;
    $doc->plugincat_s = $entity->plugincat;
    $doc->license_s = $entity->license;
    $doc->screenshots_i = $screenshots ? 1 : 0;
    // store category with the tags
    $categoryname = 'plugincat';
    $tag_registered = false;
    $md = elgg_get_registered_tag_metadata_names();
    if ($md && in_array($categoryname, $md)) {
        $tag_registered = true;
    }
    if (!$tag_registered) {
        elgg_register_tag_metadata_name($categoryname);
    }
    $doc->tags = elgg_solr_get_tags_array($entity);
    if (!$tag_registered) {
        // we should unregister it now in case anything else
        // wants to use registered tag names
        elgg_set_config('registered_tag_metadata_names', $md);
    }
    return $doc;
}
Example #12
0
/**
 * Callback function to search valid tags
 *
 * @param string $term Query term
 * @param array $options An array of getter options
 * @return array An array of metadata matching the search criteria
 */
function elgg_tokeninput_search_tags($term, $options = array())
{
    $term = sanitize_string($term);
    // replace mysql vars with escaped strings
    $q = str_replace(array('_', '%'), array('\\_', '\\%'), $term);
    $valid_tag_names = elgg_get_registered_tag_metadata_names();
    $tag_names = urldecode(get_input('tag_names', ''));
    if ($tag_names) {
        if (is_array($tag_names)) {
            $search_tag_names = $tag_names;
        } else {
            $search_tag_names = explode(',', $tag_names);
        }
        foreach ($search_tag_names as $i => $tag_name) {
            if (!in_array($tag_name, $valid_tag_names)) {
                unset($search_tag_names[$i]);
            }
        }
    } else {
        $search_tag_names = $valid_tag_names;
    }
    if (!$search_tag_names) {
        return false;
    }
    $options['metadata_names'] = $search_tag_names;
    $options['group_by'] = "v.string";
    $options['wheres'] = array("v.string LIKE '%{$q}%'");
    return elgg_get_metadata($options);
}
Example #13
0
/**
 * Returns suggested groups
 *
 * @param ElggUser $user  (optional) the user to get the groups for, defaults to the current user
 * @param int      $limit (optional) the number of suggested groups to return, default = 10
 *
 * @return ElggGroup[]
 */
function group_tools_get_suggested_groups($user = null, $limit = null)
{
    if (!$user instanceof ElggUser) {
        $user = elgg_get_logged_in_user_entity();
    }
    if (is_null($limit)) {
        $limit = (int) get_input('limit', 10);
    }
    $limit = sanitize_int($limit, false);
    if (empty($user) || $limit < 1) {
        return [];
    }
    $result = [];
    $dbprefix = elgg_get_config('dbprefix');
    $group_membership_where = "e.guid NOT IN (\n\t\tSELECT er.guid_two FROM {$dbprefix}entity_relationships er\n\t\tWHERE er.guid_one = {$user->getGUID()}\n\t\tAND er.relationship IN (\n\t\t\t'member',\n\t\t\t'membership_request'\n\t\t)\n\t)";
    if (elgg_get_plugin_setting('auto_suggest_groups', 'group_tools') !== 'no') {
        $tag_names = elgg_get_registered_tag_metadata_names();
        if (!empty($tag_names)) {
            $user_metadata_options = ['guid' => $user->getGUID(), 'limit' => false, 'metadata_names' => $tag_names];
            // get metadata
            $user_values = elgg_get_metadata($user_metadata_options);
            if (!empty($user_values)) {
                // transform to values
                $user_values = metadata_array_to_values($user_values);
                // find group with these metadatavalues
                $group_options = ['type' => 'group', 'metadata_names' => $tag_names, 'metadata_values' => $user_values, 'wheres' => $group_membership_where, 'group_by' => 'e.guid', 'order_by' => 'count(msn.id) DESC', 'limit' => $limit];
                $groups = elgg_get_entities_from_metadata($group_options);
                if (!empty($groups)) {
                    foreach ($groups as $group) {
                        $result[$group->getGUID()] = $group;
                        $limit--;
                    }
                }
            }
        }
    }
    // get admin defined suggested groups
    if ($limit > 0) {
        $group_guids = string_to_tag_array(elgg_get_plugin_setting('suggested_groups', 'group_tools'));
        if (!empty($group_guids)) {
            $group_options = ['guids' => $group_guids, 'type' => 'group', 'wheres' => [$group_membership_where], 'limit' => $limit];
            if (!empty($result)) {
                $suggested_guids = array_keys($result);
                $group_options['wheres'][] = 'e.guid NOT IN (' . implode(',', $suggested_guids) . ')';
            }
            $groups = elgg_get_entities($group_options);
            if (!empty($groups)) {
                foreach ($groups as $group) {
                    $result[$group->getGUID()] = $group;
                }
            }
        }
    }
    return $result;
}
Example #14
0
/**
 * Return default results for searches on everything
 *
 * @param string       $hook   name of hook
 * @param string       $type   type of hook
 * @param unknown_type $value  current value
 * @param array        $params parameters
 *
 * @return array
 */
function search_advanced_combined_all_hook($hook, $type, $value, $params)
{
    if (!empty($value)) {
        return;
    }
    if (elgg_get_plugin_setting('search_hooks_enabled', 'search_advanced', 'yes') == 'no') {
        return;
    }
    static $tag_name_ids;
    static $tag_value_ids;
    static $valid_tag_names;
    $return_only_count = elgg_extract('count', $params, false);
    $query_parts = (array) search_advanced_tag_query_to_array($params['query']);
    if (empty($params['query']) || empty($query_parts)) {
        return ['entities' => [], 'count' => 0];
    }
    if (!isset($tag_name_ids)) {
        $tag_name_ids = false;
        if ($valid_tag_names = elgg_get_registered_tag_metadata_names()) {
            $tag_name_ids = search_advanced_get_metastring_ids($valid_tag_names);
        }
    }
    $params['joins'] = elgg_extract('joins', $params, []);
    $db_prefix = elgg_get_config('dbprefix');
    $types = elgg_extract('type_subtype_pairs', $params);
    $wheres = [];
    foreach ($types as $entity_type => $entity_subtypes) {
        switch ($entity_type) {
            case 'object':
                $params["joins"][] = "LEFT OUTER JOIN {$db_prefix}objects_entity oe ON e.guid = oe.guid";
                $fields = ['title', 'description'];
                $wheres[] = search_advanced_get_where_sql('oe', $fields, $params, false);
                break;
            case 'user':
                $params["joins"][] = "LEFT OUTER JOIN {$db_prefix}users_entity ue ON e.guid = ue.guid";
                $fields = ['username', 'name'];
                $wheres[] = search_advanced_get_where_sql('ue', $fields, $params, false);
                break;
            case 'group':
                $params["joins"][] = "LEFT OUTER JOIN {$db_prefix}groups_entity ge ON e.guid = ge.guid";
                $fields = ['name', 'description'];
                $wheres[] = search_advanced_get_where_sql('ge', $fields, $params, false);
                break;
        }
    }
    $where = '(' . implode(' OR ', $wheres) . ')';
    $params["wheres"] = elgg_extract("wheres", $params, []);
    if ($tag_name_ids) {
        // look up value ids to save a join
        if (!isset($tag_value_ids)) {
            $tag_value_ids = search_advanced_get_metastring_ids($query_parts);
        }
        if (empty($tag_value_ids)) {
            $params['wheres'][] = $where;
        } else {
            $params["joins"][] = "LEFT OUTER JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
            $md_where = "((md.name_id IN (" . implode(",", $tag_name_ids) . ")) AND md.value_id IN (" . implode(",", $tag_value_ids) . "))";
            $params['wheres'][] = "(({$where}) OR ({$md_where}))";
        }
    } else {
        $params['wheres'][] = $where;
    }
    $params['count'] = true;
    $count = elgg_get_entities($params);
    // no need to continue if nothing here.
    if (!$count || $return_only_count) {
        return ['entities' => [], 'count' => $count];
    }
    $params['count'] = false;
    $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->title, $params['query']);
        $entity->setVolatileData('search_matched_title', $title);
        $desc = search_get_highlighted_relevant_substrings($entity->description, $params['query']);
        $entity->setVolatileData('search_matched_description', $desc);
        if (empty($valid_tag_names)) {
            continue;
        }
        $matched_tags_strs = [];
        // get tags for each tag name requested to find which ones matched.
        foreach ($valid_tag_names as $tag_name) {
            $tags = $entity->getTags($tag_name);
            // @todo make one long tag string and run this through the highlight
            // function.  This might be confusing as it could chop off
            // the tag labels.
            foreach ($query_parts as $part) {
                if (in_array(strtolower($part), array_map('strtolower', $tags))) {
                    if (is_array($tags)) {
                        $tag_name_str = elgg_echo("tag_names:{$tag_name}");
                        $matched_tags_strs[] = "{$tag_name_str}: " . implode(', ', $tags);
                        // only need it once for each tag
                        break;
                    }
                }
            }
        }
        $tags_str = implode('. ', $matched_tags_strs);
        $tags_str = search_get_highlighted_relevant_substrings($tags_str, $params['query']);
        $entity->setVolatileData('search_matched_extra', $tags_str);
    }
    return ['entities' => $entities, 'count' => $count];
}
Example #15
0
/**
 * Return default results for searches on objects.
 *
 * @param string       $hook   name of hook
 * @param string       $type   type of hook
 * @param unknown_type $value  current value
 * @param array        $params parameters
 *
 * @return array
 */
function search_advanced_objects_hook($hook, $type, $value, $params)
{
    static $tag_name_ids;
    static $tag_value_ids;
    static $valid_tag_names;
    $db_prefix = elgg_get_config('dbprefix');
    $query = sanitise_string($params['query']);
    if (!isset($tag_name_ids)) {
        if ($valid_tag_names = elgg_get_registered_tag_metadata_names()) {
            $tag_name_ids = array();
            foreach ($valid_tag_names as $tag_name) {
                $tag_name_ids[] = elgg_get_metastring_id($tag_name);
            }
        } else {
            $tag_name_ids = false;
        }
    }
    $params["joins"] = elgg_extract("joins", $params, array());
    if ($tag_name_ids) {
        $params["joins"][] = "JOIN {$db_prefix}objects_entity oe ON e.guid = oe.guid";
    } else {
        $params["joins"][] = "JOIN {$db_prefix}objects_entity oe ON e.guid = oe.guid";
    }
    $fields = array('title', 'description');
    if ($params["subtype"] === "page") {
        $params["subtype"] = array("page", "page_top");
    }
    if ($params["subtype"] === "groupforumtopic") {
        $params["subtype"] = array("groupforumtopic", "discussion_reply");
    }
    $where = search_advanced_get_where_sql('oe', $fields, $params, FALSE);
    $params["wheres"] = elgg_extract("wheres", $params, array());
    if ($tag_name_ids) {
        $query_parts = array();
        if (elgg_get_plugin_setting("enable_multi_tag", "search_advanced") == "yes") {
            $separator = elgg_get_plugin_setting("multi_tag_separator", "search_advanced", "comma");
            if ($separator == "comma") {
                $query_array = explode(",", $query);
            } else {
                $query_array = explode(" ", $query);
            }
            foreach ($query_array as $query_value) {
                $query_value = trim($query_value);
                if (!empty($query_value)) {
                    $query_parts[] = $query_value;
                }
            }
        } else {
            $query_parts[] = $query;
        }
        // look up value ids to save a join
        if (!isset($tag_value_ids)) {
            $tag_value_ids = array();
            foreach ($query_parts as $query_part) {
                $metastring_ids = elgg_get_metastring_id($query_part, false);
                if (!is_array($metastring_ids)) {
                    $metastring_ids = array($metastring_ids);
                }
                $tag_value_ids = array_merge($tag_value_ids, $metastring_ids);
            }
        }
        if (empty($tag_value_ids)) {
            $params['wheres'][] = $where;
        } else {
            $params["joins"][] = "LEFT OUTER JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
            $md_where = "((md.name_id IN (" . implode(",", $tag_name_ids) . ")) AND md.value_id IN (" . implode(",", $tag_value_ids) . "))";
            $params['wheres'][] = "(({$where}) OR ({$md_where}))";
        }
    } else {
        $params['wheres'][] = $where;
    }
    $params['count'] = TRUE;
    $count = elgg_get_entities($params);
    // no need to continue if nothing here.
    if (!$count || $params["search_advanced_count_only"] == true) {
        return array('entities' => array(), 'count' => $count);
    }
    $params['count'] = FALSE;
    $entities = elgg_get_entities($params);
    // add the volatile data for why these entities have been returned.
    foreach ($entities as $entity) {
        if ($valid_tag_names) {
            $matched_tags_strs = array();
            // get tags for each tag name requested to find which ones matched.
            foreach ($valid_tag_names as $tag_name) {
                $tags = $entity->getTags($tag_name);
                // @todo make one long tag string and run this through the highlight
                // function.  This might be confusing as it could chop off
                // the tag labels.
                if (isset($query_parts)) {
                    foreach ($query_parts as $part) {
                        if (in_array(strtolower($part), array_map('strtolower', $tags))) {
                            if (is_array($tags)) {
                                $tag_name_str = elgg_echo("tag_names:{$tag_name}");
                                $matched_tags_strs[] = "{$tag_name_str}: " . implode(', ', $tags);
                                // only need it once for each tag
                                break;
                            }
                        }
                    }
                }
            }
            $tags_str = implode('. ', $matched_tags_strs);
            $tags_str = search_get_highlighted_relevant_substrings($tags_str, $params['query']);
            $entity->setVolatileData('search_matched_extra', $tags_str);
        }
        $title = search_get_highlighted_relevant_substrings($entity->title, $params['query']);
        $entity->setVolatileData('search_matched_title', $title);
        $desc = search_get_highlighted_relevant_substrings($entity->description, $params['query']);
        $entity->setVolatileData('search_matched_description', $desc);
    }
    return array('entities' => $entities, 'count' => $count);
}