PostManager
PostManager получает записи выбранного типа, формирует списки одного или нескольких типов и подготавливает данные для вывода в шаблоне.Поддерживает
- получение названий категорий типа записей и выбранных категорий записи
- получение опубликованной записи по URL и языку
- получение списка для выбранного языка или всех языков
- получение общего списка записей нескольких типов
- получение записей по идентификаторам
- получение опубликованных переводов записи
- подсчёт записей по условиям и языку
- формирование локализованных URL записей
- учёт просмотров
- создание краткого описания из содержимого
- выбор возвращаемых полей
- фильтрацию по обычным полям и метаполям
- числовую сортировку
- безопасную работу без произвольных SQL-фрагментов
Для работы с одним типом создаётся экземпляр менеджера. Общий список нескольких типов можно получить статическим методом.
Быстрый старт
$postManager = new PostManager('news');
$posts = $postManager->getPublishedList(
orderBy: 'publish_date',
limit: 10,
columns: [
'id',
'title',
'url',
'content',
]
);
foreach ($posts as $post) {
?>
<article>
<h2>
<a href="<?php echo $post['post_url']; ?>">
<?php echo $post['title']; ?>
</a>
</h2>
<p><?php echo $post['short_description']; ?></p>
</article>
<?php
}Поля post_url и short_description создаются менеджером на основе выбранных url и content.
Создание менеджера
__construct(string $postType, ?Database $db = null)
Первым параметром передаётся системное имя типа записей:
$postManager = new PostManager('news');Допустимы латинские буквы, цифры, _ и -.
Если имя имеет недопустимый формат, выбрасывается InvalidArgumentException.
Без второго аргумента используется основная база данных CMS. При необходимости можно передать другой экземпляр Database:
$postManager = new PostManager(
'news',
$database
);Названия категорий
getCategoryNames(): array
Возвращает названия категорий, настроенных для типа записей менеджера. Ключи массива соответствуют ключам категорий.
$postManager = new PostManager('news');
$names = $postManager->getCategoryNames();Если у типа записей нет категорий, возвращается пустой массив.
getSelectedCategoryNames(array $categories): array
Возвращает названия только тех категорий, у которых в переданном массиве значение непустое. Ключи категорий сохраняются.
$postManager = new PostManager('news');
$posts = $postManager->getPublishedList(limit: 10, columns: ['id', 'title', 'category']);
foreach ($posts as $post) {
$selectedNames = $postManager->getSelectedCategoryNames($post['category'] ?? []);
}Здесь поле category запрошено явно: getPublishedList() возвращает его как массив. Если выбранных категорий нет, метод возвращает пустой массив.
Получение записи по URL
getPublishedByUrl(string $url, ?string $language = null): ?array
Возвращает опубликованную запись по её URL и языку:
$post = $postManager->getPublishedByUrl('release-notes');
$englishPost = $postManager->getPublishedByUrl('release-notes', 'en');Если язык не передан, используется текущий язык CMS, а при его отсутствии — язык сайта по умолчанию. Передаётся код языка, а не URL-префикс.
Начальные и конечные / удаляются. Вложенные сегменты не поддерживаются.
Метод возвращает null, если URL пустой, содержит вложенные сегменты, запись не найдена, не опубликована или её дата публикации ещё не наступила.
Результат получает поля post_type, post_url и, при наличии content, short_description. Структурированные поля возвращаются в исходном формате базы данных.
Формирование URL
getUrl(string $slug, ?string $language = null): string
Формирует локализованный публичный URL записи:
$url = $postManager->getUrl('release-notes');
$englishUrl = $postManager->getUrl('release-notes', 'en');Если язык не передан, используется текущий язык CMS, а при его отсутствии — язык сайта по умолчанию.
Если идентификатор пустой или содержит /, выбрасывается InvalidArgumentException.
RuntimeException выбрасывается, если для типа записей не настроен публичный URL или ссылка недоступна для выбранного языка.
Получение списка
getList(array $where = [], string $orderBy = 'id', string $order = 'DESC', ?int $limit = null, int $offset = 0, array $columns = ..., ?string $language = null, bool $allLanguages = false, bool $numeric = false): array
Возвращает записи выбранного типа по условиям, без автоматического ограничения по статусу и дате публикации.
Например, получение черновиков:
$postManager = new PostManager('news');
$posts = $postManager->getList(where: ['status' => 'save'], limit: 10, columns: ['id', 'title']);По умолчанию используется текущий язык, а при его отсутствии — язык сайта по умолчанию. Параметр allLanguages: true отключает автоматический языковой фильтр, но не отменяет условия $where.
Если подходящих записей нет, возвращается пустой массив. Для получения только опубликованных записей используйте getPublishedList().
getPublishedList(string $orderBy = 'id', string $order = 'DESC', ?int $limit = null, int $offset = 0, array $columns = ..., ?string $language = null, bool $allLanguages = false, bool $numeric = false, array $where = []): array
Возвращает список опубликованных записей:
$posts = $postManager->getPublishedList(
orderBy: 'publish_date',
order: 'DESC',
limit: 10,
offset: 0
);Параметры
| Параметр | Тип | Описание |
|---|---|---|
$orderBy |
string |
Поле сортировки. По умолчанию id. |
$order |
string |
Направление ASC или DESC. |
$limit |
int|null |
Максимальное количество записей. |
$offset |
int |
Смещение. Используется только вместе с $limit. |
$columns |
array |
Список возвращаемых полей. |
$language |
string|null |
Код языка или null для автоматического определения. |
$allLanguages |
bool |
Отключить автоматический языковой фильтр. |
$numeric |
bool |
Сортировать значения $orderBy как числа. По умолчанию false. |
$where |
array |
Условия отбора. Для методов Published применяются дополнительно к правилам публикации. |
Если язык не передан, используется текущий язык CMS, а при его отсутствии — язык сайта по умолчанию:
$englishPosts = $postManager->getPublishedList(
limit: 10,
language: 'en'
);Чтобы получить записи всех языков, передайте true в $allLanguages:
$posts = $postManager->getPublishedList(
limit: 10,
allLanguages: true
);При $allLanguages = true автоматический языковой фильтр не добавляется, а $language игнорируется. Условия $where продолжают применяться. При явном выборе полей менеджер автоматически добавляет language, если оно ещё не выбрано.
Допустимые поля сортировки:
idtitledatepublish_datemodified_dateviewsmeta.<ключ>— значение метаполя
По умолчанию из базы данных выбираются:
idtitleurlimgauthordatepublish_datemodified_dateviews
Каждый результат дополнительно получает поле post_type.
Если выбранное поле url содержит корректный идентификатор записи, результат также получает post_url.
Чтобы получить дополнительные поля, передайте их через параметр $columns:
$posts = $postManager->getPublishedList(
limit: 10,
columns: [
'id',
'title',
'url',
'content',
'meta',
]
);При выборе content менеджер добавляет поле short_description.
Если выбраны структурированные поля, они преобразуются в массивы:
metacategoryglobal_metaglobal_categorycommentseo
Фильтрация
Параметр $where позволяет отбирать записи по обычным полям и метаполям. Для метаполя используется имя meta.<ключ>. Условия разных полей внутри одного массива объединяются через И.
В примерах используется тип products с текстовыми метаполями color и price:
$postManager = new PostManager('products');
$where = ['author' => 5, 'meta.color' => 'red'];
$posts = $postManager->getPublishedList(limit: 10, where: $where);
$count = $postManager->countPublished(where: $where);Будут выбраны опубликованные записи автора с ID 5, у которых метаполе color имеет значение red. Подсчёт использует те же условия, но не ограничивается десятью записями.
Числовые сравнения
Для числового сравнения текстовых значений укажите 'numeric' => true внутри условия. Параметр сортировки $numeric на сравнения не влияет.
Например, выбор записей с ценой от 100 до 500 включительно:
$postManager = new PostManager('products');
$where = [
'$and' => [
['meta.price' => ['>=' => 100, 'numeric' => true]],
['meta.price' => ['<=' => 500, 'numeric' => true]],
],
];
$posts = $postManager->getPublishedList(limit: 10, where: $where);Одно правило содержит один оператор сравнения. Поэтому границы диапазона передаются отдельными условиями.
Для числового сравнения поддерживаются =, !=, >, <, >=, <= и in. Значения сравнения должны быть конечными числами или числовыми строками. Нечисловые значения самого поля не проходят такое сравнение.
Группа $and объединяет условия через И, $or через ИЛИ. Группы можно вкладывать друг в друга.
Условия для строк мультиполя
Оператор any-row выбирает записи, у которых хотя бы одна строка мультиполя удовлетворяет указанным условиям.
Пусть в мультиполе offers первый столбец содержит цвет, а второй размер. Номера столбцов начинаются с 0:
$postManager = new PostManager('products');
$where = ['meta.offers' => ['any-row' => [0 => 'red', 1 => 'XL']]];
$posts = $postManager->getPublishedList(limit: 10, where: $where);В одной строке должны одновременно находиться red в первом столбце и XL во втором. Совпадения в разных строках не подходят.
Внутри any-row также можно использовать группы $and, $or и числовые сравнения. Условия не должны быть пустыми; вложенный any-row не поддерживается.
Числовая сортировка
Чтобы сортировать текстовое метаполе по числовому значению, передайте numeric: true:
$postManager = new PostManager('products');
$posts = $postManager->getPublishedList(orderBy: 'meta.price', order: 'ASC', limit: 10, numeric: true);Значения 2, 10 и 100 будут расположены именно в таком порядке.
При одинаковых значениях метаполя записи дополнительно сортируются по id в том же направлении. Отсутствующие, пустые и нечисловые значения располагаются в конце при обоих направлениях сортировки.
Параметр $numeric влияет только на сортировку и не включает числовое сравнение в условиях $where.
Получение записей нескольких типов
getListByTypes(array $postTypes, array $where = [], string $orderBy = 'id', string $order = 'DESC', ?int $limit = null, int $offset = 0, array $columns = ..., ?string $language = null, bool $allLanguages = false, ?Database $db = null, bool $numeric = false): array
Возвращает общий список записей нескольких типов без автоматического ограничения по статусу и дате публикации:
$posts = PostManager::getListByTypes(['news', 'articles'], where: ['status' => 'save'], limit: 10, columns: ['id', 'title']);В примере выбираются черновики из обоих типов. Сортировка и ограничение применяются к общему списку, а не отдельно к каждому типу.
Условия и параметры выбора языка работают как у getList(). Повторяющиеся имена типов учитываются один раз; пустой массив типов возвращает пустой список.
Выбираемые поля должны существовать у всех переданных типов. Поле post_type добавляется автоматически, указывать его в $columns не нужно.
Для получения только опубликованных записей используйте getPublishedListByTypes().
getPublishedListByTypes(array $postTypes, string $orderBy = 'id', string $order = 'DESC', ?int $limit = null, int $offset = 0, array $columns = ..., ?string $language = null, bool $allLanguages = false, ?Database $db = null, bool $numeric = false, array $where = []): array
Статический метод возвращает общий список опубликованных записей нескольких типов:
$columns = ['id', 'title', 'url'];
$posts = PostManager::getPublishedListByTypes(['news', 'articles'], orderBy: 'publish_date', limit: 10, columns: $columns);Создавать отдельные экземпляры PostManager для этого вызова не нужно.
Первым параметром передаётся массив системных имён типов записей. Повторяющиеся имена учитываются один раз. Если передан пустой массив, метод возвращает пустой список.
Остальные параметры сортировки, ограничения, выбора полей и языка работают так же, как в getPublishedList().
Каждая запись дополнительно получает поле post_type, содержащее системное имя её типа. Передавать post_type в $columns не нужно: менеджер добавляет его автоматически.
Сортировка и ограничение применяются к общему результату всех переданных типов, а не отдельно к каждому типу.
Другой экземпляр Database можно передать параметром $db.
Переводы записи
getPublishedTranslations(string $translationKey): array
Возвращает опубликованные языковые варианты, объединённые одним значением translation_key:
$translations = $postManager->getPublishedTranslations(
$post['translation_key']
);Каждый элемент содержит id, url, language, seo и добавленное поле post_type. Поле seo преобразуется в массив. Если для языка можно сформировать ссылку, также добавляется post_url.
Результат сортируется по id по возрастанию. Если ключ пустой, имеет недопустимый формат или опубликованные варианты не найдены, метод возвращает пустой массив.
Получение записей по ID
getByIds(array $ids, array $columns = ['*']): array
Возвращает записи выбранного типа по идентификаторам:
$postManager = new PostManager('news');
$posts = $postManager->getByIds([15, 27], ['id', 'title', 'url']);Метод не фильтрует записи по статусу, дате публикации или языку. Для получения опубликованных записей выбранного языка используйте getPublishedByIds().
Принимаются положительные целые числа и строки с корректным целочисленным значением. Повторяющиеся идентификаторы учитываются один раз; некорректные значения и отсутствующие записи пропускаются.
Результат — список массивов данных записей, отсортированный по ID по возрастанию. Порядок идентификаторов в $ids не определяет порядок результата.
По умолчанию запрашиваются все поля. Каждая запись получает post_type. При выборе url менеджер также запрашивает language и формирует post_url, если ссылка доступна. При выборе content добавляется short_description. Структурированные поля преобразуются в массивы.
Если подходящих записей нет, возвращается пустой массив. Пустой $columns вызывает InvalidArgumentException.
getPublishedByIds(array $ids, array $columns = ..., ?string $language = null): array
Возвращает опубликованные записи по идентификаторам:
$posts = $postManager->getPublishedByIds([
15,
27,
42,
]);Идентификаторы приводятся к целым числам. Нулевые, отрицательные и повторяющиеся значения исключаются.
Результат сортируется по id по возрастанию.
Если язык не передан, используется текущий язык CMS, а при его отсутствии — язык сайта по умолчанию.
Для получения записей определённого языка передайте его код:
$englishPosts = $postManager->getPublishedByIds(
[15, 27],
language: 'en'
);Для выбора дополнительных полей передайте второй параметр:
$posts = $postManager->getPublishedByIds(
[15, 27],
[
'id',
'title',
'url',
'content',
'meta',
]
);Правила добавления post_url, short_description и преобразования структурированных полей совпадают с правилами списка.
Если после проверки не осталось допустимых идентификаторов, метод возвращает пустой массив.
Дополнительные поля
post_type
Добавляется к каждой записи и содержит системное имя типа:
$postType = $post['post_type'];post_url
Добавляется, если в результате присутствует поле url с непустым идентификатором без вложенных сегментов:
$url = $post['post_url'];URL учитывает публичный путь типа записей и язык, выбранный при вызове метода. При выборке всех языков или переводов используется язык каждой отдельной записи.
short_description
Добавляется, если в результате присутствует поле content:
$description = $post['short_description'];При подготовке краткого описания:
- декодируются HTML-сущности
- удаляются HTML-теги
- удаляется содержимое
script,style,noscriptиtemplate - переносы и повторяющиеся пробелы заменяются одним пробелом
- текст сокращается примерно до
180символов - при сокращении текст по возможности завершается на границе слова
- к сокращённому тексту добавляется
...
Если текст короче установленного ограничения, многоточие не добавляется.
Подсчёт записей
count(array $where = [], ?string $language = null, bool $allLanguages = false): int
Подсчитывает записи выбранного типа по условиям. Правила выбора языка такие же, как у getList(); ограничения по статусу и дате публикации автоматически не применяются.
$postManager = new PostManager('news');
$count = $postManager->count(['status' => 'save']);
$allLanguagesCount = $postManager->count(['status' => 'save'], allLanguages: true);Если подходящих записей нет, возвращается 0. Для подсчёта только опубликованных записей используйте countPublished().
countPublished(?string $language = null, bool $allLanguages = false, array $where = []): int
Возвращает количество опубликованных записей выбранного типа и языка:
$count = $postManager->countPublished();
$englishCount = $postManager->countPublished('en');Если язык не передан, используется текущий язык CMS, а при его отсутствии — язык сайта по умолчанию.
Параметр allLanguages: true отключает автоматический языковой фильтр. Дополнительные условия передаются через $where и не отменяют правила публикации. Если подходящих записей нет, возвращается 0.
При подсчёте учитываются статус и дата публикации.
countByTypes(array $postTypes, array $where = [], ?string $language = null, bool $allLanguages = false, ?Database $db = null): int
Возвращает общее количество записей нескольких типов без автоматического ограничения по статусу и дате публикации:
$count = PostManager::countByTypes(['news', 'articles'], where: ['author' => 5]);Для всех типов применяются одинаковые условия $where. Правила выбора языка такие же, как у count().
Повторяющиеся имена типов учитываются один раз. Если массив типов пуст или подходящих записей нет, возвращается 0.
countPublishedByTypes(array $postTypes, array $where = [], ?string $language = null, bool $allLanguages = false, ?Database $db = null): int
Возвращает общее количество опубликованных записей нескольких типов:
$count = PostManager::countPublishedByTypes(['news', 'articles'], where: ['author' => 5]);Параметры работают как у countByTypes(), но дополнительно применяются правила публикации. Условия $where не отменяют ограничения по статусу и дате публикации.
Учёт просмотров
recordView(int $id): void
Увеличивает значение views указанной записи на единицу:
$postManager->recordView(15);Метод ничего не возвращает. Если идентификатор меньше 1, выбрасывается InvalidArgumentException.
Правила публикации
Запись считается опубликованной, если:
- поле
statusсодержитpublish publish_dateне задана или не превышает текущее время
Эти правила используются в getPublishedByUrl(), getPublishedList(), getPublishedListByTypes(), getPublishedTranslations(), getPublishedByIds(), countPublished() и countPublishedByTypes().
recordView() только увеличивает счётчик просмотров и не проверяет статус или дату публикации.
Исключения
| Исключение | Когда возникает |
|---|---|
InvalidArgumentException |
Тип записи содержит недопустимые символы. |
InvalidArgumentException |
Идентификатор для getUrl() пустой или содержит /. |
InvalidArgumentException |
Передано неподдерживаемое поле сортировки. |
InvalidArgumentException |
Направление сортировки отличается от ASC и DESC. |
InvalidArgumentException |
Лимит меньше 1. |
InvalidArgumentException |
Смещение отрицательное или передано без лимита. |
InvalidArgumentException |
Массив выбираемых полей пуст. |
InvalidArgumentException |
Поле post_type вручную добавлено в $columns метода getListByTypes() или getPublishedListByTypes(). |
InvalidArgumentException |
Условия $where имеют неподдерживаемый формат, оператор или недопустимые значения числового сравнения. |
InvalidArgumentException |
В recordView() передан идентификатор меньше 1. |
RuntimeException |
Для типа записей не настроен публичный URL или ссылка недоступна для выбранного языка. |
RuntimeException также может возникнуть при получении записей с полем url, поскольку менеджер автоматически формирует для них post_url.
Важные замечания
- один экземпляр работает только с одним типом записей
- методы с
Publishedв названии учитывают только опубликованные записи getByIds()получает записи без фильтрации по статусу, дате публикации и языку- для методов с выбором языка по умолчанию используется текущий язык CMS или язык сайта по умолчанию
- списки индексируются начиная с
0 - каждый результат получает поле
post_type post_urlдобавляется только при наличии корректного поляurlи доступной ссылки для языка записиshort_descriptionдобавляется только при наличии поляcontentrecordView()не проверяет статус публикации записи- произвольные SQL-условия не поддерживаются
- для данных записи текущего запроса используйте
PageData