function search_by_proximity_hook($hook, $type, $return, $params) { $query = $params['query']; $coords = elgg_geocode_location($query); if (!$coords) { return $return; } $registered_entities = elgg_get_config('registered_entities'); $options = array('types' => array('object', 'user', 'group'), 'subtypes' => array_merge($registered_entities['object'], $registered_entities['user'], $registered_entities['group']), 'limit' => get_input('limit', 20), 'offset' => get_input('proximity_offset', 0), 'offset_key' => 'proximity_offset', 'count' => true); $options = add_order_by_proximity_clauses($options, $coords['lat'], $coords['long']); $options = add_distance_constraint_clauses($options, $coords['lat'], $coords['long'], SEARCH_RADIUS); $count = elgg_get_entities($options); if ($count) { $options['count'] = false; $entities = elgg_get_entities($options); } if ($entities) { foreach ($entities as $entity) { $name = search_get_highlighted_relevant_substrings(isset($entity->name) ? $entity->name : $entity->title, $query); $entity->setVolatileData('search_matched_title', $name); $location = search_get_highlighted_relevant_substrings($entity->getLocation(), $query); $entity->setVolatileData('search_matched_location', $location); $distance = get_distance($entity->getLatitude(), $entity->getLongitude(), $coords['lat'], $coords['long']); // distance in metres $distance = round($distance / 1000, 2); // distance in km $distance_str = elgg_echo('geo:search:proximity', array($query, $distance)); $entity->setVolatileData('search_proximity', $distance_str); } } return array('entities' => $entities, 'count' => $count); }
$subtitle['last_action'] = elgg_echo('user:membership:last_action', [elgg_get_friendly_time($last_action)]); } $menu_params = $vars; $menu_params['sort_by'] = 'priority'; $menu_params['class'] = 'elgg-menu-user-membership'; $menu = elgg_view_menu('membership', $menu_params); $metadata = ''; if (!elgg_in_context('widgets')) { $menu_params['class'] = 'elgg-menu-hz'; $metadata = elgg_view_menu('entity', $menu_params); } $title = null; $query = elgg_extract('query', $vars, get_input('query')); if ($query && elgg_is_active_plugin('search')) { $name = search_get_highlighted_relevant_substrings($entity->getDisplayName(), $query); $username = search_get_highlighted_relevant_substrings(strtolower($entity->username), $query); $title = elgg_view('output/url', array('href' => $entity->getURL(), 'text' => "{$name} (<small>@{$username}</small>)")); } $subtitle = elgg_trigger_plugin_hook('subtitle', 'user', $vars, $subtitle); $subtitle_str = ''; foreach ($subtitle as $s) { $subtitle_str .= elgg_format_element('span', ['class' => 'elgg-member-subtitle-element'], $s); } if ($entity->briefdescription) { $view_subtitle = $subtitle_str . '<br />' . $entity->briefdescription; } else { $view_subtitle = $subtitle_str; } $icon = elgg_view_entity_icon($entity, $size); $summary = elgg_view('user/elements/summary', array('entity' => $entity, 'title' => $title, 'metadata' => $metadata, 'content' => $menu, 'subtitle' => $view_subtitle)); echo elgg_view_image_block($icon, $summary, array('class' => 'elgg-user-member'));
<?php $size = elgg_extract('size', $vars, 'small'); $entity = elgg_extract('entity', $vars); if (!$entity instanceof ElggGroup) { return; } $menu_params = $vars; $menu_params['sort_by'] = 'priority'; $menu_params['class'] = 'elgg-menu-group-membership'; $menu = elgg_view_menu('membership', $menu_params); $metadata = ''; if (!elgg_in_context('widgets')) { $menu_params['class'] = 'elgg-menu-hz'; $metadata = elgg_view_menu('entity', $menu_params); } $title = null; $query = elgg_extract('query', $vars, get_input('query')); if ($query && elgg_is_active_plugin('search')) { $name = search_get_highlighted_relevant_substrings($entity->getDisplayName(), $query); $title = elgg_view('output/url', array('href' => $entity->getURL(), 'text' => $name)); } $icon = elgg_view_entity_icon($entity, $size); $summary = elgg_view('group/elements/summary', array('entity' => $entity, 'title' => $title, 'metadata' => $metadata, 'subtitle' => $entity->briefdescription, 'content' => $menu)); echo elgg_view_image_block($icon, $summary, array('class' => 'elgg-group')); ?> <script> require(['group/format/membership']); </script>
<?php $full = elgg_extract('full_view', $vars, false); if ($full) { return; } $entity = elgg_extract('entity', $vars); if ($entity->title) { if (elgg_is_active_plugin('search') && get_input('query')) { if ($entity->getVolatileData('search_matched_title')) { $title = $entity->getVolatileData('search_matched_title'); } else { $title = search_get_highlighted_relevant_substrings($entity->getDisplayName(), get_input('query'), 5, 5000); } } else { $title = $entity->title; } echo elgg_format_element('span', array('class' => 'inbox-message-subject'), $title); }
/** * Plugin project search hook * * @param string $hook * @param string $type * @param <type> $value * @param <type> $params * @return array */ function plugins_search_hook($hook, $type, $value, $params) { global $CONFIG; $query = sanitise_string($params['query']); $join = "JOIN {$CONFIG->dbprefix}objects_entity oe ON e.guid = oe.guid"; $params['joins'] = array($join); $params['joins'][] = "JOIN {$CONFIG->dbprefix}metadata summary_md on e.guid = summary_md.entity_guid"; $params['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings summary_msn on summary_md.name_id = summary_msn.id"; $params['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings summary_msv on summary_md.value_id = summary_msv.id"; $fields = array('title', 'description'); $where = search_get_where_sql('oe', $fields, $params); // cheat and use LIKE for the summary field // this is kinda dirty. $likes = array(); $query_arr = explode(' ', $query); foreach ($query_arr as $word) { $likes[] = "summary_msv.string LIKE \"%{$word}%\""; } $like_str = implode(' OR ', $likes); //$params['wheres'] = array("($where OR ($like_str))"); $params['wheres'] = array($where); // If metastrings were fulltext'd we could do this :( // $select = "summary_msv.string summary_string"; // $params['selects'] = array($select); // // $fields = array('string'); // $summary_where = search_get_where_sql('summary_msv', $fields, $params); // $params['wheres'][] = $summary_where; if (($category = get_input('category')) && $category != 'all') { $params['metadata_name_value_pair'] = array('name' => 'plugincat', 'value' => $category, 'case_sensitive' => FALSE); } $params['order_by'] = search_get_order_by_sql('e', 'oe', $params['sort'], $params['order']); $entities = elgg_get_entities_from_metadata($params); $params['count'] = TRUE; $count = elgg_get_entities_from_metadata($params); // no need to continue if nothing here. if (!$count) { return array('entities' => array(), 'count' => $count); } // 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->summary, $params['query']); $entity->setVolatileData('search_matched_description', $desc); } return array('entities' => $entities, 'count' => $count); }
$title = elgg_view('output/url', array('href' => $topic->getURL(), 'text' => $topic->getDisplayName() . $status_indicator)); $subtitle = "{$by_line} {$replies_link}"; $params = array('entity' => $topic, 'title' => false, 'metadata' => $metadata, 'subtitle' => $subtitle, 'tags' => $tags); $params = $params + $vars; $summary = elgg_view('object/elements/summary', $params); $body = elgg_view('output/longtext', array('value' => $topic->description, 'class' => 'elgg-discussion-body clearfix')); echo elgg_view('object/elements/full', array('entity' => $topic, 'summary' => $summary, 'icon' => $poster_icon, 'body' => $body)); } else { if (elgg_is_active_plugin('search') && get_input('query')) { if ($topic->getVolatileData('search_matched_title')) { $title = $topic->getVolatileData('search_matched_title'); } else { $title = search_get_highlighted_relevant_substrings($topic->getDisplayName(), get_input('query'), 5, 5000); } if ($topic->getVolatileData('search_matched_description')) { $excerpt = $topic->getVolatileData('search_matched_description'); } else { $excerpt = search_get_highlighted_relevant_substrings($topic->description, get_input('query'), 5, 5000); } } else { $title = $topic->getDisplayName(); $excerpt = elgg_get_excerpt($topic->description); } $title = elgg_view('output/url', array('href' => $topic->getURL(), 'text' => $title . $status_indicator)); // brief view $subtitle = "{$by_line} {$replies_link} <span class=\"float-alt\">{$reply_text}</span>"; $params = array('entity' => $topic, 'title' => $title, 'metadata' => $metadata, 'subtitle' => $subtitle, 'tags' => $tags, 'content' => $excerpt); $params = $params + $vars; $list_body = elgg_view('object/elements/summary', $params); echo elgg_view_image_block($poster_icon, $list_body); }
/** * NOTE - this is only used in Elgg 1.8 as comments are annotations * * @param type $hook * @param type $type * @param type $return * @param type $params * @return null */ function elgg_solr_comment_search($hook, $type, $return, $params) { $entities = array(); $select = array('start' => $params['offset'], 'rows' => $params['limit'] ? $params['limit'] : 10, 'fields' => array('id', 'container_guid', 'description', 'owner_guid', 'time_created', 'score')); if ($params['select'] && is_array($params['select'])) { $select = array_merge($select, $params['select']); } // create a client instance $client = elgg_solr_get_client(); // get an update query instance $query = $client->createSelect($select); $default_sort = array('score' => 'desc', 'time_created' => 'desc'); $sorts = $params['sorts'] ? $params['sorts'] : $default_sort; $query->addSorts($sorts); $description_boost = elgg_solr_get_description_boost(); // get the dismax component and set a boost query $dismax = $query->getEDisMax(); $qf = "description^{$description_boost}"; if ($params['qf']) { $qf = $params['qf']; } $dismax->setQueryFields($qf); $boostQuery = elgg_solr_get_boost_query(); if ($boostQuery) { $dismax->setBoostQuery($boostQuery); } // this query is now a dismax query $query->setQuery($params['query']); // make sure we're only getting comments $params['fq']['type'] = 'type:annotation'; $params['fq']['subtype'] = 'subtype:generic_comment'; $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('description')); $hl->setSimplePrefix('<span data-hl="elgg-solr">'); $hl->setSimplePostfix('</span>'); $fragsize = elgg_solr_get_fragsize(); if (isset($params['fragsize'])) { $fragsize = (int) $params['fragsize']; } $hl->setFragSize($fragsize); // 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(); $show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); $config = HTMLPurifier_Config::createDefault(); $purifier = new HTMLPurifier($config); foreach ($resultset as $document) { // comments entity_guid stored as container_guid in solr $entity = get_entity($document->container_guid); if (!$entity) { $entity = new ElggObject(); $entity->setVolatileData('search_unavailable_entity', TRUE); } // 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 $highlight) { $snippet = implode(' (...) ', $highlight); // get our highlight based on the wrapped tokens // note, this is to prevent partial html from breaking page layouts $match = array(); preg_match('/<span data-hl="elgg-solr">(.*)<\\/span>/', $snippet, $match); if ($match[1]) { $snippet = str_replace($match[1], $hl_prefix . $match[1] . $hl_suffix, $snippet); $snippet = $purifier->purify($snippet); } } } if (!$snippet) { $snippet = search_get_highlighted_relevant_substrings(elgg_get_excerpt($document->description), $params['query']); } if ($show_score == 'yes' && elgg_is_admin_logged_in()) { $snippet .= elgg_view('output/longtext', array('value' => elgg_echo('elgg_solr:relevancy', array($document->score)), 'class' => 'elgg-subtext')); } $comments_data = $entity->getVolatileData('search_comments_data'); if (!$comments_data) { $comments_data = array(); } $comments_data[] = array('annotation_id' => substr(strstr(elgg_strip_tags($document->id), ':'), 1), 'text' => $snippet, 'owner_guid' => $document->owner_guid, 'time_created' => $document->time_created); $entity->setVolatileData('search_comments_data', $comments_data); $entities[] = $entity; } return array('entities' => $entities, 'count' => $count); }
/** * Return default results for searches on users. * * @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_users_hook($hook, $type, $value, $params) { if (!empty($value)) { return; } if (elgg_get_plugin_setting('search_hooks_enabled', 'search_advanced', 'yes') == 'no') { return; } $return_only_count = elgg_extract('count', $params, false); $db_prefix = elgg_get_config('dbprefix'); $params['joins'] = ["JOIN {$db_prefix}users_entity ue ON e.guid = ue.guid"]; if (isset($params["container_guid"])) { $container_entity = get_entity($params["container_guid"]); } if (isset($container_entity) && $container_entity instanceof ElggGroup) { // check for group membership relation $params["relationship"] = "member"; $params["relationship_guid"] = $params["container_guid"]; $params["inverse_relationship"] = false; unset($params["container_guid"]); } else { // check for site relation ship $params["relationship"] = "member_of_site"; $params["relationship_guid"] = elgg_get_site_entity()->getGUID(); $params["inverse_relationship"] = true; } $i = 0; if (!empty($params["query"])) { $query_parts = (array) search_advanced_tag_query_to_array($params['query']); if (empty($query_parts)) { return ['entities' => [], 'count' => 0]; } $fields = array('username', 'name'); $where = search_advanced_get_where_sql('ue', $fields, $params, FALSE); // profile fields $profile_fields = array_keys(elgg_get_config('profile_fields')); if (!empty($profile_fields)) { $profile_field_metadata_search_values = elgg_get_plugin_setting("user_profile_fields_metadata_search", "search_advanced", array()); if (!empty($profile_field_metadata_search_values)) { $profile_field_metadata_search_values = json_decode($profile_field_metadata_search_values, true); } foreach ($profile_fields as $key => $field) { if (in_array($field, $profile_field_metadata_search_values)) { unset($profile_fields[$key]); } } $tag_name_ids = search_advanced_get_metastring_ids($profile_fields); if (!empty($tag_name_ids)) { $likes = []; foreach ($query_parts as $query_value) { $query_value = sanitise_string($query_value); if (!empty($query_value)) { $likes[] = "msv{$i}.string LIKE '%{$query_value}%'"; } } $params["joins"][] = "JOIN {$db_prefix}metadata md{$i} on e.guid = md{$i}.entity_guid"; $params["joins"][] = "JOIN {$db_prefix}metastrings msv{$i} ON md{$i}.value_id = msv{$i}.id"; $md_where = "((md{$i}.name_id IN (" . implode(",", $tag_name_ids) . ")) AND (" . implode(" OR ", $likes) . "))"; $where = "(({$where}) OR ({$md_where}))"; $i++; } } $params['wheres'] = array($where); } // additional filters $search_filter = elgg_extract('search_filter', $params); if (!empty($search_filter)) { // on profile fields? $profile_fields = elgg_extract('profile_fields', $search_filter); if (!empty($profile_fields)) { $profile_field_likes = []; // use soundex on some fields $profile_soundex = elgg_extract('profile_fields_soundex', $search_filter); foreach ($profile_fields as $field_name => $field_value) { $field_value = trim(sanitise_string($field_value)); if (!empty($field_value)) { $tag_name_id = elgg_get_metastring_id($field_name); $params["joins"][] = "JOIN {$db_prefix}metadata md{$i} on e.guid = md{$i}.entity_guid"; $params["joins"][] = "JOIN {$db_prefix}metastrings msv{$i} ON md{$i}.value_id = msv{$i}.id"; // do a soundex match if (is_array($profile_soundex) && in_array($field_name, $profile_soundex)) { $profile_field_likes[] = "md{$i}.name_id = {$tag_name_id} AND soundex(CONCAT('X', msv{$i}.string)) = soundex(CONCAT('X','{$field_value}'))"; } else { $profile_field_likes[] = "md{$i}.name_id = {$tag_name_id} AND msv{$i}.string LIKE '%{$field_value}%'"; } $i++; } } if (!empty($profile_field_likes)) { $profile_field_where = "(" . implode(" AND ", $profile_field_likes) . ")"; if (empty($params["wheres"])) { $params["wheres"] = array($profile_field_where); } else { $params["wheres"] = array($params["wheres"][0] . " AND " . $profile_field_where); } } } } if (empty($params['wheres'])) { return ['entities' => [], 'count' => 0]; } $wheres = (array) elgg_extract("wheres", $params); $wheres[] = "ue.banned = 'no'"; $params["wheres"] = $wheres; // override subtype -- All users should be returned regardless of subtype. $params['subtype'] = ELGG_ENTITIES_ANY_VALUE; $params['count'] = true; $count = elgg_get_entities_from_relationship($params); // no need to continue if nothing here. if (!$count || $return_only_count) { return ['entities' => [], 'count' => $count]; } $params['count'] = false; $entities = elgg_get_entities_from_relationship($params); $query = sanitise_string($params['query']); // add the volatile data for why these entities have been returned. foreach ($entities as $entity) { $name = search_get_highlighted_relevant_substrings($entity->name, $query); $entity->setVolatileData('search_matched_title', $name); $username = search_get_highlighted_relevant_substrings($entity->username, $query); $entity->setVolatileData('search_matched_description', $username); } return ['entities' => $entities, 'count' => $count]; }
$display_name = elgg_get_excerpt($entity->description, 50); } if ($query) { $title = search_get_highlighted_relevant_substrings($display_name, $query); $entity->setVolatileData('search_matched_title', $title); } else { $entity->setVolatileData('search_matched_title', $display_name); } $flag = ''; if ($entity->badwords) { $flag = elgg_view_icon('inbox-monitor-red-flag'); } $title = elgg_view('output/url', array('text' => $entity->getVolatileData('search_matched_title'), 'href' => $entity->getURL())); $content .= elgg_format_element('strong', array('class' => $entity->badwords ? 'inbox-monitor-flagged' : ''), $flag . $title); if ($query) { $desc = search_get_highlighted_relevant_substrings($entity->description, $query); $entity->setVolatileData('search_matched_description', '<div>' . $desc . '</div>'); } else { $desc = elgg_view('output/longtext', array('value' => $entity->description)); $entity->setVolatileData('search_matched_description', $desc); } $content .= $entity->getVolatileData('search_matched_description'); $subtitle = elgg_echo('inbox:monitor:subtitle', array($sender->getDisplayName(), $recipient->getDisplayName(), elgg_view_friendly_time($entity->time_created))); $metadata = elgg_view_menu('entity', array('entity' => $entity, 'sort_by' => 'priority', 'class' => 'elgg-menu-hz')); $sender_icon = elgg_view_entity_icon($sender, $size); $recipient_icon = elgg_view_entity_icon($recipient, $size); $summary = elgg_view("{$type}/elements/summary", array('entity' => $entity, 'tags' => false, 'title' => false, 'subtitle' => $subtitle, 'content' => $content, 'metadata' => $metadata)); $checkbox = elgg_format_element('input', array('type' => 'checkbox', 'name' => 'guids[]', 'value' => $entity->guid, 'class' => 'inbox-monitor-checkbox')); $image = $checkbox . $sender_icon . elgg_view_icon('inbox-monitor-to') . $recipient_icon; $view = elgg_view_image_block($image, $summary); ?>
/** * Get groups 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 group_subtypes_search_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}groups_entity ge ON e.guid = ge.guid"; array_unshift($params['joins'], $join); $fields = array('name', 'description'); $where = search_get_where_sql('ge', $fields, $params); $params['wheres'][] = $where; $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', 'ge', $params['sort'], $params['order']); } $entities = elgg_get_entities($params); // add the volatile data for why these entities have been returned. foreach ($entities as $entity) { $name = search_get_highlighted_relevant_substrings($entity->name, $query); $entity->setVolatileData('search_matched_title', $name); $description = search_get_highlighted_relevant_substrings($entity->description, $query); $entity->setVolatileData('search_matched_description', $description); } return array('entities' => $entities, 'count' => $count); }
function plugin_search($hook, $type, $return, $params) { $select = array('start' => $params['offset'], 'rows' => $params['limit'], 'fields' => array('id', 'title', 'description')); if ($params['select'] && is_array($params['select'])) { $select = array_merge($select, $params['select']); } // create a client instance $client = elgg_solr_get_client(); // get an update query instance $query = $client->createSelect($select); $sorts = array('score' => 'desc', 'time_created' => 'desc'); if ($params['sorts'] && is_array($params['sorts'])) { $sorts = $params['sorts']; } $query->addSorts($sorts); $title_boost = elgg_solr_get_title_boost(); $description_boost = elgg_solr_get_description_boost(); // get the dismax component and set a boost query $dismax = $query->getDisMax(); $qf = "title^{$title_boost} description^{$description_boost}"; if ($params['qf']) { $qf = $params['qf']; } $dismax->setQueryFields($qf); $dismax->setQueryAlternative('*:*'); $boostQuery = elgg_solr_get_boost_query(); if ($boostQuery) { $dismax->setBoostQuery($boostQuery); } // this query is now a dismax query $query->setQuery($params['query']); // make sure we're only getting objects:plugin_project $params['fq']['type'] = 'type:object'; $params['fq']['subtype'] = 'subtype:plugin_project'; if (($category = get_input('category')) && $category != 'all') { $params['fq']['plugincat'] = 'tags:"' . elgg_solr_escape_special_chars('plugincat%%' . $category) . '"'; } $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('title', 'description')); $hl->setSimplePrefix('<strong class="search-highlight search-highlight-color1">'); $hl->setSimplePostfix('</strong>'); // 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(); $search_results = array(); 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) { $snippet = implode(' (...) ', $highlight); $snippet = search_get_highlighted_relevant_substrings(elgg_strip_tags($snippet), $params['query']); $search_results[$document->id][$field] = $snippet; } } } // get the entities $entities = array(); $entities_unsorted = array(); if ($search_results) { $entities_unsorted = elgg_get_entities(array('guids' => array_keys($search_results), 'limit' => false)); } foreach ($search_results as $guid => $matches) { foreach ($entities_unsorted as $e) { if ($e->guid == $guid) { if ($matches['title']) { $e->setVolatileData('search_matched_title', $matches['title']); } else { $e->setVolatileData('search_matched_title', $e->title); } if ($matches['description']) { $e->setVolatileData('search_matched_description', $matches['description']); } else { $e->setVolatileData('search_matched_description', elgg_get_excerpt($e->description, 100)); } $entities[] = $e; } } } return array('entities' => $entities, 'count' => $count); }
/** * Allow subsites to be found when searching * * @param string $hook * @param string $type * @param mixed $returnvalue * @param mixed $params * @return mixed */ function subsite_manager_search_subsite_hook($hook, $type, $returnvalue, $params) { $join = "JOIN " . get_config("dbprefix") . "sites_entity se ON e.guid = se.guid"; $params['joins'] = array($join); $fields = array('name', 'description', 'url'); $where = search_get_where_sql('se', $fields, $params, FALSE); $params['wheres'] = array($where); $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; $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, $params['query']); $entity->setVolatileData('search_matched_title', $title); $desc = search_get_highlighted_relevant_substrings($entity->description, $params['query']); $entity->setVolatileData('search_matched_description', $desc); $icon = elgg_view_entity_icon($entity, 'tiny'); $entity->setVolatileData("search_icon", $icon); } return array('entities' => $entities, 'count' => $count); }
/** * Return default results for searches on comments. * * @param unknown_type $hook * @param unknown_type $type * @param unknown_type $value * @param unknown_type $params * @return unknown_type */ function search_comments_hook($hook, $type, $value, $params) { global $CONFIG; $query = sanitise_string($params['query']); $params['annotation_names'] = array('generic_comment', 'group_topic_post'); $params['joins'] = array("JOIN {$CONFIG->dbprefix}annotations a on e.guid = a.entity_guid", "JOIN {$CONFIG->dbprefix}metastrings msn on a.name_id = msn.id", "JOIN {$CONFIG->dbprefix}metastrings msv on a.value_id = msv.id"); $fields = array('string'); // force IN BOOLEAN MODE since fulltext isn't // available on metastrings (and boolean mode doesn't need it) $search_where = search_get_where_sql('msv', $fields, $params, FALSE); $e_access = get_access_sql_suffix('e'); $a_access = get_access_sql_suffix('a'); // @todo this can probably be done through the api.. $q = "SELECT DISTINCT a.*, msv.string as comment FROM {$CONFIG->dbprefix}annotations a\n\t\tJOIN {$CONFIG->dbprefix}metastrings msn ON a.name_id = msn.id\n\t\tJOIN {$CONFIG->dbprefix}metastrings msv ON a.value_id = msv.id\n\t\tJOIN {$CONFIG->dbprefix}entities e ON a.entity_guid = e.guid\n\t\tWHERE msn.string IN ('generic_comment', 'group_topic_post')\n\t\t\tAND ({$search_where})\n\t\t\tAND {$e_access}\n\t\t\tAND {$a_access}\n\n\t\tLIMIT {$params['offset']}, {$params['limit']}\n\t\t"; $comments = get_data($q); $q = "SELECT count(DISTINCT a.id) as total FROM {$CONFIG->dbprefix}annotations a\n\t\tJOIN {$CONFIG->dbprefix}metastrings msn ON a.name_id = msn.id\n\t\tJOIN {$CONFIG->dbprefix}metastrings msv ON a.value_id = msv.id\n\t\tJOIN {$CONFIG->dbprefix}entities e ON a.entity_guid = e.guid\n\t\tWHERE msn.string IN ('generic_comment', 'group_topic_post')\n\t\t\tAND ({$search_where})\n\t\t\tAND {$e_access}\n\t\t\tAND {$a_access}\n\t\t"; $result = get_data($q); $count = $result[0]->total; if (!is_array($comments)) { return FALSE; } // @todo if plugins are disabled causing subtypes // to be invalid and there are comments on entities of those subtypes, // the counts will be wrong here and results might not show up correctly, // especially on the search landing page, which only pulls out two results. // probably better to check against valid subtypes than to do what I'm doing. // need to return actual entities // add the volatile data for why these entities have been returned. $entities = array(); foreach ($comments as $comment) { $entity = get_entity($comment->entity_guid); // hic sunt dracones if (!$entity) { //continue; $entity = new ElggObject(); $entity->setVolatileData('search_unavailable_entity', TRUE); } $comment_str = search_get_highlighted_relevant_substrings($comment->comment, $query); $entity->setVolatileData('search_match_annotation_id', $comment->id); $entity->setVolatileData('search_matched_comment', $comment_str); $entity->setVolatileData('search_matched_comment_owner_guid', $comment->owner_guid); $entity->setVolatileData('search_matched_comment_time_created', $comment->time_created); $entities[] = $entity; } return array('entities' => $entities, 'count' => $count); }
<?php namespace hypeJunction\Interactions; $entity = elgg_extract('entity', $vars); /* @var $entity Comment */ if (elgg_is_active_plugin('search') && get_input('query')) { if ($entity->getVolatileData('search_matched_description')) { $body = $entity->getVolatileData('search_matched_description'); } else { $body = search_get_highlighted_relevant_substrings($entity->description, get_input('query'), 5, 5000); } } else { $body = elgg_view('output/longtext', ['value' => $entity->description]); } if (elgg_view_exists('output/linkify')) { $body = elgg_view('output/linkify', array('value' => $body)); } $body = elgg_format_element('span', array('class' => 'interactions-comment-text', 'data-role' => 'comment-text'), $body); //$body = elgg_echo('interactions:comment:body', array($owner_link, $body)); echo elgg_format_element('div', array('class' => 'interactions-comment-body'), $body);
/** * Get comments 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_comments_hook($hook, $type, $value, $params) { $db_prefix = elgg_get_config('dbprefix'); $query = sanitise_string($params['query']); $limit = sanitise_int($params['limit']); $offset = sanitise_int($params['offset']); $params['annotation_names'] = array('generic_comment', 'group_topic_post'); $params['joins'] = array("JOIN {$db_prefix}annotations a on e.guid = a.entity_guid", "JOIN {$db_prefix}metastrings msn on a.name_id = msn.id", "JOIN {$db_prefix}metastrings msv on a.value_id = msv.id"); $fields = array('string'); // force IN BOOLEAN MODE since fulltext isn't // available on metastrings (and boolean mode doesn't need it) $search_where = search_get_where_sql('msv', $fields, $params, FALSE); $container_and = ''; if ($params['container_guid'] && $params['container_guid'] !== ELGG_ENTITIES_ANY_VALUE) { $container_and = 'AND e.container_guid = ' . sanitise_int($params['container_guid']); } $e_access = get_access_sql_suffix('e'); $a_access = get_access_sql_suffix('a'); // @todo this can probably be done through the api.. $q = "SELECT count(DISTINCT a.id) as total FROM {$db_prefix}annotations a\n\t\tJOIN {$db_prefix}metastrings msn ON a.name_id = msn.id\n\t\tJOIN {$db_prefix}metastrings msv ON a.value_id = msv.id\n\t\tJOIN {$db_prefix}entities e ON a.entity_guid = e.guid\n\t\tWHERE msn.string IN ('generic_comment', 'group_topic_post')\n\t\t\tAND ({$search_where})\n\t\t\tAND {$e_access}\n\t\t\tAND {$a_access}\n\t\t\t{$container_and}\n\t\t"; if (!($result = get_data($q))) { return FALSE; } $count = $result[0]->total; // don't continue if nothing there... if (!$count) { return array('entities' => array(), 'count' => 0); } // no full text index on metastrings table if ($params['sort'] == 'relevance') { $params['sort'] = 'created'; } $order_by = search_get_order_by_sql('a', null, $params['sort'], $params['order']); if ($order_by) { $order_by = "ORDER BY {$order_by}"; } $q = "SELECT DISTINCT a.*, msv.string as comment FROM {$db_prefix}annotations a\n\t\tJOIN {$db_prefix}metastrings msn ON a.name_id = msn.id\n\t\tJOIN {$db_prefix}metastrings msv ON a.value_id = msv.id\n\t\tJOIN {$db_prefix}entities e ON a.entity_guid = e.guid\n\t\tWHERE msn.string IN ('generic_comment', 'group_topic_post')\n\t\t\tAND ({$search_where})\n\t\t\tAND {$e_access}\n\t\t\tAND {$a_access}\n\t\t\t{$container_and}\n\t\t\n\t\t{$order_by}\n\t\tLIMIT {$offset}, {$limit}\n\t\t"; $comments = get_data($q); // @todo if plugins are disabled causing subtypes // to be invalid and there are comments on entities of those subtypes, // the counts will be wrong here and results might not show up correctly, // especially on the search landing page, which only pulls out two results. // probably better to check against valid subtypes than to do what I'm doing. // need to return actual entities // add the volatile data for why these entities have been returned. $entities = array(); foreach ($comments as $comment) { $entity = get_entity($comment->entity_guid); // hic sunt dracones if (!$entity) { //continue; $entity = new ElggObject(); $entity->setVolatileData('search_unavailable_entity', TRUE); } $comment_str = search_get_highlighted_relevant_substrings($comment->comment, $query); $comments_data = $entity->getVolatileData('search_comments_data'); if (!$comments_data) { $comments_data = array(); } $comments_data[] = array('annotation_id' => $comment->id, 'text' => $comment_str, 'owner_guid' => $comment->owner_guid, 'time_created' => $comment->time_created); $entity->setVolatileData('search_comments_data', $comments_data); $entities[] = $entity; } return array('entities' => $entities, 'count' => $count); }
/** * 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); }
/** * Return default results for searches on users. * * @todo add profile field MD searching * * @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_users_hook($hook, $type, $value, $params) { $db_prefix = elgg_get_config('dbprefix'); $query = sanitise_string($params['query']); $params['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 md.value_id = msv.id"); if (isset($params["container_guid"])) { $entity = get_entity($params["container_guid"]); } if (isset($entity) && $entity instanceof ElggGroup) { // check for group membership relation $params["relationship"] = "member"; $params["relationship_guid"] = $params["container_guid"]; $params["inverse_relationship"] = TRUE; unset($params["container_guid"]); } else { // check for site relation ship if (empty($_SESSION["search_advanced:multisite"])) { $params["relationship"] = "member_of_site"; $params["relationship_guid"] = elgg_get_site_entity()->getGUID(); $params["inverse_relationship"] = TRUE; } } if (!empty($params["query"])) { $fields = array('username', 'name'); $where = search_advanced_get_where_sql('ue', $fields, $params, FALSE); // profile fields $profile_fields = array_keys(elgg_get_config('profile_fields')); if ($profile_fields) { $profile_field_metadata_search_values = elgg_get_plugin_setting("user_profile_fields_metadata_search", "search_advanced", array()); if (!empty($profile_field_metadata_search_values)) { $profile_field_metadata_search_values = json_decode($profile_field_metadata_search_values, true); } $tag_name_ids = array(); foreach ($profile_fields as $field) { if (!in_array($field, $profile_field_metadata_search_values)) { $tag_name_ids[] = elgg_get_metastring_id($field); } } if (!empty($tag_name_ids)) { $likes = 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)) { $likes[] = "msv.string LIKE '%{$query_value}%'"; } } } else { $likes[] = "msv.string LIKE '%{$query}%'"; } $md_where = "((md.name_id IN (" . implode(",", $tag_name_ids) . ")) AND (" . implode(" OR ", $likes) . "))"; $where = "(({$where}) OR ({$md_where}))"; } } $params['wheres'] = array($where); } $profile_fields = $params["profile_filter"]; if (!empty($profile_fields)) { $profile_field_likes = array(); $profile_soundex = $params["profile_soundex"]; $i = 0; foreach ($profile_fields as $field_name => $field_value) { $field_value = trim(sanitise_string($field_value)); if (!empty($field_value)) { $tag_name_id = elgg_get_metastring_id($field_name); $i++; if ($i > 1) { $params["joins"][] = "JOIN {$db_prefix}metadata md{$i} on e.guid = md{$i}.entity_guid"; $params["joins"][] = "JOIN {$db_prefix}metastrings msv{$i} ON md{$i}.value_id = msv{$i}.id"; } // do a soundex match if (is_array($profile_soundex) && in_array($field_name, $profile_soundex)) { if ($i > 1) { $profile_field_likes[] = "md{$i}.name_id = {$tag_name_id} AND soundex(CONCAT('X', msv{$i}.string)) = soundex(CONCAT('X','{$field_value}'))"; } else { $profile_field_likes[] = "md.name_id = {$tag_name_id} AND soundex(CONCAT('X', msv.string)) = soundex(CONCAT('X', '{$field_value}'))"; } } else { if ($i > 1) { $profile_field_likes[] = "md{$i}.name_id = {$tag_name_id} AND msv{$i}.string LIKE '%{$field_value}%'"; } else { $profile_field_likes[] = "md.name_id = {$tag_name_id} AND msv.string LIKE '%{$field_value}%'"; } } } } if (!empty($profile_field_likes)) { $profile_field_where = "(" . implode(" AND ", $profile_field_likes) . ")"; if (empty($params["wheres"])) { $params["wheres"] = array($profile_field_where); } else { $params["wheres"] = array($params["wheres"][0] . " AND " . $profile_field_where); } } } $wheres = (array) elgg_extract("wheres", $params); $wheres[] = "ue.banned = 'no'"; $params["wheres"] = $wheres; // override subtype -- All users should be returned regardless of subtype. $params['subtype'] = ELGG_ENTITIES_ANY_VALUE; $params['count'] = TRUE; $count = elgg_get_entities_from_relationship($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_from_relationship($params); // add the volatile data for why these entities have been returned. foreach ($entities as $entity) { $username = search_get_highlighted_relevant_substrings($entity->username, $query); $entity->setVolatileData('search_matched_title', $username); $name = search_get_highlighted_relevant_substrings($entity->name, $query); $entity->setVolatileData('search_matched_description', $name); } return array('entities' => $entities, 'count' => $count); }