amphibee / wordpress-eloquent-models
Eloquent ORM for WordPress
Installs: 2 610
Dependents: 1
Suggesters: 0
Security: 0
Stars: 4
Watchers: 2
Forks: 134
Open Issues: 2
Requires
- php: >=8.1
- bordoni/phpass: ^0.3.5
- illuminate/database: ^10.0|^11.0
- illuminate/filesystem: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- thunderer/shortcode: ^0.7.3
README
Le composant WordPress Eloquent Model est une boîte à outils complète fournissant un ORM et un générateur de schéma. Il prend en charge MySQL, Postgres, SQL Server et SQLite. Elle traduit les tables WordPress en modèles compatibles avec Eloquent.
La bibliothèque est idéale pour une utilisation avec Bedrock / Sage de Roots.
Plus besoin d'utiliser la vieille classe moisie WP_Query, on entre dans le monde du futur en produisant du code lisible et ré-utilisable ! Des fonctionnalités supplémentaires sont également disponibles pour une expérience d'utilisation personnalisée à WordPress.
La librairie assurant la compatibilité avec Eloquent, vous pouvez consulter la documentation de l'ORM si vous êtes un peu perdu :)
Sommaire
- Installation
- Mise en place
- Modèles supportés
- Images
- Alias de champs
- Scope personnalisés
- Pagination
- Meta
- Requête d'un Post à partir d'un champs personnalisé (Meta)
- Advanced Custom Fields
- Création de table
- Requètes avancées
- Type de contenu personnalisés
- Modèles personnalisés
- Shortcode
- Logs des requêtes
Installation
La méthode d'installation recommandée est Composer.
composer require amphibee/wordpress-eloquent-models
Mise en place
La connection à la base de données (via $wpdb) s'effectue au première appel d'un modèle Eloquent.
Si vous avez besoin de récupérer l'instance de connection, lancer simplement le code suivant (privilégiez l'usage de use
) :
AmphiBee\Eloquent\Database::instance();
Modèles supportés
Posts
use \AmphiBee\Eloquent\Model\Post; // récupération du post avec l'ID 1 $post = Post::find(1); // Données en relations disponibles $post->author; $post->comments; $post->terms; $post->tags; $post->categories; $post->meta;
Status
Par défaut, Post
retourne l'ensemble des articles quelque soit leur status. Cela peut être modifié via un scope local published
pour ne retourner que les articles publiés.
Post::published()->get();
Il est également possible de définir le statut en question via le scope local status
.
Post::status('draft')->get();
Post Types
Par défaut, Post
retourne l'ensemble des types de contenu. Cea peut être surchargé via le scope local type
.
Post::type('page')->get();
Comments
use \AmphiBee\Eloquent\Model\Comment; // récupère le commentaite ayant pour ID 12345 $comment = Comment::find(12345); // Données en relation disponibles $comment->post; $comment->author; $comment->meta
Terms
Dans cette version Term
est accessible en tant que modèle mais n'est accessible que par le biais d'article. Néanmoins, il suffit d'étendre Term
pour l'appliquer aux autres types de contenus personnalisés.
$post->terms()->where('taxonomy', 'country');
Users
use \AmphiBee\Eloquent\Model\User; // Tous les utilisateurs $users = User::get(); // récupère l'utilisateur ayant pour ID 123 $user = User::find(123);
Options
Dans WordPress, la récupération d'options s'effectue avec la fonction get_option
. Avec Eloquent, pour se passer d'un chargement inutile du Core WordPress, vous pourrez utiliser la fonction get
du modèle Option
.
$siteUrl = Option::get('siteurl');
Vous pouvez également ajouter d'autres options :
Option::add('foo', 'bar'); // stockée en tant que chaine de caractères Option::add('baz', ['one' => 'two']); // le tableau sera sérialisé
Vous pouvez récupérez l'ensemble des options en tant que tableau (attention aux performances...) :
$options = Option::asArray(); echo $options['siteurl'];
Vous pouvez également spécifier les options spécifiques à récupérer :
$options = Option::asArray(['siteurl', 'home', 'blogname']); echo $options['home'];
Menus
Pour récupérer un menu à partir de son alias, utiliser la syntaxe ci-dessous. Les éléments du menu seront retournés dans une variable items
(c'est une collection d'objet de type AmphiBee\Eloquent\Model\MenuItem
).
Les types de menu supportés actuellements sont : Pages, Posts, Custom Links et Categories.
Une fois que vous avez le modèle MenuItem
, si vous souhaitez utiliser l'instance d'origine (tels que Page ou Term, par exemple), appelez juste la méthode MenuItem::instance()
. L'objet MenuItem
est juste un post dont le post_type
est égal à nav_menu_item
:
$menu = Menu::slug('primary')->first(); foreach ($menu->items as $item) { echo $item->instance()->title; // si c'est un Post echo $item->instance()->name; // si c'est un Term echo $item->instance()->link_text; // si c'est un Custom Link }
La méthode instance()
retournera les objets correspondant :
Post
instance pour un élément de menu de typepost
;Page
instance pour un élément de menu de typepage
;CustomLink
instance pour un élément de menu de typecustom
;Term
instance pour un élément de menu de typecategory
.
Multi-levels Menus
Pour gérer les menus à multi-niveaux, vous pouvez effectuer des itérations pour les placer au bon niveau, par exemple.
Vous pouvez utiliser la méthode MenuItem::parent()
pour récupérer l'instance parent de l'élément du menu :
$items = Menu::slug('foo')->first()->items; $parent = $items->first()->parent(); // Post, Page, CustomLink ou Term (categorie)
Pour grouper les menus par parent, vous pouvez utiliser la méthode ->groupBy()
dans la collection $menu->items
, qui rassemblera les éléments selon leur parent ($item->parent()->ID
).
Pour en savoir plus sur la méthode groupBy()
, consulter la documentation de Eloquent.
Alias de champs
Le modèle Post
support les alias, donc si vous inspectez un objet Post
vous pourrez retrouvez des alias dans le tableau statique $aliases
(tels que title
pour post_title
et content
pour post_content
.
$post = Post::find(1); $post->title === $post->post_title; // true
Vous pouvez étendre le modèle Post
pour créer vos propres. Ajoutez juste vos alias dans le modèle étendu, il héritera automatiquement de ceux définis dans le modèle Post
:
class A extends \AmphiBee\Eloquent\Model\Post { protected static $aliases = [ 'foo' => 'post_foo', ]; } $a = A::find(1); echo $a->foo; echo $a->title; // récupéré depuis le modèle Post
Scopes personnalisés
Pour ordonner les modèles de type Post
ou User
, vous pouvez utiliser les scopes newest()
et oldest()
:
$newest = Post::newest()->first(); $oldest = Post::oldest()->first();
Pagination
Pour paginer les résultats, utiliser simplement la méthode paginate()
de Eloquent :
// Affiche les posts avec 5 éléments par page $posts = Post::published()->paginate(5); foreach ($posts as $post) { // ... }
Pour afficher les liens de paginations, utiliser la méthode links()
:
{{ $posts->links() }}
Meta
L'ensemble de modèles Eloquent intègre une gestion des méta-données de WordPress.
Voici un exemple pour récupérer des metas-données :
// Récupère un méta (ici 'link') depuis le modèle Post (on aurait pu utiliser un autre modèle comme User) $post = Post::find(31); echo $post->meta->link; // OU echo $post->fields->link; echo $post->link; // OU
Pour créer ou mettre à jour les metas données d'un utilisateur, utilisez juste les méthodes saveMeta()
ou saveField()
. Elles retourne un booléen à l'instar de la méthode save()
de Eloquent.
$post = Post::find(1); $post->saveMeta('username', 'amphibee');
Il est possible de sauvegarder plusieurs metas données en un seul appel :
$post = Post::find(1); $post->saveMeta([ 'username' => 'amphibee', 'url' => 'https://amphibee.fr', ]);
La libraire met également les méthodes createMeta()
et createField()
, qui fonctionnement comment les méthodes saveX()
, mais elles ne sont utilisées que pour la création et retourne l'objet de type PostMeta
créé par l'instance, au lieu d'un booléen.
$post = Post::find(1); $postMeta = $post->createMeta('foo', 'bar'); // instance of PostMeta class $trueOrFalse = $post->saveMeta('foo', 'baz'); // boolean
Requête d'un Post à partir d'un champs personnalisé (Meta)
Il existe différent moyen d'effectuer une requête à partir d'une méta-donnée (meta) en utilisant des scopes sur un modèle Post
(ou tout autre modèle utilisant le trait HasMetaFields
) :
Pour vérifier qu'une méta-donnée existe, utiliser le scope hasMeta()
:
// Récupère le premier article ayant la méta "featured_article"
$post = Post::published()->hasMeta('featured_article')->first();
Si vous souhaiter cible une méta-donnée avec une valeur spécifique, il est possible d'utiliser le scope hasMeta()
avec une valeur.
// Récupère le premier article ayant une méta "username" et ayant pour valeur "amphibee" $post = Post::published()->hasMeta('username', 'amphibee')->first();
Il est également possible d'effectuer une requête en définissant plusieurs meta-données et plusieurs valeurs associées en passant un tableau de valeur au scope scope hasMeta()
:
$post = Post::hasMeta(['username' => 'amphibee'])->first(); $post = Post::hasMeta(['username' => 'amphibee', 'url' => 'amphibee.fr'])->first(); // Ou juste en fournissant les clés de méta-données $post = Post::hasMeta(['username', 'url'])->first();
Si vous devez faire correspondre une chaîne de caractère insensible à la casse ou une correspondance avec des caractères génériques, vous pouvez utiliser le scope hasMetaLike()
avec une valeur. Cela utilisera l'opérateur SQL LIKE
, il est donc important d'utiliser l'opérateur générique '%'.
// Will match: 'B Gosselet', 'B BOSSELET', and 'b gosselet'. $post = Post::published()->hasMetaLike('author', 'B GOSSELET')->first(); // En utilisant l'opérateur %, les résultats suivants seront retournés : 'N Leroy', 'N LEROY', 'n leroy', 'Nico Leroy' etc. $post = Post::published()->hasMetaLike('author', 'N%Leroy')->first();
Images
Récupération d'une image depuis un modèle Post
ou Page
.
$post = Post::find(1); // Récupère une instance de AmphiBee\Eloquent\Model\Meta\ThumbnailMeta. print_r($post->thumbnail); // Vous devez afficher l'instance de l'image pour récupérer l'url de l'image d'origine echo $post->thumbnail;
Pour récupérer une taille d'image spécifique, utiliser la méthode ->size()
sur l'objet et renseigner l'alias de taille dans la paramètre (ex. thumbnail
ou medium
). Si la miniature a été générée, la méthode retourne un objet avec les méta-données, à défaut, c'est l'url d'origine qui est renvoyée (comportement WordPress).
if ($post->thumbnail !== null) { /** * [ * 'file' => 'filename-300x300.jpg', * 'width' => 300, * 'height' => 300, * 'mime-type' => 'image/jpeg', * 'url' => 'http://localhost/wp-content/uploads/filename-300x300.jpg', * ] */ print_r($post->thumbnail->size(AmphiBee\Eloquent\Model\Meta\ThumbnailMeta::SIZE_THUMBNAIL)); // http://localhost/wp-content/uploads/filename.jpg print_r($post->thumbnail->size('invalid_size')); }
Advanced Custom Fields
La librairie met à disposant la quasi-totalité des champs ACF (à l'exception du champs Google Map). Il permet de récupérer les champs de manière optimale sans passer par le module ACF.
Utilisation basique
Pour récupérer une valeur d'un champs, il suffit d'initialiser un modèle de type Post
et d'invoquer le champs personnalisé :
$post = Post::find(1); echo $post->acf->website_url; // retourne l'url fournie dans un champs ayant pour clé website_url
Performance
Lorque l'on utilise $post->acf->website_url
, des requètes additionnels sont exécutées pour récupérer le champs selon l'approche de ACF. Il est possible d'utiliser une méthode spécifique pour éviter ces requêtes additionnelles. Il suffit de renseigner le type de contenu personnalisé utilisé en tant que fonction :
// La méthode effectuant des requètes additionnelles echo $post->acf->author_username; // c'est un champs relatif à User // Sans requète additionnelle echo $post->acf->user('author_username'); // Autres exemples sans requètes echo $post->acf->text('text_field_name'); echo $post->acf->boolean('boolean_field_name');
PS: La méthode doit être appelée au format camel case. Part eemple, pour le champs de type
date_picker
vous devez écrire$post->acf->datePicker('fieldName')
. La libraire effectue la conversion de camel casse vers snake case pour vous.
Création de table
Doc à venir
Requètes avancées
La librairie étant compatible avec Eloquent, vous pouvez sans problème effectuer des requètes complexes sans tenir compte du contexte WordPress.
Par exemple, pour récupérer les clients dont l'age est supérieur à 40 ans :
$users = Capsule::table('customers')->where('age', '>', 40)->get();
Modèles personnalisés
Définition du modèle Eloquent
Pour ajouter vos propres méthode à un modèle existant, vous pouvez réaliser des "extends" de ce modèles. Par exemple, pour le modèle User
, vous pourriez produire le code suivant :
namespace App\Model; use \AmphiBee\Eloquent\Model\User as BaseUser; class User extends BaseUser { public function orders() { return $this->hasMany('\App\Model\User\Orders'); } public function current() { // fonctionnalité spécifique à l'utilisateur courant } public function favorites() { return $this->hasMany('Favorites'); } }
Un autre exemple serait de définir une nouvelle taxonomie à un article, par exemple country
namespace App\Model; user \AmphiBee\Eloquent\Model\Post as BasePost; class Post extends BasePost { public function countries() { return $this->terms()->where('taxonomy', 'country'); } } Post::with(['categories', 'countries'])->find(1);
Pour accéder au modèle d'un nouveau type de contenu, voici un exemple de ce qui pourrait être proposé :
namespace App\Model; class CustomPostType extends \AmphiBee\Eloquent\Model\Post { protected $post_type = 'custom_post_type'; public static function getBySlug(string $slug): self { return self::where('post_name', $slug)->firstOrfail(); } } CustomPostType::with(['categories', 'countries'])->find(1);
Requètes sur modèles personnalisés
Il est également possible de travailler avec des types de contenus personnalisés. Vous pouvez utiliser la méthode type(string)
ou créer vos propres classes :
// en utilisatn la méthode type() $videos = Post::type('video')->status('publish')->get(); // en définissant sa propore classe class Video extends AmphiBee\Eloquent\Model\Post { protected $postType = 'video'; } $videos = Video::status('publish')->get();
En utilisant la méthode type()
, l'objet retourné sera de type AmphiBee\Eloquent\Model\Post
. En utilisant son propre modèle, cela permet d'aller plus loin dans les possibilités en pouvant y associer des méthodes et des propriétés personnalisés et en retournant le résultat en tant qu'objet Video
par exemple.
Type de contenu personnalisé et méta-données :
// Récupération de 3 élément d'un type de contenu personnalisé et en récupérant une méta-donnée (address) $stores = Post::type('store')->status('publish')->take(3)->get(); foreach ($stores as $store) { $storeAddress = $store->address; // option 1 $storeAddress = $store->meta->address; // option 2 $storeAddress = $store->fields->address; // option 3 }
Shortcode
Implémentation en cours
Logs des requêtes
La Capsule de connexion étant directement rattachée à wpdb
, l'ensemble des requètes pourront être visualiser sur des outils de debugs tels que Query Monitor.