Ce package ajoute une fonctionnalité de recherche/filtrage aux modèles Eloquent dans Laravel 4/5/6.
Vous pourriez également trouver ces packages utiles :
Ajoutez la ligne suivante au fichier composer.json
dans votre projet :
"jedrzej/searchable": "0.0.17"
ou exécutez ce qui suit dans la ligne de commande dans le dossier racine de votre projet :
composer require "jedrzej/searchable" "0.0.17"
Afin de rendre un modèle Eloquent consultable, ajoutez le trait au modèle et définissez une liste de champs par lesquels le modèle peut être filtré. Vous pouvez soit définir une propriété $searchable, soit implémenter une méthode getSearchableAttributes si vous souhaitez exécuter une logique pour définir une liste de champs consultables.
use Jedrzej Searchable SearchableTrait ;
class Post extends Eloquent
{
use SearchableTrait ;
// either a property holding a list of searchable fields...
public $ searchable = [ ' title ' , ' forum_id ' , ' user_id ' , ' created_at ' ];
// ...or a method that returns a list of searchable fields
public function getSearchableAttributes ()
{
return [ ' title ' , ' forum_id ' , ' user_id ' , ' created_at ' ];
}
}
Afin de rendre tous les champs consultables, mettez un astérisque * dans la liste des champs consultables :
public $ searchable = [ ' * ' ];
Il est également possible de mettre sur liste noire les attributs du modèle pour éviter qu'il soit filtré.
Vous pouvez soit définir une propriété $notSearchable, soit implémenter une méthode getNotSearchableAttributes si vous souhaitez exécuter une logique pour définir une liste de champs consultables.
use Jedrzej Searchable SearchableTrait ;
class Post extends Eloquent
{
use SearchableTrait ;
// either a property holding a list of not searchable fields...
public $ notSearchable = [ ' created_at ' ];
// ...or a method that returns a list of not searchable fields
public function getNotSearchableAttributes ()
{
return [ ' created_at ' ];
}
}
Si vous définissez les deux listes (colonnes consultables et non consultables), l'ensemble résultant de champs consultables contiendra tous les attributs sur liste blanche, à l'exception de tous les attributs sur liste noire.
SearchableTrait
ajoute une portée filtered()
au modèle - vous pouvez lui transmettre une requête étant un tableau de conditions de filtre :
// return all posts with forum_id equal to $forum_id
Post :: filtered ([ ' forum_id ' => $ forum_id ])-> get ();
// return all posts with with <operator> applied to forum_id
Post :: filtered ([ ' forum_id ' => <operator>])-> get ();
ou il utilisera Request::all()
par défaut :
// if you append ?forum_id=<operator> to the URL, you'll get all Posts with <operator> applied to forum_id
Post :: filtered ()-> get ();
Le mode de requête par défaut consiste à appliquer la conjonction ( AND
) de toutes les requêtes au modèle consultable. Il peut être modifié en disjonction ( OR
) en définissant la valeur du paramètre de requête mode
sur or
. Si le paramètre de requête mode
est déjà utilisé, le nom renvoyé par la méthode getQueryMode
sera utilisé.
Le SearchableTrait
prend en charge les opérateurs suivants :
Les opérateurs de comparaison permettent un filtrage basé sur le résultat de la comparaison de l'attribut du modèle et de la valeur de la requête. Ils fonctionnent pour les chaînes, les nombres et les dates. Ils ont le format suivant :
(<operator>)<value>
Les opérateurs de comparaison suivants sont disponibles :
gt
pour greater than
la comparaisonge
pour une comparaison greater than or equal
lt
pour less than
la comparaison, par exemplele
pour une comparaison les than or equal
Afin de filtrer les publications de 2015 et plus récentes, la requête suivante doit être utilisée :
?created_at=(ge)2015-01-01
Le trait consultable permet de filtrer par valeur exacte d'un attribut ou par un ensemble de valeurs, en fonction du type de valeur transmise en tant que paramètre de requête. Si la valeur contient des virgules, le paramètre est divisé en virgules et utilisé comme entrée de tableau pour le filtrage IN
, sinon une correspondance exacte est appliquée.
Afin de filtrer les publications de l'utilisateur portant l'identifiant 42, la requête suivante doit être utilisée :
?user_id=42
Afin de filtrer les messages des forums avec l'identifiant 7 ou 8, la requête suivante doit être utilisée :
?forum_id=7,8
Les opérateurs Like permettent le filtrage à l’aide d’une requête LIKE
. Cet opérateur est déclenché si l'opérateur de correspondance exacte est utilisé, mais que la valeur contient le signe %
comme premier ou dernier caractère.
Afin de filtrer les publications commençant par How
, la requête suivante doit être utilisée :
?title=How%
Notice:
le caractère de pourcentage est utilisé pour encoder les caractères spéciaux dans les URL. Par conséquent, lors de l'envoi de la requête, assurez-vous que les outils que vous utilisez encode the % character as %25
L'opérateur nul (null)
permet de filtrer les modèles dont l'attribut est nul.
Afin de filtrer les publications sans pièce jointe, la requête suivante doit être utilisée :
?attachment_id=(null)
Il est possible d'obtenir des résultats annulés d'une requête en faisant précéder l'opérateur de !
.
Quelques exemples :
//filter posts from all forums except those with id 7 or 8
?forum_id=!7,8
//filter posts older than 2015
?created_at=!(ge)2015
//filter posts with attachment
?attachment_id=!(null)
Il est possible d'appliquer plusieurs contraintes pour un seul attribut de modèle. Pour y parvenir, fournissez un tableau de filtres de requête au lieu d’un seul filtre :
// filter all posts from year 20** except 2013
?created_at[]=20%&created_at[]=!2013%
Il est possible de filtrer par attributs des relations du modèle - whereHas()
d'Eloquent sera appliqué. Afin de filtrer par relation, ajoutez l'attribut relation à la liste des champs searchable
sous la forme relation:attribute
. La même chaîne doit être utilisée dans la requête pour filtrer selon l'attribut de cette relation, par exemple :
// allow filtering on user's active field
protected $searchable = ['user:active'];
// filter only posts of active users
?user:active=1
Il est également possible d'annuler les objets de recherche et de filtrage qui n'ont pas de relation de correspondance en appliquant whereDoesntHave()
d'Eloquent. Pour ce faire, préfixez le nom de la relation avec !
:
// allow filtering on comment's approved field
protected $searchable = ['comments:approved'];
// filter only posts that have approved comments
?comments:approved=1
// filter only posts that have not-approved comments
?comments:approved=1
// filter only posts that do not have approved comments
?!comments:approved=1
Si vous souhaitez filtrer par relation imbriquée, fournissez simplement le nom de la relation imbriquée en remplaçant le point par deux points. C'est nécessaire car PHP remplace automatiquement les points par des traits de soulignement dans l'URL.
// filter only posts that have comments from active authors
?comments:author:active=1
Il est possible de traiter les filtres sélectionnés avec votre propre logique, par exemple lorsque le nom du filtre ne correspond pas au nom de l'attribut utilisé pour le filtrage ou que certaines opérations personnalisées doivent être exécutées. Afin de remplacer la logique du filtre xyz
, vous devrez définir une méthode dans votre modèle appelée processXyzFilter
. Cette méthode doit renvoyer true
si le filtre a été traité et que la logique par défaut ne devrait plus se produire.
// use one filter to search in multiple columns
protected function processNameFilter ( Builder $ builder , Constraint $ constraint )
{
// this logic should happen for LIKE/EQUAL operators only
if ( $ constraint -> getOperator () === Constraint :: OPERATOR_LIKE || $ constraint -> getOperator () === Constraint :: OPERATOR_EQUAL ) {
$ builder -> where ( function ( $ query ) use ( $ constraint ) {
$ query -> where ( ' first_name ' , $ constraint -> getOperator (), $ constraint -> getValue ())
-> orWhere ( ' last_name ' , $ constraint -> getOperator (), $ constraint -> getValue ());
});
return true ;
}
// default logic should be executed otherwise
return false ;
}
Afin de remplacer un filtre pour la recherche de relations, remplacez les deux points dans le nom du filtre par un trait de soulignement. Si vous souhaitez remplacer la logique pour user:active
, vous devez définir la méthode processUser_ActiveFilter
.