Функции-хелперы
Для более удобной работы с API предусмотрены вспомогательные PHP функции.
abortx()
Выбрасывает соответствующее исключение HttpException
для указанного кода.
Аргументы:
(int)
code - HTTP код.(string)
message - сообщение об ошибке.(string)
title - заголовок для страницы, выводящей ошибку.(array)
headers - массив HTTP заголовков.
$router->get('items/{$id}', function($id) use($modx) { $item = $modx->getObject('itemClass', ['id' => (int)$id]); if ($item === null) { abortx(404, 'Item not found!'); } return jsonx($item->toArray(), ['X-Some-Header' => 'Some value']); });
Из коробки доступны исключения для следующих кодов -
- 400 - Bad request.
- 401 - Unauthorized.
- 403 - Forbidden.
- 404 - Not found.
- 406 - Not Acceptable.
- 415 - Unsupported media type.
- 500 - Internal Server Error.
- 503 - Service Unavailable.
Исключения можно расширять для адаптации к задаче и добавлять свои собственные. Для этого нужно в файле core/config/exceptions.php
для нужного кода указать соответствующий класс исключения.
return [ 401 => Zoomx\Exceptions\myUnauthorizedHttpException::class, ];
Для кодов для всех исключений кроме 400, 401 и 403 срабатывает событие OnRequestError
. В плагине доступны следующие переменные -
$error_type
- класс исключения.$error_code
- код ошибки.$error_pagetitle
- заголовок для страницы.$error_message
- сообщение.$e
- объект исключения.
filex()
Используется для управления скачиванием файлов. Может вернуть как содержимое файла, так и вывести диалог для сохранения. Удобно использовать для проксирования запросов, когда нужно исключить прямой доступ к статическому файлу.
Аргументы:
(string)
path - абсолютный путь к файлу.(bool)
isAttachment - скачать файл.(bool)
deleteFileAfterSend - удалить файл после скачивания.
$router->get('files/{file}', function ($file) { // Проверить права if (!$modx->user->isMember('Subscribers')) { abortx(403, 'Только члены группы "Subscribers" могут скачивать файлы.'); } // Не искать ресурс с указанным URI. zoomx()->autoloadResource(false); // Фильтрация имени файла $file = basename($file); // Скачать файл return filex(MODX_CORE_PATH . "path/to/subscribers/files/$file", true); });
Можно изменить имя скачиваемого файла
$router->get('files/{file}', function ($file) use ($modx) { ... return filex(MODX_CORE_PATH . "path/to/files/$file", true)->downloadAs('newFileName'); });
В случае, когда нужно отобразить содержимое файла в браузере, в ответе необходимо указать правильный тип контента. Иначе браузер не сможет отобразить его корректно.
$router->get('files/modx.pdf', function () { zoomx()->autoloadResource(false); return filex(MODX_CORE_PATH . "path/to/files/modx.pdf")->withHeaders(['Content-Type' => 'application/pdf']); });
Чтобы немного упростить задачу с типом контента в системе предусмотрен автоматический детектор. Для управления им предназначена системная настройка zoomx_autodetect_content_type
. Изначально он включен и срабатывает, если не указан заголовок Content-Type
. Принцип работы у него следующий -
- Первым делом он проверяет URI на наличие расширения файла. По нему определяется mime тип запрашиваемого файла.
- Если расширение не найдено, он проверяет mime тип указанного файла.
- Если тип не удалось определить, то указывается дефолтное значение
'text/html'
.
Таким образом, предыдущий пример можно переписать без указания заголовка.
$router->get('files/modx.pdf', function () { zoomx()->autoloadResource(false); return filex(MODX_CORE_PATH . "path/to/files/modx.pdf"); });
Ещё одна из возможностей - парсить запрашиваемый файл. Что это даёт? В файлах скриптов и стилей можно указывать теги шаблонизатора. Это добавляет альтернативу подходу, когда основной функционал размещают в файле скриптов, а инициализацию делают отдельно в секции <head>
.
Чтобы распарсить файл, нужно вызывать метод parse
и передать в него массив параметров.
# HTML <body> ... <script src="js/scripts.js"></script> </body> </html> # router.php $router->get('js/scripts.js', function () { zoomx()->autoloadResource(false); return filex(MODX_ASSETS_PATH . "js/scripts.js")->parse(['foo' => 'bar']); });
jsonx()
Возвращает объект класса Json\Response
. Его задача подготовить данные, перевести в JSON формат и отправить пользователю с правильным заголовком.
Аргументы:
(array)
data - данные.(array)
headers - масссив HTTP заголовков.(int)
code - HTTP код статуса для ответа. По-умолчанию 200.
$router->get('api/foo', function() { return jsonx(['foo' => 'bar'], ['X-Some-Header' => 'Some value']); }); // Ответ { success: true, data: { foo: "bar" }, meta: { total_time: "0.0230 s", query_time: "0.0000 s", php_time: "0.0230 s", queries: 1, memory: "2 048 kb" } }
Если указать код 400 и выше, то свойство success
в массиве ответа будет иметь значение false. А данные будут помещены в свойство errors
.
{ success: false, data: {}, errors: { foo: "bar" // данные из функции jsonx }, meta: { ... } }
В случае, если в коде сработает исключение или PHP ошибка, то в errors будут их данные
... errors: { "code": 500, "title": "Error 500: Internal Server Error", "message": "Сообщение об ошибке" }, ...
В запрос добавляются информационные данные. Отключить их можно с помощью системной настройки zoomx_include_request_info
.
Важно!
Указанный выше пример сработает без ошибки 404 в двух случаях - если в запросе есть заголовок Content-Type
со значением application/json
или отключена автоматическая загрузка ресурса в системных настройках. В противном случае нужно отключить загрузку ресурса в самом роуте с помощью zoomx()->autoloadResource(false);
или define('ZOOMX_API_MODE', true);
. Вариант с заголовком оптимальнее.
$router->get('api/foo', function() { zoomx()->autoloadResource(false); // или define('ZOOMX_API_MODE', true); return jsonx(['foo' => 'bar'], ['X-Some-Header' => 'Some value']); });
parserx()
Возвращает объект текущего шаблонизатора.
echo parserx()->parse($string, $placeholders); // === zoomx('parser') === zoomx()->getParser();
redirectx()
Используется для более удобной переадресации.
Аргументы:
(string)
url — новый URL для переадресации.(int)
code — код переадресации. По-умолчанию, 302.(array)
headers — массив HTTP заголовков.
$router->get('first.html', function () use ($modx) { // Вместо // $modx->sendRedirect('second.html', ['responseCode' => $_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently']); return redirectx('second.html', 301); });
viewx()
Возвращает объект класса ZoomView
.
Аргументы:
(string)
tpl - имя файла шаблона.(array)
data - переменные шаблона.
$router->get('articles/{alias}', function($alias) { return viewx('article.tpl', ['foo' => 'bar']); });
Шаблон должен располагаться в папке, в которой храняться шаблоны Smarty.
zoomx()
Возвращает инстанс главного сервис-класса компонента.
Аргумент:
(string)
property - название свойства, в котором хранится соответствующий объект. Из коробки доступны "modx", "parser", "request", "response", "elementService", "router". Это системные объекты. Также можно получить кастомные объекты, зарегистрированные пользователем, используя функционал контейнера зависимостей.
# Получить обычный чанк MODX. $content = zoomx()->getChunk('modx.chunk', $params); # Запустить сниппет MODX. zoomx()->runSnippet('modx.snippet', $params); # Запустить файловый сниппет. zoomx()->runSnippet('file_snippet.php', $params); # Получить ресурс из кэша. Если кэша нет, то из БД. $resource = zoomx()->getResource('post1'); // В параметре можно передать как URI так и id ресурса. # Замена $modx->getOption('setting', null, 'default') zoomx()->config('setting', 'default');