sanderdekroon/parlant

以一种表达的方式查询 WordPress 中的帖子。

0.1.0 2018-11-01 22:06 UTC

This package is auto-updated.

Last update: 2024-09-29 05:21:25 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Quality Score Total Downloads

Parlant 是一个 PHP 库,以表达的方式查询 WordPress 中的帖子。摆脱混乱的 WP_Query 数组,开始编写表达式的查询。

记得这个吗?

$args = array(
  'post_status' => 'future',
  'meta_query' => array(
     array(
        'key' => '_thumbnail_id',
        'value' => '',
        'compare' => '!='
     )
  )
);
$slider_posts = new WP_Query($args);

如果你可以简化成这样呢?

$slider_posts = Post::type('post')
    ->where('post_status', 'future')
    ->whereMeta('_thumbnail_id', '!=', '')
    ->get();

Parlant 是一个查询构建器,这意味着你可以以简单和表达的方式构建查询。它仍然在底层使用 WP_Query,但它消除了构建参数的痛苦和杂乱。

安装

通过 Composer

$ composer require sanderdekroon/parlant

使用

基本使用

Parlant 的语法深受 Laravel 的 Query Builder 包的启发。

要开始构建查询,只需在 Parlant 类上调用静态方法 type()。将查询的 posttype 传递给 type() 方法,或者调用 all() 查询所有 posttype。

这些方法返回一个 PosttypeBuilder 实例,您可以在其上链接多个方法。通过调用 get() 结束查询,以获取查询的所有结果。

虽然 Parlant 在后台使用 WP_Query,但它覆盖了一些默认设置。Parlant 默认将返回所有找到的帖子('posts_per_page' => -1),而不是默认值。可以通过更改 Parlant 的设置来覆盖此行为。

例如:获取所有 'article' 类型的帖子

use Sanderdekroon\Parlant\Posttype as Post;

$articles = Post::type('article')->get();

变量 $articles 现在将包含 WP_Post 实例的数组。或者,Parlant 可以配置为返回 WP_Query 实例或查询参数的数组。也可以注入自己的输出格式化程序。

限制结果

除了更改 Parlant 的配置外,还可以将任何限制方法传递给查询构建器。您可以通过调用 first() 返回第一个结果,而不是通过调用 get() 返回结果。

$article = Post::type('article')->first();

根据您的配置,这将返回一个 WP_Post 实例。请记住,您可以定义自己的输出设置。

当您需要返回特定数量的帖子时,请将 limit() 方法添加到查询中,并以 get() 结束。

$fiveArticles = Post::type('article')->limit(5)->get();

指定结果

使用 where() 方法来指定结果。基本上,所有用于 WP_Query 外部数组的参数都通过此方法支持。

例如,您可以在 PosttypeBuilder 上调用 where('author', 7) 来指定作者。想要获取 1970 年的所有帖子?直接这样做: where('year', 1970)

一个简单的带有 where() 的查询看起来像这样

use Sanderdekroon\Parlant\Posttype as Post;

// Get all articles that are within the category called 'linux', 
// limited to 5 results.
Post::type('articles')
    ->where('category_name', 'linux')
    ->limit(5)
    ->get();

可以添加多个 where 语句,应用限制方法并排序结果。所有都在一个链中。

// Get articles written by author 42, within the category called 'Meaning of Life' 
// and limit it to 14 results.
Post::type('articles')
    ->where('author', '42')
    ->where('category_name', 'Meaning of Life')
    ->orderBy('title', 'ASC')
    ->limit(14)
    ->get();

元查询

当然,您也可以使用 WP_Query 类的 meta_query。只需添加 whereMeta() 方法。这意味着您将查询特定的 post_meta 键/值组合。例如

// Get all posts within the posttype 'post' where the post_meta key 'foo' should be equal to 'bar'.
Post::type('post')->whereMeta('foo', '=', 'bar')->get();

操作符

您可以传递任何支持的运算符。如果没有提供运算符,Parlant 默认使用 '='。

// Get all posts within the 'post' posttype where the post_meta key 'secretkey' is not equal to 'hunter2'.
Post::type('post')->whereMeta('secretkey', '!=', 'hunter2')->get();

由于 Parlant 利用 WP_Query 类,因此您可以传递 WP_Query 支持的任何运算符。以下为运算符列表

=, !=, >, >=, <, <=, LIKE, NOT LIKE, IN, NOT IN,
BETWEEN, NOT BETWEEN, NOT EXISTS, REGEXP, NOT REGEXP, RLIKE

