Recherche
Contenu
Recherche d’entité
Le noyau de Elgg fournit des elgg_search()
flexibles, qui préparent des clauses de recherche personnalisées et utilisent elgg_get_entities()
pour récupérer les résultats.
Outre tous les paramètres acceptés par elgg_get_entities()
, elgg_search()
accepte les paramètres suivants :
query
Requête - Termes de la recherche
fields
Un tableau de noms par type de propriété à rechercher (voir l’exemple ci-dessous)
sort_by
Un tableau contenant des options de tri, comprenant property, property_type et direction
type
Type d’entité à rechercher
subtype
Sous-type d’entité à rechercher - facultatif
search_type
Type de recherche personnalisé (requis si aucuntype
n’est fourni)
partial_match
Autorise les correspondances partiellesPar défaut, les correspondances partielles sont autorisées, ce qui signifie que
elgg
sera trouvé lors de la recherche deel
. Les correspondances exactes peuvent être utiles lorsque vous souhaitez trouver les correspondances pour une métadonnée précise, par exemple lorsque vous voulez trouver tous les objets dont la couleur estred
et nondarkred
tokenize
Décomposer la requête de recherche en jetonsPar défaut, les requêtes de recherche utilisent des jetons - sont tokenisées, ce qui signifie que nous allons trouver
elgg a été publié
lors d’une recherche surelgg publié
// List all users who list United States as their address or mention it in their description
$options = [
'type' => 'user',
'query' => 'us',
'fields' => [
'metadata' => ['description'],
'annotations' => ['location'],
],
'sort_by' => [
'property' => 'zipcode',
'property_type' => 'annotation',
'direction' => 'asc',
],
];
echo elgg_list_entities($options, 'elgg_search');
Champs de recherche
Vous pouvez personnaliser les champs de recherche pour chaque type/sous-type d’entité, en utilisant l’événement search:fields
:
// Let's remove search in location and add address field instead
elgg_register_event_handler('search:fields', 'user', 'my_plugin_search_user_fields');
function my_plugin_search_user_fields(\Elgg\Event $event) {
$fields = $event->getValue();
$location_key = array_search('location', $fields['annotations']);
if ($location_key) {
unset($fields[$location_key]['annotations']);
}
$fields['metadata'][] = 'address';
return $fields;
}
Entités pouvant être recherchées
Pour enregistrer un type d’entité pour la recherche, utilisez elgg_entity_enable_capability($type, $subtype, 'searchable')
, ou faites-le lors de la définition du type d’entité dans elgg-plugin.php
.
Note
Le plugin de recherche utilise la capacité d’entité searchable. Cette capacité définit si une entité peut être recherchée.
Pour combiner les résultats de recherche ou filtrer la façon dont les résultats de recherche sont présentés dans le plugin de recherche, utilisez l’événement 'search:config', 'type_subtype_pairs'
.
// Let's add places and place reviews as public facing entities
elgg_entity_enable_capability('object', 'place', 'searchable');
elgg_entity_enable_capability('object', 'place_review', 'searchable');
// Now let's include place reviews in the search results for places
elgg_register_event_handler('search:options', 'object:place', 'my_plugin_place_search_options');
elgg_register_event_handler('search:config', 'type_subtype_pairs', 'my_plugin_place_search_config');
// Add place review to search options as a subtype
function my_plugin_place_search_options(\Elgg\Event $event) {
$params = $event->getParams();
if (isset($params['subtypes'])) {
$subtypes = (array) $params['subtypes'];
} else {
$subtypes = (array) elgg_extract('subtype', $params);
}
if (!in_array('place', $subtypes)) {
return;
}
unset($params["subtype"]);
$subtypes[] = 'place_review';
$params['subtypes'] = $subtypes;
return $params;
}
// Remove place reviews as a separate entry in search sections
function my_plugin_place_search_config(\Elgg\Event $event) {
$types = $event->getValue();
if (empty($types['object'])) {
return;
}
foreach ($types['object'] as $key => $subtype) {
if ($subtype == 'place_review') {
unset($types['object'][$key]);
}
}
return $types;
}
Types de recherches personnalisés
Le noyau de Elgg prend en charge uniquement la recherche d’entités. Vous pouvez implémenter des recherches personnalisées, par exemple en utilisant une requête de recherche comme un emplacement pour lister les entités à proximité de cet emplacement.
// Let's added proximity search type
elgg_register_event_handler('search:config', 'search_types', function (\Elgg\Event $event) {
$search_types = $event->getValue();
$search_types[] = 'promimity';
return $search_types;
});
// Let's add search options that will look for entities that have geo coordinates and order them by proximity to the query location
elgg_register_event_handler('search:options', 'proximity', function (\Elgg\Event $event) {
$query = $event->getParam('query');
$options = $event->getValue();
// Let's presume we have a geocoding API
$coords = geocode($query);
// We are not using standard 'selects' options here, because counting queries do not use custom selects
$options['wheres']['proximity'] = function (QueryBuilder $qb, $alias) use ($lat, $long) {
$dblat = $qb->joinMetadataTable($alias, 'guid', 'geo:lat');
$dblong = $qb->joinMetadataTable($alias, 'guid', 'geo:long');
$qb->addSelect("(((acos(sin(($lat*pi()/180))
*sin(($dblat.value*pi()/180)) + cos(($lat*pi()/180))
*cos(($dblat.value*pi()/180))
*cos((($long-$dblong.value)*pi()/180)))))*180/pi())
*60*1.1515*1.60934
AS proximity");
$qb->orderBy('proximity', 'asc');
return $qb->merge([
$qb->compare("$dblat.value", 'is not null'),
$qb->compare("$dblong.value", 'is not null'),
]);
};
return $options;
});
Points de terminaison pour l’autocomplétion et la recherche en direct
Le coeur de Elgg fournit un point de terminaison JSON pour rechercher des utilisateurs et des groupes. Ces points de terminaison sont utilisés par les vues input/autocomplete
et input/entitypicker
.
// Get JSON results of a group search for 'class'
$json = file_get_contents('http://example.com/livesearch/groups?view=json&q=class');
Vous pouvez ajouter des types de recherche personnalisés en ajoutant une vue de ressource correspondante :
// Let's add an endpoint that will search for users that are not members of a group
// and render a userpicker for our invite form
echo elgg_view('input/userpicker', [
'handler' => 'livesearch/non_members',
'options' => [
// this will be sent as URL query elements
'group_guid' => $group_guid,
],
]);
// To enable /livesearch/non_members endpoint, we need to add a view
// in /views/json/resources/livesearch/non_members.php
$limit = get_input('limit', elgg_get_config('default_limit'));
$query = get_input('term', get_input('q'));
$input_name = get_input('name');
// We have passed this value to our input view, and we want to make sure
// external scripts are not using it to mine data on group members
// so let's validate the HMAC that was generated by the userpicker input
$group_guid = (int) get_input('group_guid');
$data = [
'group_guid' => $group_guid,
];
// let's sort by key, in case we have more elements
ksort($data);
$hmac = elgg_build_hmac($data);
if (!$hmac->matchesToken(get_input('mac'))) {
// request does not originate from our input view
throw new \Elgg\Exceptions\Http\EntityPermissionsException();
}
elgg_set_http_header("Content-Type: application/json;charset=utf-8");
$options = [
'query' => $query,
'type' => 'user',
'limit' => $limit,
'sort' => 'name',
'order' => 'ASC',
'fields' => [
'metadata' => ['name', 'username'],
],
'item_view' => 'search/entity',
'input_name' => $input_name,
'wheres' => function (QueryBuilder $qb) use ($group_guid) {
$subquery = $qb->subquery('entity_relationships', 'er');
$subquery->select('1')
->where($qb->compare('er.guid_one', '=', 'e.guid'))
->andWhere($qb->compare('er.relationship', '=', 'member', ELGG_VALUE_STRING))
->andWhere($qb->compare('er.guid_two', '=', $group_guid, ELGG_VALUE_INTEGER));
return "NOT EXISTS ({$subquery->getSQL()})";
}
];
echo elgg_list_entities($options, 'elgg_search');