本文介绍了如何使用 PHP 以及可用的模型与 Tailor 进行交互。
以下模型类可以观察到它们所关联的蓝图类型。
| Model Class | Blueprint Type |
|---|---|
Tailor\Models\EntryRecord | entry |
Tailor\Models\StructureRecord | structure |
Tailor\Models\StreamRecord | stream |
Tailor\Models\SingleRecord | single |
Tailor\Models\GlobalRecord | global |
EntryRecord 模型是一个用于存储条目内容的基础模型。除了您定义的表单字段之外,在检索到的模型上还可以找到以下属性。
| Attribute | Description |
|---|---|
| id | The Primary Key found in the database. |
| blueprint_uuid | The UUID of the associated blueprint. |
| content_group | The content group name, if used. |
| title | A title descriptor for the entry, for example, My Blog Post. |
| slug | A slug identifier for the entry, for example, my-blog-post. |
| is_enabled | Determines if the entry is currently visible. |
| created_at | The creation date for the entry. |
| updated_at | The last updated date for the entry. |
| expired_at | The expiry date for the entry. |
| published_at | The published date for the entry. |
| published_at_date | The published date, or if none is specified, the creation date. |
StructureRecord 模型扩展了 EntryRecord,并用于存储结构化条目的内容。如果条目类型是 structure,它将解析为此模型并拥有一些额外属性。
| Attribute | Description |
|---|---|
| fullslug | A slug identifier that includes parent slugs, for example, parent-slug/child-slug. |
| parent | The parent record for this entry, if available. |
| children | The child records for this entry, if available. |
StreamRecord 模型扩展了 EntryRecord 模型用于存储流式条目的内容。如果条目类型是 stream,它将具有一些额外属性。
| Attribute | Description |
|---|---|
| published_at_day | The numerical day the entry was published. |
| published_at_month | The numerical month the entry was published. |
| published_at_year | The numerical year the entry was published. |
要使用 PHP 处理条目, 您可以使用模型类(例如 EntryRecord) 并调用 inSection 静态方法, 传入句柄以返回一个准备好的[数据库模型查询](../../extend/database/query.md)。 或者, 您可以使用 UUID 和 inSectionUuid 方法查找它。
以下 get 方法查询返回 记录集合。
$records = EntryRecord::inSection('Blog\Post')->get();
$records = EntryRecord::inSectionUuid('a63fabaf-7c0b-4c74-b36f-7abf1a3ad1c1')->get();结合 where 约束,你可以使用 first 方法找到一条记录。下面将找到一个条目,其中 slug 等于 first-post。
$record = EntryRecord::inSection('Blog\Post')->where('slug', 'first-post')->first();如果一个 入口类型 被设置为 single, 你可以使用 findSingleForSection 方法来查找该入口. 同样地, findSingleForSectionUuid 可以用于通过 UUID 进行查找. 这些方法会确保在查找过程中记录存在.
$record = SingleRecord::findSingleForSection('Homepage');
$record = SingleRecord::findSingleForSectionUuid('3328c303-7989-462e-b866-27e7037ba275');inSection 方法可用于动态创建记录。以下将创建一个新的博客文章条目。相同的代码可用于在首次检索它之后更新现有记录。
$post = EntryRecord::inSection('Blog\Post');
$post->title = 'Imported Post';
$post->save();GlobalRecord 模型用于存储一个全局的内容。
除了定义的表单字段,在检索到的模型上可以找到以下属性。
| Attribute | Description |
|---|---|
| id | The Primary Key found in the database. |
| blueprint_uuid | The UUID of the associated blueprint. |
要使用 PHP 查找全局项,您可以使用 Tailor\Models\GlobalRecord 模型并调用 findForGlobal 静态方法,传入其句柄。或者,您可以使用 UUID 以及 findForGlobalUuid 方法查找它。
GlobalRecord::findForGlobal('Blog\Config');
GlobalRecord::findForGlobalUuid('7b193500-ac0b-481f-a79c-2a362646364d');相关字段可以包括 中继器字段 和 条目字段,并且读写这些字段需要一些额外步骤。
读取相关字段时,你可以使用 load 方法在集合上预加载它们。此方法使相关内容作为单个查询可用,并且性能最佳。
以下预加载了 categories 字段并将其添加到结果中,以及一个传递多个相关字段的示例。
$records->load('categories');
$records->load(['categories', 'author']);在编写关联字段时,您可以将关联名称作为方法调用,以返回关联定义,然后可以调用一个后续的create()方法,该方法会返回新创建的关联。
以下定位在 Blog\Post 部分中的第一个博客文章,然后创建一个关联类别。
$post = EntryRecord::inSection('Blog\Post')->first();
$post->categories()->create(['title' => 'Test', 'price' => '100']);使用 make() 方法创建一个新的空模型实例。
$category = $post->categories()->make();如果类别已存在,请改用 add() 方法。下面将第一个博客类别添加到第一个博客文章中。
$post = EntryRecord::inSection('Blog\Post')->first();
$category = EntryRecord::inSection('Blog\Category')->first();
$post->categories()->add($category);查看 关联文章 以了解有关模型关系的更多信息。
:::
类似于 扩展常规模型,您可以扩展 EntryRecord 模型构造函数,使用 extendInSection 方法以针对特定的蓝图。 extendInSectionUuid 方法也可以用于进行更精确的定位。
EntryRecord::extendInSection('Blog\Post', function($model) {
$model->bindEvent('model.afterDelete', function () use ($model) {
// Model has been deleted!
});
});GlobalRecord 模型构造函数也支持使用 extendInGlobal 和 extendInGlobalUuid 方法来针对特定蓝图进行扩展。
GlobalRecord::extendInGlobal('Blog\Config', function($model) {
$model->bindEvent('model.beforeSave', function () use ($model) {
// Model has been saved!
});
});
extendInSectionUuid和extendInGlobalUuid方法即使找不到蓝图,也不会抛出异常。
在某些情况下您可能希望将定制模型与常规数据库模型结合使用。
使用 modelClass 蓝图属性,当你需要 Tailor 蓝图包含更复杂的功能时。这将把蓝图解析为一个自定义模型实例。
handle: Blog\Post
type: stream
name: Blog Post
modelClass: App\Models\TailorBlogPost
# ...所定义的模型必须扩展蓝图类型所使用的确切模型类,这一点很重要。在上面的示例中,我们必须扩展 StreamRecord 类,因为它使用了 stream 类型。
namespace App\Models;
use Tailor\Models\StreamRecord;
class TailorBlogPost extends StreamRecord
{
// Custom model logic goes here
}现在,每当蓝图被解析时,它将是 TailorBlogPost 类的一个实例。
recordfinder 表单字段引入了一个关系定义到一个常规模型,例如一个由插件定义的模型。modelClass 应该指向模型类,并且对于单数关系,list 属性是必需的,正如由 maxItems 指定的。
products:
label: Products
type: recordfinder
modelClass: Acme\Test\Models\Product
list: $/acme/test/models/product/columns.yaml
maxItems: 1了解更多关于 记录查找器表单小部件此处。
由于所有 Tailor 模型共享相同的模型类,您的关系定义中需要一些额外的属性。 此Tailor\Traits\BlueprintRelationModel 实现了这些属性以引用 Tailor 模型,支持“属于”和“多对多”关系。
当特性 BlueprintRelationModel 在您的模型中实现时, 您可以提供一个 blueprint 属性, 以及引用 tailor blueprint 的 blueprint UUID. 以下将与 Tailor\Models\EntryRecord 类建立一个名为 author 的 Belongs To 关系.
class Product extends Model
{
use \Tailor\Traits\BlueprintRelationModel;
public $belongsTo = [
'author' => [
\Tailor\Models\EntryRecord::class,
'blueprint' => '6947ff28-b660-47d7-9240-24ca6d58aeae'
]
];
}您也可以引用一个常规模型,使用一个实现特定的字段类型,例如,一个客户内容字段可能被硬编码到一个 Customer 模型类。这涉及创建一个自定义的定制字段,该字段将提供对模型和数据库表的完整访问。
在内容字段类定义中,extendModelObject 方法允许内容字段扩展记录模型,以及 extendDatabaseTable 用于向数据库表添加列。
class MyContentField extends ContentFieldBase
{
public function extendModelObject($model)
{
$model->belongsTo[$this->fieldName] = MyOtherModel::class;
}
public function extendDatabaseTable($table)
{
$table->integer($this->fieldName . '_id')->nullable();
}
}这需要多花一点功夫才能使其正常运行,但结果是一个简单的字段类型定义,配置量极小。
myfield:
label: My Field
type: mycontentfield了解更多关于构建自定义 Tailor 字段详情。