/** * 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; }
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; }
/** * 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; }
/** * 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); }
/** * {@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); }
/** * 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)); }
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); }
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; }
/** * 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); }
/** * 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; }
/** * 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]; }
/** * 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); }