anthonybudd/wp_user

此包已被弃用,不再维护。未建议替代包。
此包的最新版本(dev-master)没有可用的许可证信息。

dev-master 2017-08-07 16:22 UTC

This package is not auto-updated.

Last update: 2020-01-24 16:53:26 UTC


README

68747470733a2f2f63312e737461746963666c69636b722e636f6d2f312f3431352f33313835303438303531335f366366326235626464655f622e6a7067

一个用于创建WordPress帖子活动记录模型的简单类。

WP_Model是一个为WordPress设计的伪ORM,旨在提供使用简单的OOP语法处理帖子的一种更好的方法。WP_Model专门设计得尽可能简单,以便前端开发者(辅助方法、分类法)和具有初级PHP知识的开发者使用,但功能强大(虚拟属性、关系、事件),足以真正有助于想要制作复杂基于WP项目的后端开发者。

简介:Medium文章

高级功能:Medium文章


Class Product extends WP_Model
{
    public $postType = 'product';
    public $attributes = [
        'color',
        'weight'
    ];
}

Product::register();

$book = new Product;
$book->title = 'WordPress for dummies';
$book->color = 'Yellow';
$book->weight = 100;
$book->save();

安装

使用composer要求WP_Model

$ composer require anthonybudd/WP_Model

或者

下载WP_Model类并在functions.php文件顶部要求它。不推荐这样做。

设置

然后您需要创建一个继承自WP_Model的类。此类需要公共属性$postType和$attributes,这是一个字符串数组。

Class Product extends WP_Model
{
    public $postType = 'product';

    public $attributes = [
        'color',
        'weight'
    ];
    
    public $prefix = 'wp_model_'; // Optional
}

如果您需要在您的post_meta表中的模型数据前加前缀,请添加公共属性$prefix。这将添加到post meta中,因此属性'color'将使用meta_key 'wp_model_color'保存到数据库中

注册

在您能够创建帖子之前,您需要注册帖子类型。您可以通过在functions.php文件中调用静态方法register()来完成此操作。

Product::register();

Product::register([
    'singular_name' => 'Product'
]);

可选地,您还可以向此方法提供一个参数数组,该数组将直接发送到WordPress的register_post_type()函数的第二个参数。

创建和保存

您可以使用以下方法创建模型。

$product = new Product();
$product->color = 'white';
$product->weight = 300;
$product->title = 'the post title';
$product->content = 'the post content';
$product->save();

$product = new Product([
    'color' => 'blue',
    'weight' => '250'
]);
$product->save();

$product = Product::insert([
    'color' => 'blue',
    'weight' => '250'
]);

检索模型

find()

如果数据库中存在具有该ID的帖子,find()将返回一个实例化的模型;如果找不到帖子,则返回NULL。

$product = Product::find(15);

findOrFail()

如果数据库中没有找到正确类型的帖子,findOrFail()方法将抛出异常。

try {
    $product = Product::findorFail(15);
} catch (Exception $e) {
    echo "Product not found.";
}

all()

all()将返回所有帖子。请谨慎使用。

$allProducts = Product::all();

in()

要按ID查找多个帖子,可以使用in()方法。

$firstProducts = Product::in([1, 2, 3, 4]);

链式查找器

如果您希望使用链式OOP语法查找模型,则query()方法是对where()方法的封装。每个可链式查找方法meta()和tax()都可以接受不同数量的参数。您必须调用execute()方法来运行查询。

meta()

Product::query()
    ->meta('meta_key', 'meta_value')
    ->meta('meta_key', 'compare', 'meta_value')
    ->meta('meta_key', 'compare', 'meta_value', 'type')

tax()

Product::query()
    ->tax('taxonomy', 'terms')
    ->tax('taxonomy', 'field', 'terms')
    ->tax('taxonomy', 'field', 'operator', 'terms')

params()

WP_Query的额外参数数组。

