highliuk / wp-eloquent
WordPress的Eloquent ORM
Requires
- php: >=8.0
- bordoni/phpass: ^0.3.5
- illuminate/database: ^9.0|^10.0
- illuminate/filesystem: ^9.0|^10.0
- illuminate/support: ^9.0|^10.0
- thunderer/shortcode: ^0.7.3
README
WP Eloquent是一个完整的工具箱,提供ORM和模式生成器。它支持MySQL、Postgres、SQL Server和SQLite。它将WordPress表转换为Eloquent兼容模型。
不再需要使用旧的WP_Query类,我们通过生成可读和可重用的代码进入未来的世界!还提供了额外的功能以获得定制的WordPress体验。
确保与Eloquent兼容的库,如果您有些迷茫,可以查阅ORM文档 :)
安装
推荐的安装方法是Composer。
composer require highliuk/wp-eloquent
设置
在第一次调用Eloquent模型时建立数据库连接(通过$ wpdb)。如果您需要检索连接实例,只需运行以下代码(优先使用use)
HighLiuk\Eloquent\Database::instance();
支持模型
文章
use HighLiuk\Eloquent\Model\Post; // Get the post with ID 1 $post = Post::find(1); // Related data available $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 HighLiuk\Eloquent\Model\Comment; // Get the comment with ID 12345 $comment = Comment::find(12345); // Related data available $comment->post; $comment->author; $comment->meta;
术语
在这个版本中,Term作为一个模型可以访问,但只能通过文章访问。然而,只需扩展Term即可将其应用于其他自定义内容类型。
$post->terms()->where('taxonomy', 'country');
用户
use HighLiuk\Eloquent\Model\User; // All users $users = User::get(); // Get the user with ID 123 $user = User::find(123);
选项
在WordPress中,使用get_option函数检索选项。使用Eloquent,为了避免加载WordPress核心的不必要加载,您可以使用Option模型的get函数。
$siteUrl = Option::get('siteurl');
您还可以添加其他选项
Option::add('foo', 'bar'); // stored as a string Option::add('baz', ['one' => 'two']); // the array will be serialized
您可以检索所有选项作为数组(注意性能...)
$options = Option::asArray(); echo $options['siteurl'];
您还可以指定要检索的特定选项
$options = Option::asArray(['siteurl', 'home', 'blogname']); echo $options['home'];
菜单
要从其别名检索菜单,请使用以下语法。菜单项将作为items变量返回(它是一个HighLiuk\Eloquent\Model\MenuItem对象集合)。
目前支持的菜单类型是:页面、文章、自定义链接和分类。
一旦您有了MenuItem模型,如果您想使用原始实例(例如Page或Term等),只需调用MenuItem::instance()方法。MenuItem对象只是一个post_type等于nav_menu_item的文章。
$menu = Menu::slug('primary')->first(); foreach ($menu->items as $item) { echo $item->instance()->title; // if it's a Post echo $item->instance()->name; // if it's a Term echo $item->instance()->link_text; // if it's a 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 or Term (category)
要按父级分组菜单,您可以在 $menu->items 集合中使用 ->groupBy() 方法,这将根据父级($item->parent()->ID)对项目进行分组。
有关 groupBy() 方法的更多信息,请参阅 Eloquent 文档。
## 自定义字段
Post 模型支持别名,因此您可能会在静态数组 $aliases 中找到别名(例如,title 为 post_title,content 为 post_content)。
$post = Post::find(1); $post->title === $post->post_title; // true
您可以通过扩展 Post 模型来创建自己的模型。只需将您的别名添加到扩展的模型中,它将自动继承 Post 模型中定义的别名。
class A extends \HighLiuk\Eloquent\Model\Post { protected static $aliases = [ 'foo' => 'post_foo', ]; } $a = A::find(1); echo $a->foo; echo $a->title; // retrieved from the Post model
自定义作用域
要排序 Post 或 User 模型,您可以使用 newest() 和 oldest() 作用域。
$newest = Post::newest()->first(); $oldest = Post::oldest()->first();
分页
要分页结果,请使用 Eloquent 的 paginate() 方法。
// Display posts with 5 items per page $posts = Post::published()->paginate(5); foreach ($posts as $post) { // ... }
要显示分页链接,请使用 links() 方法。
{{ $posts->links() }}
元数据
Eloquent 模型集包括 WordPress 元数据管理。
以下是一个检索元数据的示例
// Retrieves a meta (here 'link') from the Post model (we could have used another model like User) $post = Post::find(31); echo $post->meta->link; // OR echo $post->fields->link; echo $post->link; // OR
要创建或更新用户的元数据,只需使用 saveMeta() 或 saveField() 方法。它们返回一个布尔值,就像 Eloquent 的 save() 方法一样。
$post = Post::find(1); $post->saveMeta('username', 'highliuk');
您可以在单个调用中保存多个元数据。
$post = Post::find(1); $post->saveMeta([ 'username' => 'highliuk', 'url' => 'https://github.com/HighLiuk', ]);
该库还提供了 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 特性的任何其他模型)上的作用域从元数据(元数据)进行查询。
要检查元数据是否存在,请使用 hasMeta() 作用域。
// Retrieves the first article with the meta "featured_article" $post = Post::published()->hasMeta('featured_article')->first();
要检查元数据是否存在并且具有特定值,请使用带值的 hasMeta() 作用域。
// Retrieves the first article with the meta "username" and having the value "highliuk" $post = Post::published()->hasMeta('username', 'highliuk')->first();
您还可以通过传递给 hasMeta() 作用域的值数组来定义多个元数据和多个相关值进行查询。
$post = Post::hasMeta(['username' => 'highliuk'])->first(); $post = Post::hasMeta(['username' => 'highliuk', 'url' => 'highliuk.fr'])->first(); // Or just by providing the meta-data keys $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(); // Using the % operator, the following results will be returned: 'N Leroy', 'N LEROY', 'n leroy', 'Nico Leroy' etc. $post = Post::published()->hasMetaLike('author', 'N%Leroy')->first();
图像
从 Post 或 Page 模型检索图像。
$post = Post::find(1); // Retrieves an instance of HighLiuk\Eloquent\Model\Meta\ThumbnailMeta. print_r($post->thumbnail); // You must display the image instance to retrieve the url of the original image 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(HighLiuk\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; // returns the url provided in a field with the key website_url
性能
当使用 $post->acf->website_url 时,将执行额外的请求来根据 ACF 方法检索字段。您可以使用特定方法来避免这些额外的请求。只需输入用作函数的自定义内容类型即可。
// The method performing additional requests echo $post->acf->author_username; // it's a field relative to User // Without additional request echo $post->acf->user('author_username'); // Other examples without requests 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模型的定义
要向现有模型添加自己的方法,可以执行此模型的“扩展”。例如,对于User模型,可以编写以下代码
namespace App\Model; use \HighLiuk\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 \HighLiuk\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 \HighLiuk\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)方法或创建自己的类
// using the type() method $videos = Post::type('video')->status('publish')->get(); // by defining its own class class Video extends HighLiuk\Eloquent\Model\Post { protected $postType = 'video'; } $videos = Video::status('publish')->get();
使用type()方法,返回的对象将是类型为HighLiuk\Eloquent\Model\Post的对象。通过使用自己的模型,这允许你在可能性上更进一步,例如能够将自定义方法和属性关联到它,并将结果作为Video对象返回。
自定义内容类型和元数据
// Retrieving 3 elements of a custom content type and retrieving a meta-data (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)上查看。