Base Manager
WNCMS 提供 ModelManager 作为所有 Manager classes 的基础。它集中管理资料撷取、过滤、排序、快取与分页。
概述
ModelManager 是一个抽象类别,位于:
Wncms\Services\Managers\ModelManager每个具体的 Manager(如 PostManager、LinkManager)都应该继承它,并实作必要的方法:getModelClass() 和 buildListQuery()。
主要特性
- 统一的查询建构:标准化的方式来建构查询(tags、keywords、status 等)
- 快取支援:整合 WNCMS Cache 机制以提升效能
- 网站范围:自动套用 multi-site 过滤(若启用)
- 分页与限制:内建
count、offset、page_size处理 - Eager loading:简化关联载入
- 可扩充性:易于覆写方法来客制化行为
必须实作的方法
getModelClass()
abstract public function getModelClass(): string;用途: 回传此 Manager 所处理的 Model class 名称。
范例:
public function getModelClass(): string
{
return wncms()->getModelClass('post');
}此方法使用 wncms()->getModelClass() 来尊重 config/wncms.php 中的 model 覆写设定。
buildListQuery()
abstract protected function buildListQuery(array $options): mixed;用途: 定义如何建构清单查询。此方法套用过滤条件、排序、限制等。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
$options | array | 过滤、排序、分页相关选项 |
预期回传: 一个 Eloquent Builder 实例或原始 query。
范例:
protected function buildListQuery(array $options): mixed
{
$q = $this->query();
$this->applyTagFilter($q, $options['tags'] ?? [], $options['tag_type'] ?? 'post_category');
$this->applyKeywordFilter($q, $options['keywords'] ?? [], ['title', 'content']);
$this->applyStatus($q, 'status', $options['status'] ?? 'published');
$sort = $options['sort'] ?? 'id';
$direction = $options['direction'] ?? 'desc';
$this->applyOrdering($q, $sort, $direction, $sort === 'random');
return $q;
}常用公开方法
get(array $options = []): ?Model
撷取单一记录。
常见选项:
| 选项 | 类型 | 说明 |
|---|---|---|
id | int | 以 ID 撷取 |
slug | string | 以 slug 撷取 |
name | string | 以 name 撷取 |
withs | array | 要 eager load 的 relations |
wheres | array | 额外的 where 条件 |
cache | bool | 是否使用快取(预设 true) |
seconds | int | 快取时间(秒),预设为 gss('data_cache_time') 或 3600 |
范例:
$post = wncms()->post()->get(['slug' => 'hello-world']);getList(array $options = []): mixed
撷取记录集合或分页结果。
常见选项:
| 选项 | 类型 | 说明 |
|---|---|---|
page | int | 分页页码 |
page_size | int | 每页笔数 |
count | int | 限制笔数(不分页时使用,0 = 不限制) |
offset | int | 跳过笔数 |
cache | bool | 是否使用快取(预设 true) |
seconds | int | 快取时间(秒),预设为 gss('data_cache_time') 或 3600 |
withs | array | 要 eager load 的 relations |
wheres | array | 额外的 where 条件 |
sort | string | 建议使用的排序栏位 |
direction | string | 建议使用的排序方向:asc 或 desc |
范例:
$posts = wncms()->post()->getList([
'page_size' => 10,
'status' => 'published',
'sort' => 'created_at',
'direction' => 'desc',
]);排序参数规范
建议在 Manager 对外选项中优先使用 sort 与 direction。
run(array $options = []): mixed
在没有快取的情况下执行 buildListQuery()。
范例:
$query = wncms()->post()->run([
'tags' => ['news'],
'count' => 5,
]);回传的是 Builder 实例,你可以继续链结额外的查询方法。
内建的过滤 Helpers
ModelManager 提供多个 helper 方法来简化过滤逻辑:
| Method | 说明 |
|---|---|
applyIds($q, $column, $ids) | 依 ID 过滤 |
applyExcludeIds($q, $column, $ids) | 排除特定 ID |
applyTagFilter($q, $tags, $type) | 依 tag 类型过滤 |
applyExcludedTags($q, $excludedTagIds) | 排除特定 tag ID |
applyKeywordFilter($q, $keywords, $columns) | 套用关键字搜寻 |
applyStatus($q, $column, $status) | 依状态过滤 |
applyWebsiteId($q, $websiteId) | 依网站 ID 限定范围 |
applyOrdering($q, $column, $sequence, $isRandom) | 套用排序 |
applyLimit($q, $count) | 限制笔数 |
applyOffset($q, $offset) | 跳过记录 |
applyWiths($q, $relations) | Eager load 多个关联 |
这些方法确保所有 WNCMS Manager 的行为一致。
多站点模式 Helper
Manager 也提供集中式模式检查方法:
public function getModelMultiWebsiteMode(): string
public function isModelWebsiteScoped(): bool这些方法会优先使用模型方法(getMultiWebsiteMode() / getWebsiteMode()),因此可以尊重运行时模式覆写。
显式 false 选项值
ModelManager 现在会把显式传入的 false 视为有效过滤值(例如 status => false),而不是当作空值忽略。
当你需要过滤布林栏位时,可直接这样写:
$items = wncms()->advertisement()->getList([
'status' => false,
]);Advertisement type 过滤示例
AdvertisementManager 现在支援按广告类型过滤(一种或多种)。
单一类型可使用 type:
$items = wncms()->advertisement()->getList([
'type' => 'image',
]);多类型可使用 types:
$items = wncms()->advertisement()->getList([
'types' => ['image', 'card'],
]);快取支援
ModelManager 与 wncms()->cache() 整合,自动处理快取键生成与失效。
设定属性:
| 属性 | 类型 | 说明 |
|---|---|---|
$cacheKeyPrefix | string | 用于生成快取键的前缀(例如 wncms_post) |
$cacheTags | string/array | 快取标签,用于批次失效(例如 ['posts']) |
$shouldAuth | bool | 是否在快取键中包含使用者 ID(预设 false) |
范例:
protected string $cacheKeyPrefix = 'wncms_product';
protected string|array $cacheTags = ['products'];
protected bool $shouldAuth = false;快取会在 get() 与 getList() 中自动启用,除非明确设定 cache => false。
扩充 ModelManager
要建立自订 Manager:
- 继承
ModelManager - 实作
getModelClass() - 实作
buildListQuery() - (选用)覆写
get()或getList()来自订行为
自订 App Manager 解析
当你用动态方式呼叫 manager(例如 wncms()->post())时,WNCMS 会依照这个顺序解析:
App\Services\Managers\{Name}ManagerWncms\Services\Managers\{Name}Manager
App manager 会优先透过 Laravel container 解析,因此建构子相依性可自动注入。
WNCMS 也支援单复数别名查找。例如 wncms()->catalog_item() 与 wncms()->catalog_items() 都可解析到 App\Services\Managers\CatalogItemManager。
范例:
namespace App\Services\Managers;
use Wncms\Services\Managers\ModelManager;
class ProductManager extends ModelManager
{
protected string $cacheKeyPrefix = 'wncms_product';
protected string|array $cacheTags = ['products'];
public function getModelClass(): string
{
return wncms()->getModelClass('product');
}
protected function buildListQuery(array $options): mixed
{
$q = $this->query();
$this->applyTagFilter($q, $options['tags'] ?? [], 'product_category');
$this->applyKeywordFilter($q, $options['keywords'] ?? [], ['name', 'description']);
$this->applyStatus($q, 'status', $options['status'] ?? 'active');
return $q;
}
}详细指南请参阅 Create a Manager。
核心对齐说明
- Core 已移除
BannerManager。横幅/广告位请统一使用AdvertisementManager(wncms()->advertisement())。 StarterManager现已改为基于ModelManager的脚手架模板,用于复制后快速创建新 manager。SettingManager仍为特殊的键值管理器,不继承ModelManager,以保持gss()/uss()依赖的get($key, $fallback)、update($key, $value)API。SettingManager仍已对齐动态模型解析:查询前会通过wncms()->getModelClass('setting')解析模型类。
Tag 模型兼容性
ModelManager::applyTagFilter() 现在接受弹性输入(mixed),并动态解析 tag 模型类。
解析顺序:
config('wncms.models.tag.class')或config('wncms.models.tag')wncms()->getModelClass('tag')
这样可兼容 package/custom tag 模型实例,不再强依赖继承 Wncms\Models\Tag。