PostManager


PostManager получает записи выбранного типа, формирует списки одного или нескольких типов и подготавливает данные для вывода в шаблоне.

Поддерживает

  • получение названий категорий типа записей и выбранных категорий записи
  • получение опубликованной записи по URL и языку
  • получение списка для выбранного языка или всех языков
  • получение общего списка записей нескольких типов
  • получение записей по идентификаторам
  • получение опубликованных переводов записи
  • подсчёт записей по условиям и языку
  • формирование локализованных URL записей
  • учёт просмотров
  • создание краткого описания из содержимого
  • выбор возвращаемых полей
  • фильтрацию по обычным полям и метаполям
  • числовую сортировку
  • безопасную работу без произвольных SQL-фрагментов

Для работы с одним типом создаётся экземпляр менеджера. Общий список нескольких типов можно получить статическим методом.

Быстрый старт

php
$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)

Первым параметром передаётся системное имя типа записей:

php
$postManager = new PostManager('news');

Допустимы латинские буквы, цифры, _ и -.

Если имя имеет недопустимый формат, выбрасывается InvalidArgumentException.

Без второго аргумента используется основная база данных CMS. При необходимости можно передать другой экземпляр Database:

php
$postManager = new PostManager(
    'news',
    $database
);

Названия категорий

getCategoryNames(): array

Возвращает названия категорий, настроенных для типа записей менеджера. Ключи массива соответствуют ключам категорий.

php
$postManager = new PostManager('news');
$names = $postManager->getCategoryNames();

Если у типа записей нет категорий, возвращается пустой массив.

getSelectedCategoryNames(array $categories): array

Возвращает названия только тех категорий, у которых в переданном массиве значение непустое. Ключи категорий сохраняются.

php
$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 и языку:

php
$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 записи:

php
$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

Возвращает записи выбранного типа по условиям, без автоматического ограничения по статусу и дате публикации.

Например, получение черновиков:

php
$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

Возвращает список опубликованных записей:

php
$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, а при его отсутствии — язык сайта по умолчанию:

php
$englishPosts = $postManager->getPublishedList(
    limit: 10,
    language: 'en'
);

Чтобы получить записи всех языков, передайте true в $allLanguages:

php
$posts = $postManager->getPublishedList(
    limit: 10,
    allLanguages: true
);

При $allLanguages = true автоматический языковой фильтр не добавляется, а $language игнорируется. Условия $where продолжают применяться. При явном выборе полей менеджер автоматически добавляет language, если оно ещё не выбрано.

Допустимые поля сортировки:

  • id
  • title
  • date
  • publish_date
  • modified_date
  • views
  • meta.<ключ> — значение метаполя

По умолчанию из базы данных выбираются:

  • id
  • title
  • url
  • img
  • author
  • date
  • publish_date
  • modified_date
  • views

Каждый результат дополнительно получает поле post_type.

Если выбранное поле url содержит корректный идентификатор записи, результат также получает post_url.

Чтобы получить дополнительные поля, передайте их через параметр $columns:

php
$posts = $postManager->getPublishedList(
    limit: 10,
    columns: [
        'id',
        'title',
        'url',
        'content',
        'meta',
    ]
);

При выборе content менеджер добавляет поле short_description.

Если выбраны структурированные поля, они преобразуются в массивы:

  • meta
  • category
  • global_meta
  • global_category
  • comment
  • seo

Фильтрация

Параметр $where позволяет отбирать записи по обычным полям и метаполям. Для метаполя используется имя meta.<ключ>. Условия разных полей внутри одного массива объединяются через И.

В примерах используется тип products с текстовыми метаполями color и price:

php
$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 включительно:

php
$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:

php
$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:

php
$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

Возвращает общий список записей нескольких типов без автоматического ограничения по статусу и дате публикации:

php
$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

Статический метод возвращает общий список опубликованных записей нескольких типов:

php
$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:

php
$translations = $postManager->getPublishedTranslations(
    $post['translation_key']
);

Каждый элемент содержит id, url, language, seo и добавленное поле post_type. Поле seo преобразуется в массив. Если для языка можно сформировать ссылку, также добавляется post_url.

Результат сортируется по id по возрастанию. Если ключ пустой, имеет недопустимый формат или опубликованные варианты не найдены, метод возвращает пустой массив.

Получение записей по ID

getByIds(array $ids, array $columns = ['*']): array

Возвращает записи выбранного типа по идентификаторам:

php
$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

Возвращает опубликованные записи по идентификаторам:

php
$posts = $postManager->getPublishedByIds([
    15,
    27,
    42,
]);

Идентификаторы приводятся к целым числам. Нулевые, отрицательные и повторяющиеся значения исключаются.

Результат сортируется по id по возрастанию.

Если язык не передан, используется текущий язык CMS, а при его отсутствии — язык сайта по умолчанию.

Для получения записей определённого языка передайте его код:

php
$englishPosts = $postManager->getPublishedByIds(
    [15, 27],
    language: 'en'
);

Для выбора дополнительных полей передайте второй параметр:

php
$posts = $postManager->getPublishedByIds(
    [15, 27],
    [
        'id',
        'title',
        'url',
        'content',
        'meta',
    ]
);

Правила добавления post_url, short_description и преобразования структурированных полей совпадают с правилами списка.

Если после проверки не осталось допустимых идентификаторов, метод возвращает пустой массив.

Дополнительные поля

post_type

Добавляется к каждой записи и содержит системное имя типа:

php
$postType = $post['post_type'];

post_url

Добавляется, если в результате присутствует поле url с непустым идентификатором без вложенных сегментов:

php
$url = $post['post_url'];

URL учитывает публичный путь типа записей и язык, выбранный при вызове метода. При выборке всех языков или переводов используется язык каждой отдельной записи.

short_description

Добавляется, если в результате присутствует поле content:

php
$description = $post['short_description'];

При подготовке краткого описания:

  • декодируются HTML-сущности
  • удаляются HTML-теги
  • удаляется содержимое script, style, noscript и template
  • переносы и повторяющиеся пробелы заменяются одним пробелом
  • текст сокращается примерно до 180 символов
  • при сокращении текст по возможности завершается на границе слова
  • к сокращённому тексту добавляется ...

Если текст короче установленного ограничения, многоточие не добавляется.

Подсчёт записей

count(array $where = [], ?string $language = null, bool $allLanguages = false): int

Подсчитывает записи выбранного типа по условиям. Правила выбора языка такие же, как у getList(); ограничения по статусу и дате публикации автоматически не применяются.

php
$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

Возвращает количество опубликованных записей выбранного типа и языка:

php
$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

Возвращает общее количество записей нескольких типов без автоматического ограничения по статусу и дате публикации:

php
$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

Возвращает общее количество опубликованных записей нескольких типов:

php
$count = PostManager::countPublishedByTypes(['news', 'articles'], where: ['author' => 5]);

Параметры работают как у countByTypes(), но дополнительно применяются правила публикации. Условия $where не отменяют ограничения по статусу и дате публикации.

Учёт просмотров

recordView(int $id): void

Увеличивает значение views указанной записи на единицу:

php
$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 добавляется только при наличии поля content
  • recordView() не проверяет статус публикации записи
  • произвольные SQL-условия не поддерживаются
  • для данных записи текущего запроса используйте PageData