Modèles intelligents auto-validés pour l'ORM Eloquent de Laravel Framework 5.
Basé sur le bundle Aware pour Laravel 3 de Colby Rabideau.
Copyright (C) 2013-2015 Max Ehsan et Igor Santos
Visitez notre liste de versions. Le changelog est fait là :)
Ajoutez laravelbook/ardent
comme exigence à composer.json
(voir notre dernière version stable sur les badges !) :
{"require": {"laravelbook/ardent": "3.*"}}
Mettez à jour vos packages avec composer update
ou installez avec composer install
.
Vous pouvez également ajouter le package en utilisant composer require laravelbook/ardent
et en spécifiant plus tard la version souhaitée (pour l'instant, dev-master
est votre meilleur pari).
Si vous souhaitez utiliser Ardent en tant que package ORM autonome, vous êtes invité à le faire en utilisant la configuration suivante dans le fichier de démarrage/démarrage de votre projet (en modifiant les propriétés en fonction de votre base de données, évidemment) :
LaravelArdentArdentArdent::configureAsExternal(array( 'driver' => 'mysql', 'host' => 'localhost', 'port' => 3306, 'database' => 'my_system', 'username' => 'moi-même', 'mot de passe' => 'h4ckr', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci'), 'fr'); //L'anglais est la langue des messages par défaut, peut être laissé vide
Introduction
Commencer
Validation sans effort avec Ardent
Récupération des erreurs de validation
Remplacement de la validation
Messages d'erreur de validation personnalisée
Règles de validation personnalisées
Crochets de modèle
Définition plus claire des relations
Hydrater automatiquement les entités ardentes
Purger automatiquement les données de formulaire redondantes
Transformer automatiquement les attributs de texte sécurisé
Mises à jour avec des règles uniques
À quelle fréquence vous retrouvez-vous à recréer le même code passe-partout dans les applications que vous créez ? Ce code typique de traitement de formulaire vous semble-t-il trop familier ?
Route::post('register', function() {$rules = array('name' => 'required|between:3,80|alpha_dash','email' => 'required|between:5,64|email |unique:users','password' => 'obligatoire|min:6|confirmé','password_confirmation' => 'required|min:6');$validator = Validator::make(Input::all(), $rules);if ($validator->passes()) { User::create(array('name' => Input::get('name'),'email' => Input::get('email'),'password' => Hash::make(Input:: obtenir('mot de passe')) ));return Redirect::to('/')->with('message', 'Merci pour votre inscription !'); } else {return Redirect::to('/')->withErrors($validator->getMessages()); } } );
L’implémentation vous-même entraîne souvent de nombreux codes passe-partout répétés. En prime, vos contrôleurs (ou gestionnaires de routes) grossissent prématurément et votre code devient désordonné, laid et difficile à comprendre.
Et si quelqu’un d’autre faisait tout le gros du travail à votre place ? Et si, au lieu de régurgiter le désordre ci-dessus, il vous suffisait de taper ces quelques lignes ?...
Route::post('register', function() {$user = new User;if ($user->save()) {return Redirect::to('/')->with('message', 'Merci pour vous inscrire!'); } else {return Redirect::to('/')->withErrors($user->errors()); } } );
Entrez Ardent!
Ardent - la solution unique, alimentée par la poussière magique, adaptée au poignet, à tous vos ennuyeux passe-partout de désinfection des entrées !
Jeux de mots mis à part, la fonctionnalité de validation des entrées peut rapidement devenir fastidieuse à écrire et à maintenir. Ardent résout ces complexités en fournissant des aides pour automatiser de nombreuses tâches répétitives.
Cependant, Ardent n'est pas seulement idéal pour la validation des entrées : il vous aidera à réduire considérablement le code de votre modèle de données Eloquent. Ardent est particulièrement utile si vous vous retrouvez fatigué à écrire encore et encore du code très similaire dans plusieurs applications individuelles.
Par exemple, l'enregistrement des utilisateurs ou la soumission d'articles de blog sont une exigence de codage courante que vous souhaiterez peut-être implémenter dans une application et réutiliser à nouveau dans d'autres applications. Avec Ardent, vous pouvez écrire vos modèles intelligents et conscients de vous -même une seule fois, puis les réutiliser (sans ou très peu de modifications) dans d'autres projets. Une fois que vous vous serez habitué à cette façon de faire les choses, vous vous demanderez honnêtement comment vous avez pu vous en sortir sans Ardent.
Fini les lésions cérébrales répétitives pour vous !
Ardent
vise à étendre la classe de base Eloquent
sans modifier ses fonctionnalités de base. Étant donné Ardent
lui-même est un descendant de IlluminateDatabaseEloquentModel
, tous vos modèles Ardent
sont entièrement compatibles avec Eloquent
et peuvent exploiter toute la puissance du génial OR/M de Laravel.
Pour créer un nouveau modèle Ardent, faites simplement dériver votre classe de modèle de la classe de base Ardent
. Dans les exemples suivants, nous utiliserons la classe complète avec espace de noms pour rendre les exemples plus propres, mais nous vous encourageons à utiliser use
dans toutes vos classes :
utiliser LaravelArdentArdentArdent;class L'utilisateur étend Ardent {}
Remarque : vous pouvez librement mélanger vos modèles Eloquent nature vanille avec des descendants Ardent. Si un objet modèle ne repose pas sur le contenu soumis par l'utilisateur et ne nécessite donc pas de validation, vous pouvez laisser la classe modèle Eloquent telle quelle.
Les modèles Ardent utilisent la classe Validator intégrée de Laravel. La définition des règles de validation pour un modèle est simple et s'effectue généralement dans votre classe de modèle en tant que variable statique :
class User extends LaravelArdentArdentArdent { public static $rules = array('name' => 'required|between:3,80|alpha_dash','email' => 'required|between:5,64|email|unique:users', 'password' => 'obligatoire|min:6|confirmé','password_confirmation' => 'obligatoire|min:6', ); }
Remarque : vous êtes également libre d'utiliser la syntaxe du tableau pour les règles de validation. J'espère que l'ancien lien de la documentation Laravel ne vous dérange pas, mais aussi bonne que soit la documentation Laravel, une référence claire sur les syntaxes de tuyaux/tableaux pour les règles de validation a malheureusement disparu depuis la version 5.1.
Les modèles Ardent se valident automatiquement lorsque Ardent->save()
est appelé.
$user = nouvel utilisateur;$user->name = 'John doe';$user->email = '[email protected]';$user->password = 'test';$success = $user->save( ); // renvoie false si le modèle n'est pas valide
Remarque : Vous pouvez également valider un modèle à tout moment en utilisant la méthode
Ardent->validate()
.
Lorsqu'un modèle Ardent ne parvient pas à être validé, un objet IlluminateSupportMessageBag
est attaché à l'objet Ardent qui contient des messages d'échec de validation.
Récupérez l’instance de collecte de messages d’erreurs de validation avec la méthode Ardent->errors()
ou la propriété Ardent->validationErrors
.
Récupérez toutes les erreurs de validation avec Ardent->errors()->all()
. Récupérez les erreurs pour un attribut spécifique en utilisant Ardent->validationErrors->get('attribute')
.
Remarque : Ardent exploite l'objet MessagesBag de Laravel qui dispose d'une méthode simple et élégante de formatage des erreurs.
Il existe deux manières de remplacer la validation d'Ardent :
forceSave()
valide le modèle mais enregistre qu'il y ait ou non des erreurs de validation.
Ardent->save($rules, $customMessages)
et Ardent->validate($rules, $customMessages)
prennent deux paramètres :
$rules
est un tableau de règles Validator de la même forme qu'Ardent Ardent::$rules
.
Il en va de même pour le paramètre $customMessages
(identique à Ardent::$customMessages
)
Un tableau qui n'est pas vide remplacera les règles ou les messages d'erreur personnalisés spécifiés par la classe pour cette instance de la méthode uniquement.
Remarque : la valeur par défaut de
$rules
et$customMessages
est videarray()
; ainsi, si vous transmettez unarray()
rien ne sera remplacé.
Tout comme Laravel Validator, Ardent vous permet de définir des messages d'erreur personnalisés en utilisant la même syntaxe.
class User extends LaravelArdentArdentArdent { public static $customMessages = array('required' => 'Le champ :attribute est obligatoire.', ... ); }
Vous pouvez créer des règles de validation personnalisées de la même manière que vous le feriez pour Laravel Validator.
Ardent fournit un peu de sucre syntaxique par rapport aux événements de modèle d'Eloquent : les hooks de modèle traditionnels. Ils constituent un moyen simple d’associer des opérations supplémentaires à différents moments de la vie de votre modèle. Ils peuvent être utilisés pour effectuer un travail de nettoyage supplémentaire avant de supprimer une entrée, effectuer des correctifs automatiques après la validation ou mettre à jour les modèles associés après une mise à jour.
Tous before
les hooks, lors du retour de false
(en particulier des valeurs booléennes, pas simplement "fausses"), l'opération sera interrompue. Ainsi, par exemple, si vous souhaitez arrêter la sauvegarde si quelque chose ne va pas dans une méthode beforeSave
, return false
et la sauvegarde n'aura pas lieu - et évidemment afterSave
ne sera pas non plus appelé.
Voici la liste complète des hooks disponibles :
before
/ afterCreate()
before
/ afterSave()
before
/ afterUpdate()
before
/ afterDelete()
before
/ afterValidate()
- lors du retour de false, la validation s'arrêtera, ce qui fera échouer également les opérations save()
puisque la validation a été un échec.
Par exemple, vous pouvez utiliser beforeSave
pour hacher le mot de passe d'un utilisateur (en fait, ce serait une meilleure idée d'utiliser le hachage automatique !) :
class User extends LaravelArdentArdentArdent { public function beforeSave() {// s'il y a un nouveau mot de passe, hachez itif($this->isDirty('password')) { $this->password = Hash::make($this->password ); } return true;//ou ne renvoie rien, puisque seul un booléen false arrêtera l'opération } }
beforeSave
et afterSave
peuvent être inclus au moment de l'exécution. Passez simplement les fermetures avec le modèle comme argument à la méthode save()
(ou forceSave()
).
$user->save(array(), array(), array(), function ($model) { // fermeture pour beforeSaveecho "enregistrer l'objet modèle...";return true; }, function ($model) { // fermeture pour afterSaveecho "done!"; } );
Remarque : les fermetures doivent avoir un paramètre car une référence au modèle en cours d'enregistrement lui sera transmise.
Avez-vous déjà écrit un modèle Eloquent avec un tas de relations, juste pour remarquer à quel point votre classe est encombrée, avec tous ces one-liners qui ont presque le même contenu que le nom de la méthode lui-même ?
Dans Ardent, vous pouvez définir proprement vos relations dans un tableau avec leurs informations, et elles fonctionneront comme si vous les aviez définies dans des méthodes. Voici un exemple :
class User extends LaravelArdentArdentArdent { public static $relationsData = array('address' => array(self::HAS_ONE, 'Address'),'orders' => array(self::HAS_MANY, 'Order'),'groups' = > array(self::BELONGS_TO_MANY, 'Groupe', 'table' => 'groups_have_users') ); }$user = User::find($id);echo "{$user->address->street}, {$user->address->city} - {$user->address->state}";
La syntaxe du tableau est la suivante :
Première valeur indexée : nom de la relation, étant l'un des hasOne
, hasMany
, belongsTo
, belongsToMany
, morphTo
, morphOne
, morphMany
ou l'une des constantes associées ( Ardent::HAS_MANY
ou Ardent::MORPH_ONE
par exemple).
Deuxième indexé : nom de classe, avec espace de noms complet. L'exception concerne les relations morphTo
, qui ne prennent aucun argument supplémentaire.
arguments nommés, suivant ceux définis pour les méthodes Eloquent originales :
foreignKey
[facultatif], valable pour hasOne
, hasMany
, belongsTo
et belongsToMany
table
, otherKey
[facultatif], timestamps
[booléen, facultatif] et pivotKeys
[array, facultatif], valides pour belongsToMany
name
, type
et id
, utilisés par morphTo
, morphOne
et morphMany
(les deux derniers nécessitent name
soit défini)
Remarque : Cette fonctionnalité était basée sur les relations faciles sur Yii 1.1 ActiveRecord.
Ardent est capable d'hydrater automatiquement votre classe de modèle d'entité à partir de la soumission d'entrée du formulaire !
Voyons l'action. Considérez cet extrait de code :
$user = nouvel utilisateur;$user->name = Input::get('name');$user->email = Input::get('email');$user->password = Hash::make(Input ::get('mot de passe'));$user->save();
Invoquons la magie d'Ardent et réécrivons l'extrait précédent :
$user = nouvel utilisateur;$user->save();
C'est ça! Tout ce que nous avons fait, c'est supprimer les éléments ennuyeux.
Croyez-le ou non, le code ci-dessus effectue essentiellement la même tâche que son frère aîné, quoique plutôt verbeux. Ardent remplit l'objet modèle avec les attributs des données de formulaire soumises par l'utilisateur. Plus besoin de vous arracher les cheveux pour essayer de savoir quelle propriété Eloquent vous avez oublié de renseigner. Laissez Ardent s'occuper des choses ennuyeuses, pendant que vous vous occupez des choses amusantes !
Il suit les mêmes règles d'affectation de masse en interne, en fonction des propriétés $fillable
/ $guarded
.
Pour activer la fonctionnalité d'hydratation automatique, définissez simplement la variable d'instance $autoHydrateEntityFromInput
sur true
dans votre classe de modèle. Cependant, pour éviter de remplir des propriétés préexistantes, si vous souhaitez également une hydratation automatique pour les scénarios de mise à jour, vous devez utiliser à la place $forceEntityHydrationFromInput
:
class User extends LaravelArdentArdentArdent { public $autoHydrateEntityFromInput = true; // s'hydrate lors de la validation des nouvelles entrées public $forceEntityHydrationFromInput = true; // s'hydrate chaque fois que la validation est appelée}
Les modèles Ardent peuvent purger automatiquement et par magie les données d'entrée redondantes (telles que la confirmation du mot de passe , _token
CSRF caché ou les champs _method
HTTP personnalisés) - afin que les données supplémentaires ne soient jamais enregistrées dans la base de données. Ardent utilisera les champs de confirmation pour valider la saisie du formulaire, puis éliminera prudemment ces attributs avant d'enregistrer l'instance de modèle dans la base de données !
Pour activer cette fonctionnalité, définissez simplement la variable d'instance $autoPurgeRedundantAttributes
sur true
dans votre classe de modèle :
class User extends LaravelArdentArdentArdent { public $autoPurgeRedundantAttributes = true; }
Vous pouvez également purger des champs supplémentaires. L'attribut Ardent::$purgeFilters
est un tableau de fermetures auquel vous pouvez ajouter vos règles personnalisées. Ces fermetures reçoivent la clé d'attribut comme argument et doivent renvoyer false
pour les attributs qui doivent être purgés. Comme ça:
function __construct($attributs = array()) { parent::__construct($attributs); $this->purgeFilters[] = function($key) {$purge = array('tempData', 'myAttribute');return ! in_array($clé, $purge); } ; }
Supposons que vous ayez un attribut nommé password
dans votre classe de modèle, mais que vous ne souhaitiez pas stocker la version en texte brut dans la base de données. La chose pragmatique à faire serait de stocker le hachage du contenu original. Ne vous inquiétez pas, Ardent est entièrement capable de transmogrifier automatiquement un certain nombre de champs sécurisés pour vous !
Pour ce faire, ajoutez le nom de l'attribut à la variable de tableau statique Ardent::$passwordAttributes
dans votre classe de modèle et définissez la variable d'instance $autoHashPasswordAttributes
sur true
:
class User extends LaravelArdentArdentArdent { public static $passwordAttributes = array('password'); public $autoHashPasswordAttributes = true ; }
Ardent remplacera automatiquement l'attribut de mot de passe en texte brut par une somme de contrôle de hachage sécurisée et l'enregistrera dans la base de données. Il utilise la méthode Laravel Hash::make()
en interne pour générer du hachage. Remarque : il est conseillé d'utiliser l'attribut $hidden
d'Eloquent afin que le mot de passe, même haché, ne sorte pas aussi facilement si vous créez une API ou similaire :)
Si vous utilisez Ardent autonome, vous pouvez utiliser Ardent::$hasher
pour vérifier la valeur du champ, en utilisant quelque chose comme User::$hasher->check($given_password, $user->password)
.
Ardent peut vous aider avec des mises à jour uniques. Selon la documentation Laravel, lorsque vous mettez à jour (et donc validez) un champ avec une règle unique, vous devez transmettre l'ID unique de l'enregistrement que vous mettez à jour. Sans transmettre cet identifiant, la validation échouera car le validateur de Laravel pensera que cet enregistrement est un doublon.
Extrait de la documentation Laravel :
'email' => 'unique:utilisateurs,email,10'
Dans le passé, les programmeurs devaient gérer manuellement la transmission de l'ID et la modification de l'ensemble de règles pour inclure l'ID au moment de l'exécution. Ce n’est pas le cas d’Ardent. Configurez simplement vos règles avec unique
, appelez la fonction updateUniques
et Ardent s'occupera du reste.
Dans votre modèle étendu, définissez vos règles
public static $rules = array( 'email' => 'required|email|unique', 'password' => 'required|between:4,20|confirmed', 'password_confirmation' => 'entre:4,20', );
Dans votre contrôleur, lorsque vous avez besoin d'une mise à jour, appelez simplement
$model->updateUniques();
Si nécessaire, vous pouvez transmettre des règles à l'exécution à updateUniques
, sinon il utilisera les règles statiques fournies par votre modèle.
Notez que dans l'exemple de règles ci-dessus, nous n'avons pas indiqué au validateur quelle table ou même quel champ utiliser comme cela est décrit dans la documentation de Laravel (c'est-à-dire unique:users,email,10
). Ardent est assez intelligent pour le comprendre. (Merci à l'utilisateur de github @Sylph)