highliuk/wp-eloquent

WordPress的Eloquent ORM

2.0.1 2024-01-29 11:38 UTC

This package is auto-updated.

Last update: 2024-09-29 13:05:57 UTC


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 中找到别名(例如,titlepost_titlecontentpost_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

自定义作用域

要排序 PostUser 模型,您可以使用 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();

图像

PostPage 模型检索图像。

$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() 方法并输入大小别名作为参数(例如,thumbnailmedium)。如果缩略图已生成,则方法返回包含元数据的对象,否则返回原始 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)上查看。