anthonybudd / wp_user
This package is not auto-updated.
Last update: 2020-01-24 16:53:26 UTC
README
一个用于创建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() 方法之前,不会将模型的分类法更改写入数据库。