元类型

您还可以指定要查询的元类型。如果您提供元类型,则必须提供运算符。

Post::type('shoes')->whereMeta('size', '=', 37, 'NUMERIC')->get();

默认元类型是 'CHAR',在大多数(基本)情况下应该足够。您可以传递 WP_Query 支持的任何元类型。以下为类型列表

NUMERIC, BINARY, CHAR, DATE, DATETIME,
DECIMAL, SIGNED, TIME, UNSIGNED

与WP_Query类类似,可以为DECIMAL和NUMERIC类型指定精度或比例。例如 'DECIMAL(10,5)' 或 'NUMERIC(10)' 是有效的元类型。

元关系

可以定义多个元查询之间的关系。默认情况下,通过链接多个whereMeta()方法将创建一个'AND'关系。使用orWhereMeta()将关系设置为'OR'。

例如:我们想查询类型为'shirts'的所有帖子,但只想查询尺寸为'M'或'L'的帖子。

Post::type('shirts')
    ->whereMeta('size', 'M')
    ->orWhereMeta('size', 'L')
    ->get();

要构建更复杂的元查询,请使用闭包来开始嵌套元查询。在上面的例子中,我们想获取所有尺寸为'M'或'L'且颜色为红色的衬衫。

Post::type('shirts')
    ->whereMeta(function() {
        return $this->where('size', 'M')->orWhere('size', 'L');
    })
    ->whereMeta('color', 'red')
    ->get();

当使用闭包时,使用orWhere()来指定嵌套查询之间的'OR'关系。默认为'AND'。

注意:Parlant知道闭包在whereMeta()方法内,因此不需要在闭包内调用whereMeta()。相反,只需调用where()方法即可。

注意:与正常的whereMeta()方法一样,您仍然可以传递不同的操作符和元类型。

嵌套疯狂

Parlant会递归地解决所有嵌套查询,因此查询级别没有硬性限制。

Post::type('*')->whereMeta(function() {
        return $this->relation('OR')
            ->where('size', 'L')
            ->where('size', 'M')
            ->where(function() {
                return $this->relation('AND')
                    ->where('color', 'RED')
                    ->where('fit', 'slim')
                    ->where(function() {
                        return $this->where('foo', 'bar')
                        ->where('bar', 'baz');
                    });
            });
    })->get()

尽管可以将查询嵌套得相当深,但我不会推荐超过3层。

只是为了您的理智。

分类查询/术语查询

除了自定义帖子元数据外,还可以查询自定义分类。与元查询类似,通过使用whereTerm()方法开始分类/术语查询。首先传入分类,然后是术语字段,操作符(可选)和最后是术语值。

// Get all posts within the posttype 'jeans' that are within the term called '37' of the 'size' taxonomy.
Post::type('jeans')->whereTerm('size', 'name', 'IN', 37)->get();

当然,您可以通过传递其他分类查询操作符。省略操作符将使Parlant回退到默认的'IN'操作符。

注意:与元查询不同,分类查询有不同的操作符。操作符是IN、NOT IN、AND、EXISTS、NOT EXISTS。

分类/术语关系

多个分类查询之间的关系处理与元查询相同。默认情况下,通过链接多个whereTerm()方法将创建一个'AND'关系。使用orWhereTerm()将关系设置为'OR'。

例如:我们想查询类型为'jeans'的所有帖子,但只想查询尺寸为'32'或'33'的帖子。在这个例子中,尺寸是分类。

Post::type('jeans')
    ->whereTerm('size', 'name', '32')
    ->orWhereTerm('size', 'name', '33')
    ->get();

分类/术语查询也支持嵌套查询。有一个区别:不需要指定查询的字段,因为有不同的方法负责处理。当您在构建嵌套查询的闭包内时,只需调用您想要查询的字段作为方法。例如slug()name()id()termTaxonomyId()

从上面的例子继续,我们想获取所有尺寸为'32'或'33'且颜色为'blue'的牛仔裤。

Post::type('jeans')
    ->whereTerm(function() {
        return $this->relation('OR')
            ->name('size', '32')
            ->name('size', '33');
    })
    ->whereTerm('color', 'term_slug', 'blue')
    ->get();

在嵌套分类查询内,可以混合使用不同的方法。

设置默认分类

当您在单个分类内查询大量值时,可以为嵌套分类查询设置默认分类。不是立即开始闭包,而是先传入分类名称,然后是闭包。

