amphibee / wordpress-eloquent-models
WordPress 的 Eloquent ORM
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
WordPress Eloquent Model 组件是一个完整的工具包,提供 ORM 和模式生成器。它支持 MySQL、Postgres、SQL Server 和 SQLite。它将 WordPress 表转换为与 Eloquent 兼容的 模型。
该库非常适合与 Roots 的 Bedrock / Sage 一起使用。
不再需要使用过时的 WP_Query 类,我们进入未来世界,生成可读和可重用的代码!还有其他功能可供在 WordPress 中进行自定义体验。
与 Eloquent 兼容的库,如果您有点困惑,可以查看 ORM 文档 :)
目录
安装
推荐的安装方法是 Composer。
composer require amphibee/wordpress-eloquent-models
配置
数据库连接(通过 $wpdb)在第一次调用 Eloquent 模型时执行。如果您需要获取连接实例,只需运行以下代码即可(优先使用 use
)
AmphiBee\Eloquent\Database::instance();
支持的模型
文章
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;
状态
默认情况下,Post
返回所有状态的文章。这可以通过 本地作用域 published
修改,仅返回已发布文章。
Post::published()->get();
还可以通过 本地作用域 status
定义状态。
Post::status('draft')->get();
文章类型
默认情况下,Post
返回所有内容类型。这可以通过 本地作用域 type
覆盖。
Post::type('page')->get();
评论
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
术语
在这个版本中,Term
作为模型可用,但只能通过文章访问。不过,只需扩展 Term
即可将其应用于其他自定义内容类型。
$post->terms()->where('taxonomy', 'country');
用户
use \AmphiBee\Eloquent\Model\User; // Tous les utilisateurs $users = User::get(); // récupère l'utilisateur ayant pour ID 123 $user = User::find(123);
选项
在 WordPress 中,使用 get_option
函数获取选项。使用 Eloquent,您可以使用 Option
模型的 get
函数避免加载不必要的 WordPress 核心。
$siteUrl = Option::get('siteurl');
您还可以添加其他选项
Option::add('foo', 'bar'); // stockée en tant que chaine de caractères Option::add('baz', ['one' => 'two']); // le tableau sera sérialisé
您可以以数组形式获取所有选项(注意性能...)
$options = Option::asArray(); echo $options['siteurl'];
您还可以指定要获取的特定选项
$options = Option::asArray(['siteurl', 'home', 'blogname']); echo $options['home'];
菜单
要从别名获取菜单,请使用以下语法。菜单项将返回到 items
变量中(这是一个类型为 AmphiBee\Eloquent\Model\MenuItem
的对象集合)。
目前支持的菜单类型包括:页面、文章、自定义链接和分类。
一旦你有了MenuItem
模型,如果你想要使用原始实例(例如页面或术语),只需调用方法MenuItem::instance()
。MenuItem
对象只是类型为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 }
instance()
方法将返回相应的对象
Post
实例用于post
类型的菜单项;Page
实例用于page
类型的菜单项;CustomLink
实例用于custom
类型的菜单项;Term
实例用于category
类型的菜单项。
多级菜单
为了管理多级菜单,你可以通过迭代将其放置在正确的级别,例如。
你可以使用方法MenuItem::parent()
来获取菜单项的父实例
$items = Menu::slug('foo')->first()->items; $parent = $items->first()->parent(); // Post, Page, CustomLink ou Term (categorie)
为了按父级分组菜单,你可以在$menu->items
集合中使用方法->groupBy()
,这将根据父级($item->parent()->ID
)收集元素。
有关groupBy()
方法的更多信息,请参阅Eloquent 文档。
字段别名
Post
模型支持别名,因此如果你检查一个Post
对象,你可以在静态数组$aliases
中找到别名(例如,title
对于post_title
和content
对于post_content
)。
$post = Post::find(1); $post->title === $post->post_title; // true
你可以扩展Post
模型来创建自己的模型。只需在你的扩展模型中添加别名,它将自动继承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
自定义作用域
为了排序Post
或User
类型的模型,你可以使用newest()
和oldest()
作用域。
$newest = Post::newest()->first(); $oldest = Post::oldest()->first();
分页
为了分页结果,只需使用Eloquent的paginate()
方法。
// Affiche les posts avec 5 éléments par page $posts = Post::published()->paginate(5); foreach ($posts as $post) { // ... }
要显示分页链接,使用links()
方法。
{{ $posts->links() }}
元数据
Eloquent模型集成了WordPress的元数据管理。
以下是一个获取元数据的示例
// 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
要创建或更新用户的元数据,只需使用方法saveMeta()
或saveField()
。它们与Eloquent的save()
方法一样返回布尔值。
$post = Post::find(1); $post->saveMeta('username', 'amphibee');
可以在单个调用中保存多个元数据。
$post = Post::find(1); $post->saveMeta([ 'username' => 'amphibee', 'url' => 'https://amphibee.fr', ]);
库还提供了createMeta()
和createField()
方法,它们与saveX()
方法类似,但仅用于创建,并返回由实例创建的PostMeta
对象,而不是布尔值。
$post = Post::find(1); $postMeta = $post->createMeta('foo', 'bar'); // instance of PostMeta class $trueOrFalse = $post->saveMeta('foo', 'baz'); // boolean
根据自定义字段(元数据)查询文章
有多种方法可以通过在Post
模型(或使用HasMetaFields
特质的其他模型)上使用作用域从元数据(meta)执行查询。
要检查元数据是否存在,使用hasMeta()
作用域。
// Récupère le premier article ayant la méta "featured_article"
$post = Post::published()->hasMeta('featured_article')->first();
如果你想要针对具有特定值的元数据,可以使用带有值的hasMeta()
作用域。
// Récupère le premier article ayant une méta "username" et ayant pour valeur "amphibee" $post = Post::published()->hasMeta('username', 'amphibee')->first();
也可以通过传递到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();
如果你需要执行不区分大小写的字符串匹配或通配符匹配,可以使用带有值的hasMetaLike()
作用域。这会使用SQL的LIKE
运算符,因此请务必使用通配符'%'。
// 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();
图片
从Post
或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;
要获取特定大小的图片,请在对象上使用 ->size()
方法,并在参数中指定大小别名(例如 thumbnail
或 medium
)。如果已生成缩略图,则该方法返回包含元数据的对象;否则,返回原始 URL(WordPress 的行为)。
if ($post->thumbnail !== null) { /** * [ * 'file' => 'filename-300x300.jpg', * 'width' => 300, * 'height' => 300, * 'mime-type' => 'image/jpeg', * 'url' => 'https:///wp-content/uploads/filename-300x300.jpg', * ] */ print_r($post->thumbnail->size(AmphiBee\Eloquent\Model\Meta\ThumbnailMeta::SIZE_THUMBNAIL)); // https:///wp-content/uploads/filename.jpg print_r($post->thumbnail->size('invalid_size')); }
高级自定义字段
库提供了几乎所有 ACF 字段(除 Google Map 字段外)。它可以以最优方式获取字段,而无需通过 ACF 模块。
基本使用
要获取字段值,只需初始化一个 Post
类型的模型,并调用自定义字段
$post = Post::find(1); echo $post->acf->website_url; // retourne l'url fournie dans un champs ayant pour clé website_url
性能
当使用 $post->acf->website_url
时,会执行额外的查询来获取字段,根据 ACF 的方法。可以使用特定方法来避免这些额外的查询。只需指定用作函数的自定义内容类型即可
// 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:方法必须以驼峰式命名。例如,对于
date_picker
类型的字段,您必须编写$post->acf->datePicker('fieldName')
。库会为您执行驼峰式到蛇形命名的转换。
创建表
文档待更新
高级查询
由于库与 Eloquent 兼容,您可以无障碍地执行复杂的查询,而无需考虑 WordPress 的上下文。
例如,要获取年龄大于 40 岁的客户
$users = Capsule::table('customers')->where('age', '>', 40)->get();
自定义模型
定义 Eloquent 模型
要向现有模型添加自己的方法,可以实现该模型的“extends”。例如,对于 User
模型,您可以生成以下代码
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'); } }
另一个示例是定义文章的新分类,例如 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);
要访问新内容类型的模型,以下是一个示例
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);
查询自定义模型
还可以与自定义内容类型一起工作。您可以使用 type(string)
方法或创建自己的类
// 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();
使用 type()
方法时,返回的对象类型为 AmphiBee\Eloquent\Model\Post
。使用自己的模型可以进一步扩展功能,例如关联自定义方法和属性,并将结果作为 Video
等对象返回。
自定义内容类型和元数据
// 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 }
短代码
正在进行实施
查询日志
由于连接胶囊直接关联到 wpdb
,因此可以像在 Query Monitor 等调试工具中一样查看所有查询。