Добавление API к компонентам Joomla 4

  1. Как интегрировать слой Web Services, представленный в Joomla 4.0, в существующий компонент Joomla
    1. Примеры интеграции веб-служб для добавления веб-ссылок в Joomla 4
  2. Код плагина для Joomla 4
  3. Код API Joomla 4
  4. Создание пакетов для Joomla 4
    1. Пакет для компонентов
    2. Пакет для плагина
  5. Категории
  6. Поля и группы
  7. Данные
  8. Пример работы по интеграции в Joomla 4
    1. Веб-ссылки
      1. Получение списка веб-ссылок
      2. Получить отдельную веб-ссылку
      3. Удалить веб-ссылку
      4. Создать веб-ссылку
      5. Обновить веб-ссылку
    2. Категории
    3. Поля
    4. Группы полей


Как интегрировать слой Web Services, представленный в Joomla 4.0, в существующий компонент Joomla.

Эта статья предназначена для документирования того, как интегрировать слой Web Services, представленный в Joomla 4.0, в существующий компонент Joomla. Предполагается, что используется стандартный слой Joomla MVC.

Примеры интеграции веб-служб для добавления веб-ссылок в Joomla 4.

Код плагина для Joomla 4.

Точкой входа в ваш компонент из вызова API является плагин.

Плагин перенаправляет вызов API в код API, который обслуживает запрос.

В данном примере вызов API для компонента weblinks может выглядеть следующим образом

(ваш_сайт)/api/index.php/v1/weblinks

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

1. Создайте папку плагина plugins/webservices/weblinks.

Код вашего плагина помещается в подкаталог каталога webservices в каталоге plugins, в данном примере plugins/webservices/weblinks.

Структура файловой системы плагина API Joomla 4

2. В файле weblinks.php создайте класс PlgWebservicesWeblinks.

В методе onBeforeApiRoute зарегистрируйте все маршруты, необходимые для веб-сервиса.

use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Router\ApiRouter;

class PlgWebservicesWeblinks extends CMSPlugin
{
    public function onBeforeApiRoute(&$router)
    {
        $router->createCRUDRoutes('v1/weblinks', 'weblinks', ['component' => 'com_weblinks']);
    }
}

Когда Joomla 4 получает вызов API, она загружает маршрутизатор API, который затем собирает список конечных точек, о которых он должен знать, выполняя метод "onBeforeApiRoute" во всех включенных классах плагинов, которые его содержат. Затем он может найти компонент API, соответствующий конечной точке API, которая была вызвана.

Метод createCRUDRoutes создает пять маршрутов; два маршрута GET для данных списка и элемента, а также один маршрут POST, один PATCH и один DELETE. Если вам это не требуется, просто создайте маршруты непосредственно в данном методе.

Код API Joomla 4.

Маршрутизатор указывает путь к соответствующему коду API.

Этот код API находится в папке с именем "api" в корне сайта. Она является аналогом разделов "admin" и "site".

Этот код должен быть включен в ваш установочный пакет компонента, потому что процесс установки Joomla 4 автоматически создает там раздел для каждого установленного компонента, независимо от того, есть ли в нем код API или нет.

Структура этого раздела имеет ту же схему каталогов, что и другие разделы расширений (т.е. компоненты, модули, плагины).

1. Создайте папку с кодом API /api.

Структура файловой системы Joomla 4 c кодом API

2. Создайте класс контроллера WeblinksController.

Контроллер указывается во втором параметре метода "createCRUDRoutes" в плагине.

Можно открыть более одной структуры вывода, зарегистрировав более одного маршрута, указав для каждой структуры свой контроллер.

 

use Joomla\CMS\MVC\Controller\ApiController;

class WeblinksController extends ApiController
{
    protected $contentType = 'weblinks';

    protected $default_view = 'weblinks';
}

Переопределите следующие поля:

$contentType - будет использоваться по умолчанию для $modelName, а также при выводе ответа в виде объекта типа
$default_view - будет использоваться по умолчанию для $viewName

3. Класс отображения JsonapiView.php.

Расширение JsonApiView дает вам те же возможности, что и HtmlView в обычном компонентном представлении, слегка измененные для вывода Json.

Обратите внимание, что хотя основной класс - JsonApiView ( заглавное A для Api), ваше переопределение должно иметь строчную букву a.

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

use Joomla\CMS\MVC\View\JsonApiView as BaseApiView;

class JsonapiView extends BaseApiView
{
    protected $fieldsToRenderItem = [
        'id',
        'catid',
        'title',
        'alias',
        'url',
        'xreference',
        'tags',
    ];

    protected $fieldsToRenderList = [
        'id',
        'title',
        'alias',
    ];
}