// Query all jeans that are either in the term 32, 33, 34 or 35, within the 'size' taxonomy.
Post::type('jeans')
    ->whereTaxonomy('size', function () {
        return $this->relation('OR')->name('32')->name('33')->name('34')->name('35');
    })->get();

配置

Parlant的默认配置可以随时更改,但建议尽早配置,以避免意外结果。通过在Parlant实例上调用configure()方法来执行更改。

这些设置是全局设置的,因此每次开始查询时无需更改配置。Parlant配置自己以返回所有已发布的帖子,并将找到的帖子作为WP_POST实例的数组返回。

use Sanderdekroon\Parlant\Configurator\ParlantConfigurator;

ParlantConfigurator::globally([
    'posts_per_page'    => -1,
    'post_type'         => 'any',
    'post_status'       => 'publish',
    'return'            => 'array',
]);

注意:这是默认配置,无需复制此确切代码。将其用作参考或起点。

现在让我们将默认的posts_per_page从-1更改为9。

use Sanderdekroon\Parlant\Configurator\ParlantConfigurator;

ParlantConfigurator::globally(['posts_per_page' => 9]);

更改输出

Parlant使用输出格式化器来决定如何输出查询结果。默认情况下,它将返回一个WP_Post实例数组。如果您想开始一个WP_Query循环,只需更改Parlant的默认设置

use Sanderdekroon\Parlant\Configurator\ParlantConfigurator;

ParlantConfigurator::globally(['return' => 'query']);

此配置将使Parlant在所有查询中返回一个WP_Query实例。如果您只想更改一个查询的输出,请对PosttypeBuilder实例调用setConfig()方法

use Sanderdekroon\Parlant\Posttype as Post;

Post::any()->setConfig('return', 'query')->get();

Parlant有三个内置输出格式化器

  • array,将输出一个WP_Post实例数组
  • argument,将输出原始查询参数
  • query,将输出一个WP_Query实例

或者,您可以通过提供完全命名空间的全类名来提供自己的输出格式化器。格式化器应遵循Sanderdekroon\Parlant\Formatter\FormatterInterface接口,如下所示

namespace Sanderdekroon\Parlant\Formatter;

interface FormatterInterface
{

    public function output(array $queryArguments);
}

output()方法始终接收一个参数数组。以下是一个查询格式化器的示例

namespace Sanderdekroon\Parlant\Formatter;

use WP_Query;

class QueryFormatter implements FormatterInterface
{
    /**
     * Return an instance of WP_Query
     * @param  array  $arguments
     * @return WP_Query
     */
    public function output(array $arguments)
    {
        $query = new WP_Query($arguments);

        return $query;
    }
}

方法

以下是一个支持的方法及其参数列表。一些方法尚未实现,但将在未来的版本中添加。

返回结果

get() - 返回所有结果

first() - 仅返回第一个结果。

all() - 与get相同,但忽略limit()方法或其他任何默认设置。

count() - 返回表示找到的文章数量的整数。

find($id) - 返回ID等于传入整数的单个结果(如果有)。

pluck($column_name) - 仅返回指定列名的数组。

avg('column_name') - 将触发BadMethodCallException,因为此功能尚未实现。

max('column_name') - 将触发BadMethodCallException,因为此功能尚未实现。

min('column_name') - 将触发BadMethodCallException,因为此功能尚未实现。

限制方法

limit($number) - 限制输出到传入的数量。

select('column_name') - 将触发BadMethodCallException,因为此功能尚未实现。

Where

where($column, $value) - 指定结果。

whereMeta() - 通过搜索特定的元键/值关系来指定结果。

whereTaxonomy() - 通过搜索特定的分类/术语关系来指定结果。

whereBetween() / whereNotBetween() - 将触发BadMethodCallException,因为此功能尚未实现。

whereIn() / whereNotIn() - 将触发BadMethodCallException,因为此功能尚未实现。

排序

orderBy($column, $direction = null) - 按给定列对结果进行排序。方向参数是可选的。

order($direction) - 指定结果应按哪个方向排序。通常不需要此操作,因为可以使用orderBy()方法指定方向。

groupBy() - 将触发BadMethodCallException,因为此功能尚未实现。

inRandomOrder() - 将触发BadMethodCallException,因为此功能尚未实现。

变更日志

有关最近更改的详细信息,请参阅CHANGELOG

测试

$ composer test

贡献

有关详细信息,请参阅CONTRIBUTING

安全性

如果您发现任何安全问题,请通过sander@dekroon.xyz而不是使用问题跟踪器发送电子邮件。

许可

MIT许可(MIT)。有关更多信息,请参阅许可文件