Product::query()
    ->params(['orderby' => 'meta_value', 'order' => 'ASC])

示例

$products = Product::query()
    ->meta('color', 'blue')
    ->execute();
$products = Product::query()
    ->meta('color', 'red')
    ->meta('weight', '>', 2000, 'NUMERIC')
    ->tax('type', 'small')
    ->tax('category', ['office', 'home'])
    ->tax('quality', 'slug', 'high')
    ->tax('county', 'term_id', 'NOT IN', [1, 5])
    ->params(['orderby' => 'meta_value menu_order title'])
    ->execute();

删除

delete()

delete()会将帖子移动到回收站。

$product = Product::find(15);
$product->delete();

restore()

restore()将取消删除帖子并将其模型恢复。您不能恢复已永久删除的模型。

$product = Product::restore(15);

hardDelete()

hardDelete()将删除帖子并将所有元数据(在数据库和对象中)设置为NULL。

$product->hardDelete();

辅助属性

$new属性将返回true,如果模型尚未在数据库中保存。

$dirty属性将返回true,如果模型中的数据与数据库中当前存储的数据不同。

$product = new Product;
$product->new; // Returns (bool) true

$product = Product::find(15);
$product->new; // Returns (bool) false

$product->color = 'red';
$product->dirty; // Returns (bool) true
$product->save();
$product->dirty; // Returns (bool) false

$product->title; // Returns the post's title

$product->content; // Returns the post's content

$product->the_content; // Returns the post's content via the 'the_content' filter

辅助方法

Product::single(); // Returns the current model if on a single page or in the loop

Product::exists(15); // Returns (bool) true or false

Product::mostRecent($limit = 1); // Returns the most recent post

Product::mostRecent(10); // Returns the most recent 10 posts [Product, Product, Product, Product]

Product::count($postStatus = 'publish'); // Efficient way to get the number of models (Don't use count(WP_Model::all()))

$product->postDate($format = 'd-m-Y'); // Returns the post date based on the format supplied

$product->get($attribute, $default) // Get attribute from the model

$product->set($attribute, $value) // Set attribute of the model

$product->post() // Returns the WP_Post object (This will be the post at load, any updates to the post (title, content, etc) will not be reflected)

$product->permalink() // Returns the post permalink

$product->hasFeaturedImage() // Returns TRUE if a featured image has been set or FALSE if not

$product->featuredImage($defaultURL) // Returns the featured image URL

$product->toArray() // Returns an array representation of the model

Product::asList() // Returns array of posts keyed by the post's ID
[
    15 => Product,
    16 => Product,
    17 => Product
]

// You can also specify the value of each element in the array to be meta from the model.
Product::asList('post_title')
[
    15 => "Product 1",
    16 => "Product 2",
    17 => "Product 3"
]

虚拟属性

如果您想向模型添加虚拟属性,可以通过添加一个以'_get'为前缀的方法名来实现。


Class Product extends WP_Model
{
    ...

    public $virtual = [
        'humanWeight'
    ];

    public function _getHumanWeight()
    {  
        return $this->weight . 'Kg';
    }
}

$product = Product::find(15);
echo $product->humanWeight;

默认属性

要为模型中的属性设置默认值,请使用$default属性。该数组的键是您希望设置默认值的属性,值是默认值。


Class Product extends WP_Model
{
    ...

    public $default = [
        'color' => 'black'
    ];
}

$product = new Product;
echo $product->color; // black

过滤属性

如果您需要解析属性后再返回,可以使用过滤方法。您必须将属性名添加到名为$filter的数组中,并创建一个以'_filter'为前缀的方法,该方法必须接受一个参数,这将是一个属性值。

或者,如果您想通过现有的函数(例如intval()、number_format()、your_function()等)传递值,可以通过使用关联数组语法将所需的函数名称作为值命名来实现。注意:如示例代码所示,您可以使用两种过滤方法同时进行。

当您将属性值设置为WP_Model或WP_Model实例的对象时,或者当您保存一个WP_Model数组时,都会导致模型单独保存。父模型只会存储子模型的ID(或ID数组)。要作为实例化模型检索这些属性值,请将过滤属性值设置为所需模型的类。


Class Product extends WP_Model
{
    ...

    public $filter = [
        'weight'
        'stock' => 'number_format',
        'seller' => Seller::class,
        'related' => Product::class,
    ];

    public function _filterWeight($value){
        return intval($value);
    }
}

$product = Product::insert([
    'weight' => 250,
    'stock' => '3450',
    'seller' => Seller::find(3),
    'related' => [
        new Product,
        new Product,
        new Product,
    ]
]);

$product->weight;  // (int) 250
$product->stock;   // (string) 3,450
$product->seller;  // (object) Seller
$product->related; // (array) [Product, Product, Product]

注意:WP_Model会在需要时动态加载子模型。如果您在没有显式请求子模型(例如$product->seller)的情况下转储模型,父模型只会存储子模型的ID。

序列化

如果您想对模型进行JSON编码并保留虚拟属性,可以在模型中添加$serialize属性。相反,如果您想隐藏属性,可以通过在模型中添加$protected来实现。

序列化将触发序列化事件。


Class Product extends WP_Model
{
    ...

    public $serialize = [
        'humanWeight',
    ];

    public $protected = [
        'weight',
    ];

    public function _getHumanWeight()
    {  
        return $this->weight . 'Kg';
    }
}

$product = Product::find(15);
echo json_encode($product);

结果

{
    "ID":           15,
    "title":        "The post title",
    "content":      "The post content",
    "color":        "blue",
    "HumanWeight":  "250Kg"
}

高级查找

Where(String $metaKey, String $metaValue) Where(Array $WPQuery)

where() 是 WP_Query 的简单接口,该方法可以接受两个字符串参数 meta_value 和 meta_key。

对于复杂的查询,将一个数组作为参数传递给该方法。该数组将自动分解为分类查询和元查询,然后执行 WP_Query,并返回模型数组。

$greenProducts = Product::where('color', 'green');

$otherProducts = Product::where([
    [
        'key' => 'color',
        'value' => 'green',
        'compare' => '!='
    ],[
        'taxonomy' => 'category',
        'terms' => ['home', 'garden']
    ]
]);

finder()

finder() 方法允许您创建自定义查找方法,这是在您的模型类中包含常用 WP_Query 的最佳方式。要创建自定义查找方法,首先在您的模型中创建一个名为“finders name”的方法,并以前缀“_finder”开头,该方法必须返回一个数组。该数组将直接传递给 WP_Query 的构造函数。finder() 方法将返回 WP_Query 的结果。您可以通过将数组作为静态方法 finder() 的第二个参数提供来向查找方法提供额外的参数,如下所示('heavyWithArgs')。

如果您想对自定义查找的结果进行后处理,可以添加一个 '_postFinder' 方法。该方法必须接受一个参数,该参数将是找到的帖子数组。


Class Product extends WP_Model
{
    ...

    public function _finderHeavy($args)
    {  
        return [
            'meta_query' => [
                [
                    'key' => 'weight',
                    'compare' => '>',
                    'type' => 'NUMERIC',
                    'value' => '1000'
                ]
            ]
        ];
    }

    // Optional
    public function _postFinderHeavy($results)
    {  
        return array_map(function($model){
            if($model->color == 'green'){
                return $model->color;
            }
        }, $results);
    }


    // Finder with optional args
    public function _finderHeavyWithArgs($args)
    {  
        return [
            'paged'      => $args['page'], // 3
            'meta_query' => [
                [
                    'key' => 'weight',
                    'compare' => '>',
                    'type' => 'NUMERIC',
                    'value' => '1000'
                ]
            ]
        ];
    }
}

$heavyProducts = Product::finder('heavy');

// Finder with optional args
$heavyProducts = Product::finder('heavyWithArgs', ['page' => 3]); 

事件

WP_Model 具有事件系统,这是 hook 到 WP_Model 核心功能的最佳方式。所有以 -ing 结尾的事件在方法被调用时立即触发。所有以 -ed 结尾的事件将在方法末尾触发。以下是可用事件的列表。所有事件都将提供触发事件的模型。

您还可以从 WordPress 的管理部分触发保存、插入和删除事件。

  • booting
  • booted
  • saving
  • inserting
  • inserted
  • saved
  • deleting
  • deleted
  • hardDeleting
  • hardDeleted
  • serializing

当保存新模型时,保存、插入、已插入和已保存事件都会被触发(按此顺序)。

Class Product extends WP_Model
{
    ...
    
    public function saving(){
        echo "The save method has been called, but nothing has been written to the database yet.";
    }
    
    public function saved($model){
        echo "The save method has completed and the post and it's meta data have been updated in the database.";
        echo "The Model's ID is". $model->ID;
    }
}

分类法

如果您希望将任何分类法加载到模型中,请将可选的公共属性 $taxonomies(分类法 slugs 的数组)添加到类中。

Class Product extends WP_Model
{
    ...
    public $taxonomies = [
        'category',
    ];
}

您可以通过在实例化模型时提供它来设置模型的分类法,该数组可以是术语 slugs 或术语 _ids 的组合。您可以通过获取名为分类法名称的属性来访问模型的术语。

$product = Product::insert([
    'title' => 'product',
    'color' => 'blue',
    'weight' => '250',
    'category' => ['home', 3]
]);

$product->category; // ['Home', 'Office'];

如果您想要直接访问分类法对象,可以使用 getTaxonomy() 方法。第一个参数是分类法名称,第二个参数是可选的,它是从术语对象中提取的属性。如果不提供第二个参数,将返回 WP_Term 对象。

$product->getTaxonomy('category'); // [WP_Term, WP_Term];
$product->getTaxonomy('category', 'term_id'); // [2, 3];
$product->getTaxonomy('category', 'name'); // ['Home', 'Office'];

您可以使用 addTaxonomy() 方法添加分类法。第一个参数是分类法名称,第二个参数可以是术语_id(必须是整数)或术语 slug(必须作为字符串提供)。如果找不到术语,该方法将返回 FALSE。

如果您想要向模型添加多个术语,可以使用 addTaxonomies() 方法。第二个参数必须是术语 slugs 和/或术语_ids 的数组。

$product->addTaxonomy('category', 'home');
$product->addTaxonomy('category', 3);

$product->addTaxonomies('category', ['home', 'office']);
$product->addTaxonomies('category', ['home', 3]);
$product->addTaxonomies('category', [2, 3]);

要从不属于模型的术语中删除术语,您可以使用 removeTaxonomy() 和 removeTaxonomies() 方法。这些方法与上面显示的 addTaxonomy() 和 addTaxonomies() 方法类似。

$product->removeTaxonomy('category', 'home');
$product->removeTaxonomy('category', 3);

$product->removeTaxonomies('category', ['home', 'office']);
$product->removeTaxonomies('category', [2, 3]);

要删除与指定分类法关联的所有术语,请使用 clearTaxonomy()。

$product->clearTaxonomy('category');
$product->getTaxonomy('category'); // [];

在您调用 save() 方法之前,不会将模型的分类法更改写入数据库。