idetik / coretik
Idetik WP 主题核心
Requires
- globalis/wp-cubi-helpers: ^1.0
- globalis/wp-cubi-transient-cache: ^0.3.0
- illuminate/collections: ^10.6
- johnbillion/extended-cpts: ^5.0
- nesbot/carbon: ^2.66
- pelago/emogrifier: ^7.0
- pimple/pimple: ^3.5
- wesbos/burner-email-providers: ^1.0
Requires (Dev)
Suggests
- idetik/coretik-navigation: Navigation service, resolve breadcrumb and page title
- idetik/coretik-page-builder: Page builder service
- dev-master
- v1.9.2
- v1.9.1
- v1.9.0
- v1.8.3
- v1.8.2
- v1.8.1
- v1.8.0
- v1.7.2
- v1.7.1
- v1.7.0
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.7
- v1.5.6
- v1.5.5
- v1.5.4
- v1.5.3
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.8
- v1.4.7
- v1.4.6
- v1.4.5
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.15
- v1.3.14
- v1.3.13
- v1.3.12
- v1.3.11
- v1.3.10
- v1.3.9
- v1.3.8
- v1.3.7
- v1.3.6
- v1.3.5
- v1.3.4
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.17
- v1.2.16
- v1.2.15
- v1.2.14
- v1.2.13
- v1.2.12
- v1.2.11
- v1.2.10
- v1.2.9
- v1.2.8
- v1.2.7
- v1.2.6
- v1.2.5
- v1.2.4
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.1
- v1.0.0
- dev-feature_relationship
- dev-develop
This package is auto-updated.
Last update: 2024-09-26 19:06:48 UTC
README
Coretik:WordPress 框架
管理模型、查询、服务等...
安装
composer require idetik/coretik
开始使用
依赖注入容器
Coretik 应用使用 Pimple 作为依赖注入容器。与其他依赖注入容器类似,Pimple 管理两种不同类型的数据:服务和参数。请阅读 Github 上的官方文档:https://github.com/silexphp/Pimple。Coretik 随带几个内置服务。您可以在 src/Services
中找到它们(在 todoux 列表中有文档...)
首先,在您的 functions.php 中创建应用程序容器
use Coretik\App; use Coretik\Core\Container; $container = new Container(); $container['my-service'] = function ($container) { return new MyService(); }; App::run($container);
模式:声明自定义帖子类型和分类法
简单用例
use Coretik\Core\Builders\Taxonomy; use Coretik\Core\Builders\PostType; // Declare post type PostType::make('my_custom_post_type') ->setSingularName('Title') ->setPluralName('Titles') ->addToSchema(); // Declare taxonomy Taxonomy::make('my_taxonomy') ->setSingularName('Title') ->setPluralName('Titles') ->for('my_custom_post_type') ->addToSchema();
高级
帖子类型
use Coretik\Core\Builders\Taxonomy; use App\Model\MyModel; use App\Query\MyQuery; use App\Handler\MyHandlerA; use App\Handler\MyHandlerB; // Accept same arguments as register_post_type() (https://developer.wordpress.org/reference/functions/register_post_type/) and register_extended_post_type() (https://github.com/johnbillion/extended-cpts/wiki/Registering-Post-Types) $register_extended_post_type_args = []; PostType::make('my_custom_post_type') ->setSingularName('Title') ->setPluralName('Titles') ->setArgs($register_extended_post_type_args) // Optional, ->factory(MyModel::class) // Optional, you can add a custom model factory or use the default factory built in Coretik ->querier(MyQuery::class) // Optional, you can add a custom query class or use the default querier built in Coretik ->handler(MyHandlerA::class) // Optional, you can use many handlers on the same builder ->handler(MyHandlerB::class) ->attach('myMacroA', 'my_callable') // Optional, you can attach all callables you want ->attach('myMacroB', 'my_callable') ->addToSchema();
分类法
use Coretik\Core\Builders\Taxonomy; use App\Model\MyTermModel; use App\Query\MyTermQuery; use App\Handler\MyTermHandlerA; use App\Handler\MyTermHandlerB; // Accept same arguments as register_taxonomy() (https://developer.wordpress.org/reference/functions/register_taxonomy/) and register_extended_taxonomy() (https://github.com/johnbillion/extended-cpts/wiki/Registering-taxonomies) $register_extended_taxonomy_args = []; Taxonomy::make('my_custom_taxonomy') ->setSingularName('Title') ->setPluralName('Titles') ->setArgs($register_extended_taxonomy_args) // Optional, ->factory(MyTermModel::class) // Optional, you can add a custom model factory or use the default factory built in Coretik ->querier(MyTermQuery::class) // Optional, you can add a custom query class or use the default querier built in Coretik ->handler(MyTermHandlerA::class) // Optional, you can use many handlers on the same builder ->handler(MyTermHandlerB::class) ->attach('myMacroA', 'my_callable') // Optional, you can attach all callables you want ->attach('myMacroB', 'my_callable') ->addToSchema();
模型
作为 MVC 设计模式中的模型,它只包含纯应用数据。这使得随着时间的推移更容易维护和扩展应用程序。它支持帖子类型和分类法或其他自定义内容之间的关联。
设置
use Coretik\Core\Models\Wp\PostModel; class MyPostModel extends PostModel { public function foo() { return 'bar'; } } $postSchema = app()->schema('post'); $postSchema->factory(MyPostModel::class);
用法
$models = app()->schema('post')->query()->models(); foreach ($models as $model) { echo $model->foo(); // 'bar' }
高级
模型可以轻松处理帖子元数据,包括受保护的元数据。模型提供了类似对象属性的元访问器。元数据必须在模型构造函数中声明。仅在 CRUD 操作中声明的元数据才会被保存到数据库中。
use Coretik\Core\Models\Wp\PostModel; use Coretik\Core\Models\Interfaces\ModelInterface; use Coretik\Core\Collection; class MyPostModel extends PostModel { protected function intializeModel(): void { $this->declareMetas([ 'ma_meta_a' => 'bdd_field_name', 'ma_meta_b' => 'other_bdd_field_name', ]); // Each meta // @see Core/Models/MetaDefinition.php $this->metaDefinition('ma_meta_a')->castTo('array'); $this->metaDefinition('ma_meta_b')->protectWith(fn ($model) => (bool)$model->canIUpdateThisValue()); } public function canIUpdateThisValue(): bool { // @todo create a guard return true; } public function foo(): string { if (in_array('bar', $this->get('ma_meta_a'))) { return 'bar'; } return 'foo'; } /** * Accessor * * To define an accessor, create a getFooAttribute method on your model where Foo is the "studly" cased name of the column you wish to access. * In this example, we'll define an accessor for the first_name attribute. The accessor will automatically be called when attempting to retrieve the value of the first_name attribute: */ public function getFirstNameAttribute(): string { if (empty($this->get('ma_meta_b'))) { return 'toto'; } return $this->get('ma_meta_b'); } /** * Mutator * * To define a mutator, define a setFooAttribute method on your model where Foo is the "studly" cased name of the column you wish to access. * So, again, let's define a mutator for the first_name attribute. This mutator will be automatically called when we attempt to set the value of the first_name attribute on the model: */ public function setFirstNameAttribute($value) { $this->ma_meta_b = strtolower($value); } /** * Relationships * * For now, only post <-> taxonomy relationships are ready to use with wp-admin. * Posts to posts relationships (1, n) require an extra handler on the post type builder, who update the post_parent column on save post. * We are working to include this feature on a next release. */ public function setCategory(ModelInterface|int|string $category): self { $current = $this->category(); if (!empty($current)) { $this->detachTerm($current, 'my_category_taxonomy'); } $this->setTerm($category, 'my_category_taxonomy'); return $this; } public function category(): ?ModelInterface { return $this->hasOne('my_category_taxonomy'); } public function setAttributes(array $attributes): self { $this->attributes()->each(fn ($attribute) => $this->detachTerm($attribute, 'my_attributes_taxonomy')); $this->attributes = []; foreach ($attributes as $attr) { $this->setTerm($attribute, 'my_attributes_taxonomy'); } return $this; } public function attributes(): Collection { return $this->hasMany('my_attributes_taxonomy'); } public function addToGroup(int $post_group_id): self { $this->post_parent = $group_id; return $this; } public function group(): ?ModelInterface { return $this->belongsTo('my_post_type_group'); // require an extra handler } } $postSchema = app()->schema('my_custom_post_type'); $postSchema->factory(MyPostModel::class);
创建并保存模型
$model = app()->schema('my_custom_post_type')->model(); $model->post_title = 'Mr Bar Foo'; $model->post_status = 'publish'; $model->ma_meta_a = 'Foo'; $model->first_name = 'Bar'; $model->setAttributes(['smart', 'tall']); $model->addToGroup(100); // a post with title 'Groupe 1' from 'my_post_type_group' with ID 100, $model->save(); $modelId = $model->id();
使用模型
$myModel = app()->schema('my_custom_post_type')->model($modelId); echo $myModel->foo(); // foo echo $myModel->ma_meta_a; // ['Foo'] echo $myModel->first_name; // bar echo $myModel->ma_meta_b; // bar echo $myModel->group()->title(); // Groupe 1 $myModel->attributes()->each(fn ($attributeModel) => echo $attributeModel->title() . ', '); // smart, tall,
查询
使用 Coretik 查询检索复杂子句后面的模型。查询比需要直接管理元数据、分类法和设置的基wp_query 更易于阅读和使用。有四种类型的查询可供使用:PostQuery、TermQuery、UserQuery 和 CommentQuery。
简单查询
查询所有通过默认查询参数过滤的 wp_post 的方法,并浏览结果模型
见 src/Core/Query/Post::getQueryArgsDefault()
$models = app()->schema('my_custom_post_type')->query()->models(); foreach ($models as $model) { echo $model->title(); }
其他查询
见 src/Core/Query/Adapters
文件夹。
自定义查询
设置
use Coretik\Core\Query\Post as PostQuery; use Coretik\Core\Models\Interfaces\ModelInterface; class MyPostQuery enxtends PostQuery { public function myCustomFilter(): self { $this->set([...]); $this->whereMeta([...]); $this->whereTax([...]); return $this; } public function ordered(): self { $this->set('orderby', 'menu_order title'); $this->set('order', 'ASC'); return $this; } public function category(int $category): self { $this->whereTax('my_taxonomy', $category); return $this; } public function inGroup(int $group_id): self { $this->set('post_parent', $group_id); return $this; } public function withAttribute(string $attribute): self { $this->whereTax('my_attributes_taxonomy', $attribute, 'IN', 'slug'); return $this; } } $postSchema = app()->schema('my_custom_post_type'); $postSchema->querier(MyPostQuery::class);
用法
$result = app() ->schema('my_custom_post_type') ->query() ->ordered() ->inGroup(100) ->withAttribute('smart') ->or('small') ->whereMeta('ma_meta_b', 'bar') ->first(); echo $result->title(); // Mr Bar Foo
处理器
处理器旨在可重用、可维护和灵活。处理器允许我们挂钩帖子类型或分类法相关的任何内容,并允许我们根据需要修改默认工作流程。
您的处理器必须实现 Coretik\Core\Builders\Interfaces\HandlerInterface;
让我们以一个应用程序为例,该应用程序有许多属于分类的培训。每个培训有许多属于同一分类的事件。我们有一个培训帖子类型、一个事件帖子类型和一个分类法。我想在更改培训分类时更新事件分类。
use Coretik\Core\Builders\Interfaces\HandlerInterface; use Coretik\Core\Builders\Interfaces\HandlerInterface; /** * Reset session domain on formation saving */ class FormationCategoryOnChangeHandler implements HandlerInterface { private $builder; public function handle(BuilderInterface $builder): void { $this->builder = $builder; \add_action('set_object_terms', [$this, 'setEventsCategory'], 10, 6); } public function freeze(): void { \remove_action('set_object_terms', [$this, 'setEventsCategory'], 10, 6); } public function setEventsCategory($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids) { // Ensure current post editing belongs to our builder if (!$this->builder->concern((int)$object_id)) { return; } // Bypass if any diff about terms after save (You have to verify the taxonomy name if many taxonomies exist) if (empty(\array_diff($tt_ids, $old_tt_ids))) { return; } $model = $this->builder->model((int)$object_id); $model->events()->each(fn ($event) => $event->setCategories($tt_ids)->save()); } }
宏
用于扩展构建器。
PostType::make('my_custom_post_type') ->setSingularName('Title') ->setPluralName('Titles') ->attach('myMacroA', fn ($input) => 'my_custom_post_type : ' . $input) // Optional, you can attach all callables you want ->addToSchema(); echo app()->schema('my_custom_post_type')->myMacroA('foo'); // my_custom_post_type : foo