amphibee/wordpress-eloquent-models

WordPress 的 Eloquent ORM

v2.0.1 2024-07-12 14:03 UTC

This package is auto-updated.

Last update: 2024-09-12 14:17:23 UTC


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_titlecontent对于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

自定义作用域

为了排序PostUser类型的模型,你可以使用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();

图片

PostPage模型获取图像。

$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() 方法,并在参数中指定大小别名(例如 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(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 等调试工具中一样查看所有查询。