Переопределите следующие поля:

$fieldsToRenderItem - массив полей для отображения одного объекта
$fieldsToRenderList - массив полей для отображения списка объектов

Обратите внимание, что здесь содержится существенная разница между представлениями JSON API и представлениями HTML. В представлениях HTML принято иметь отдельные файлы и каталоги для отображения списка элементов и отдельных элементов. Для JSON такой разницы в "отображении" нет, поэтому один JsonapiView работает с обоими типами. Вот почему оба списка полей отображаются в одном файле представления.

3. Создайте файл манифеста, weblinks.xml.

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="webservices" method="upgrade">
    <name>PLG_WEBSERVICES_WEBLINKS</name>
    <author>Joomla! Project</author>
    <creationDate>August 2017</creationDate>
    <copyright>(C) 2005 - 2019 Open Source Matters. All rights reserved.</copyright>
    <license>GNU General Public License version 2 or later; see LICENSE.txt</license>
    <authorEmail>admin@joomla.org</authorEmail>
    <authorUrl>www.joomla.org</authorUrl>
    <version>4.0.0</version>
    <description>PLG_WEBSERVICES_WEBLINKS_XML_DESCRIPTION</description>
    <files>
         ##FILES##
    </files>
    <languages folder="administrator/language">
         ##LANGUAGE_FILES##
    </languages>
</extension>

4. Создайте языковые файлы с нужным содержимым

Как обычно, языковые файлы должны быть предоставлены в комплекте: en-GB/plg_webservices_weblinks.ini, en-GB/plg_webservices_weblinks.sys.ini. Возможно, нет необходимости предоставлять пользовательский языковой файл (".ini"), но содержимое системного файла (".sys.ini") необходимо, хотя бы для администратора в списке плагинов.

; Joomla! Project
; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_WEBSERVICES_WEBLINKS="Web Services - Weblinks"
PLG_WEBSERVICES_WEBLINKS_XML_DESCRIPTION="Used to add weblinks routes to the Web Services API for your website."

Создание пакетов для Joomla 4.

Для создания пакета есть два аспекта: код в секциях api и plugin.

Пакет для компонентов.

Как уже упоминалось, код api упаковывается вместе с кодом компонента. Чтобы включить код в пакет, добавьте следующий раздел в манифест компонента

<api>
    <files folder="api">
        <folder>src</folder>
    </files>
</api>

Это создаст раздел для вашего api кода в правильно названной (для вашего компонента) папке, в папке "api".

Пакет для плагина.

Файл манифеста для самого плагина показан выше. Поскольку плагин теперь является неотъемлемой частью компонента, лучше всего упаковать их вместе. Как и файл установки отдельного расширения, файл установки пакета содержит каждое расширение в пакете, и файл манифеста пакета. В данном примере файл манифеста будет выглядеть следующим образом (некоторые поля опущены):

<?xml version="1.0" encoding="utf-8"?>
<!--~
  ~ @package   Weblinks
    ....
  -->

<extension version="4.0.0" type="package" method="upgrade">
    <name>Weblinks</name>
    <packagename>weblinks</packagename>
    <version>x.y.z</version>
    <!-- etc etc -->

    <!-- List of extensions to install -->
    <files>
        <!-- Component -->
        <file type="component" id="com_weblinks">com_weblinks.zip</file>

        <!-- Plugins: web services -->
        <file type="plugin" id="weblinks" group="webservices">plg_webservices_weblinks.zip</file>
    </files>
</extension>

Категории.

1. Добавьте поддержку категорий для веб-сервиса weblinks. Отредактируйте файл src/plugins/webservices/weblinks/weblinks.php.

class PlgWebservicesWeblinks extends CMSPlugin
{
    public function onBeforeApiRoute(&$router)
    {
        ...
        $router->createCRUDRoutes(
            'v1/weblinks/categories',
            'categories',
            ['component' => 'com_categories', 'extension' => 'com_weblinks']
        );
    }
}

Для этого используется готовый компонент com_categories, и нам просто нужно передать параметр 'extension' => 'com_weblinks'.

Поля и группы.

1. Добавьте поддержку полей и групп полей для веб-сервиса weblinks. Отредактируйте файл src/plugins/webservices/weblinks/weblinks.php.

class PlgWebservicesWeblinks extends CMSPlugin
{
    public function onBeforeApiRoute(&$router)
    {
        ...
        $router->createCRUDRoutes(
            'v1/fields/weblinks',
            'fields',
            ['component' => 'com_fields', 'context' => 'com_weblinks.weblink']
        );

        $router->createCRUDRoutes(
            'v1/fields/groups/weblinks',
            'groups',
            ['component' => 'com_fields', 'context' => 'com_weblinks.weblink']
        );
    }
}

2. Переопределите функцию save в WeblinksController.

class WeblinksController extends ApiController
{
    ...

    protected function save($recordKey = null)
    {
        $data = (array) json_decode($this->input->json->getRaw(), true);

        foreach (FieldsHelper::getFields('com_weblinks.weblink') as $field)
        {
            if (isset($data[$field->name]))
            {
                !isset($data['com_fields']) && $data['com_fields'] = [];

                $data['com_fields'][$field->name] = $data[$field->name];
                unset($data[$field->name]);
            }
        }

        $this->input->set('data', $data);

        return parent::save($recordKey);
    }

    ...
}

3. Переопределите функции displayList, displayItem, prepareItem в Weblinks\JsonApiView.

class JsonApiView extends BaseApiView
{
    ...

    public function displayList(array $items = null)
    {
        foreach (FieldsHelper::getFields('com_weblinks.weblink') as $field)
        {
            $this->fieldsToRenderList[] = $field->name;
        }

        return parent::displayList();
    }

    public function displayItem($item = null)
    {
        foreach (FieldsHelper::getFields('com_weblinks.weblink') as $field)
        {
            $this->fieldsToRenderItem[] = $field->name;
        }

        return parent::displayItem();
    }

    protected function prepareItem($item)
    {
        foreach (FieldsHelper::getFields('com_weblinks.weblink', $item, true) as $field)
        {
            $item->{$field->name} = isset($field->apivalue) ? $field->apivalue : $field->rawvalue;
        }

        return parent::prepareItem($item);
    }

    ...
}

Обратите внимание в функции prepareItem на

$field->apivalue

Если тип поля complex, мы надеемся, что оно вернет значение для вывода в компонент Web Services API, иначе мы возьмем

$field->rawvalue

Данные.

Основной функционал отображает данные, которые вы ожидаете от простого компонента в обычном веб-интерфейсе. Для этого API по умолчанию использует административные модели данных. Однако предоставление раздела "Model" в коде вашего API дает вам возможность создать любую форму данных, которая вам нужна, только для вывода API. Создайте модель для каждого представления с обычными соглашениями об именовании.

Системный класс JsonApiView форматирует вывод Json как три набора данных: ссылки, элементы и метаданные. Чтобы изменить это, переопределите класс display в своем собственном JsonapiView и не вызывайте родительский класс.

Пример работы по интеграции в Joomla 4.

ПРИМЕЧАНИЕ: Не забудьте включить плагин веб-сервиса weblinks!

Веб-ссылки.

Получение списка веб-ссылок.

curl -X GET /api/index.php/v1/weblinks

Получить отдельную веб-ссылку.

curl -X GET /api/index.php/v1/weblinks/{weblink_id}

Удалить веб-ссылку.

curl -X DELETE /api/index.php/v1/weblinks/{weblink_id}

Создать веб-ссылку.

curl -X POST -H "Content-Type: application/json" /api/index.php/v1/weblinks -d
'{
    "access": "1",
    "alias": "",
    "catid": "8",
    "description": "<p>text</p>",
    "images": {
        "float_first": "",
        "float_second": "",
        "image_first": "",
        "image_first_alt": "",
        "image_first_caption": "",
        "image_second": "",
        "image_second_alt": "",
        "image_second_caption": ""
    },
    "language": "*",
    "metadata": {
        "rights": "",
        "robots": ""
    },
    "metadesc": "",
    "metakey": "",
    "modified": "",
    "params": {
        "count_clicks": "",
        "height": "",
        "target": "",
        "width": ""
    },
    "title": "weblink title",
    "url": "http://somelink.com/",
    "xreference": "xreference"
}'

Обновить веб-ссылку.

curl -X PUT -H "Content-Type: application/json" /api/index.php/v1/weblinks/{weblink_id} -d
'{
    "catid": "8",
    "description": "<p>some new text</p>",
    "language": "*",
    "title": "new title",
    "url": "http://newsomelink.com/"
}'

Категории.

Маршрутизация Weblinks Categories: "v1/weblinks/categories".

Работа с ним аналогична работе с Banners Categories.

Поля.

Маршрутизация Fields Weblinks: "v1/fields/weblinks".

Работа с ним аналогична работе с Fields Contact.

Группы полей.

Маршрутизация Groups Fields Weblinks: "v1/fields/groups/weblinks".

Работа с ним аналогична работе с Groups Fields Contact.

Перевод с английского официальной документации Joomla 4:
https://docs.joomla.org/J4.x:Adding_an_API_to_a_Joomla_Component

Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню