Web Services in Joomla 4

// HTTP request headers
$headers = [
‘Accept: application/vnd.api+json’,
‘Content-Type: application/json’,
‘Content-Length: ‘ . mb_strlen($dataString),
sprintf(‘X-Joomla-Token: %s’, trim($token)),
]; // Timeout in seconds $timeout = 30; // Set the endpoint for working with materials. // This is part of $uri. $uri->setPath(‘content/articles’); // This will be PSR-7 compliant Response $response = $http->request(‘POST’, $uri, $dataString, $headers, $timeout); // As a result of the request, we have a stream, so we simply do: echo $response->body;

A small digression about the Uri class in Joomla (from the translator)

For a better understanding of what is happening in the code and further more convenient work with the Joomla API, let me introduce a brief reference about the Uri classes in Joomla:

  • Joomla Official Documentation on Joomla\Uri\Uri class

  • Docks for Joomla 3, but the Uri class in Joomla 4 has remained largely the same.

  • The documentation at the link specifies the class Joomla\CMS\Uri\Uriwhich extends the class Joomla\Uri\Uriwhich in turn extends the class Joomla\Uri\AbstractUri. The methods of the parent class are available in the child class.

  • Class Joomla\Uri\Uri designed to work with url and allows you to work with it as an object: $url->setPath, $url->setScheme, $url->setScheme , $url->setScheme and other methods (see the list in the class file: libraries/vendor/joomla/uri/src/Uri.php). Appropriate getters are defined in the class Joomla\Uri\AbstractUri

  • Class Joomla\CMS\Uri\Uri adds a few methods that are needed for more internal work of Joomla: determining whether the url is external or internal, the current url without GET parameters, etc.

GET – Get a list of all Joomla content from the “Uncategorized” category

<?php
use Joomla\Http\HttpFactory;
use Joomla\Uri\Uri;

$http = (new HttpFactory())->getAvailableDriver();
$url="https://example.org/api/index.php/v1";
$uri  = new Uri($url);

$token = '';

$categoryId = 2; // Категория "Без категории" Joomla по умолчанию

// Не будем отправлять payload на сервер
$dataString = null;

// HTTP заголовки запроса
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
sprintf('X-Joomla-Token: %s', trim($token)),
];

// Таймаут в секундах
$timeout = 30;

// Установите endpoint для работы с материалами.
// Это часть $uri.
$uri->setPath('content/articles');

// Это будет PSR-7 совместимый Response
$response = $http->request('GET', $uri, $dataString, $headers, $timeout);

// В результате запроса мы имеем stream, поэтому делаем просто:
echo $response->body;

GET – Getting Joomla content by id (REST API)

<?php
use Joomla\Http\HttpFactory;
use Joomla\Uri\Uri;

$http = (new HttpFactory())->getAvailableDriver();
$url="https://example.org/api/index.php/v1";
$uri  = new Uri($url);

$token = '';

$articleId = 1; // ID нужной статьи в Joomla

// Не будем отправлять payload на сервер
$dataString = null;

// HTTP заголовки запроса
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
sprintf('X-Joomla-Token: %s', trim($token)),
];

// Таймаут в секундах
$timeout = 30;

// Устанавливаем path-часть Url для получения конкретного материала.
$uri->setPath(sprintf('content/articles/%d', $articleId));

// Это будет PSR-7 совместимый Response
$response = $http->request('GET', $uri, $dataString, $headers, $timeout);

// В результате запроса мы имеем stream, поэтому делаем просто:
echo $response->body;

PATCH – Change Joomla content by id (REST API)

<?php
use Joomla\Http\HttpFactory;
use Joomla\Uri\Uri;

$http = (new HttpFactory())->getAvailableDriver();
$url="https://example.org/api/index.php/v1";
$uri  = new Uri($url);

$token = '';
$articleId = 1; // ID нужной статьи в Joomla

$data = [
'id'          => $articleId,
'title'       => 'Как добавить материал Joomla с помощью REST API?',
'introtext' => 'При использовании PATCH текст статьи должен быть разделен на две части или использовать, по крайней мере, только introtext, чтобы сохранить данные должным образом',
'fulltext' => 'Больше контента богу контента!',
];

$dataString = json_encode($data);

// HTTP заголовки запроса
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
'Content-Length: ' . mb_strlen($dataString),
sprintf('X-Joomla-Token: %s', trim($token)),
];

// Таймаут в секундах
$timeout = 30;

// Устанавливаем path-часть Url для изменения конкретного материала.
$uri->setPath(sprintf('content/articles/%d', $articleId));

// Это будет PSR-7 совместимый Response
$response = $http->request('PATCH', $uri, $dataString, $headers, $timeout);

// Здесь получим status code запроса
echo $response->code;

Translator’s Note on Joomla Material Entity Structure

Translator’s note for developers not familiar with the structure of the content component (com_content) of Joomla. Each article has an introductory text and an introductory text. The introductory text is displayed in the list of materials in the form of a blog (with a picture of the introductory text, a couple of paragraphs and a “more” button). The full text of the material is displayed, respectively, when the user wants to read the article in full and opens it.

In the database in the table for Joomla materials, 2 cells are implemented: introtext And full text type MEDIUM TEXT respectively.

If the content manager, by inserting the “more” line in the admin panel, indicated to Joomla that the text should be divided into an introductory and full part, then the text will be cut into 2 parts and each part will be stored in its own cell. If the “more” line is not inserted, then all the text is stored in the cell introtext.

Thus, when working with the REST API, you need to understand HOW the text is processed at all stages: creation, editing, display to the editor, display to the user of the site. If Joomla is used as a backend, and the front is a mobile application or the front is made on a js-framework, then the display no longer depends on Joomla, but on the implementation of the application, and then all the text of the material can be stored in introtext. If the REST API is used for editing, and Joomla’s HTML output is used for visitors, then following the rules of the CMS game will be important, as this will affect the display for users of the site.

DELETE – Deleting Joomla content by id (REST API)

<?php
use Joomla\Http\HttpFactory;
use Joomla\Uri\Uri;

$http = (new HttpFactory())->getAvailableDriver();
$url="https://example.org/api/index.php/v1";
$uri  = new Uri($url);

$token = '';
$articleId = 1; // ID нужной статьи в Joomla

// Не будем отправлять payload на сервер
$dataString = null;

// HTTP заголовки запроса
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
sprintf('X-Joomla-Token: %s', trim($token)),
];

// Таймаут в секундах
$timeout = 30;

// Устанавливаем path-часть Url для удаления конкретного материала.
$uri->setPath(sprintf('content/articles/%d', $articleId));

// Это будет PSR-7 совместимый Response
$response = $http->request('DELETE', $uri, $dataString, $headers, $timeout);

// Здесь получим status code запроса
echo $response->code;

Requests to Joomla REST API using pure PHP cURL

Before using this code, make sure cURL is installed on your hosting, check with phpinfo(). [Данный раздел документации может пригодится для non-Joomla сайтов, которые будут взаимодействовать с Joomla 4+ сайтами – Т.С.]

Let’s define variables

First, we’ll define some variables that we’ll use in all of our cURL requests:

  • URL of our site on Joomla 4.x

  • Joomla API token of the superuser account or an account that has at least permission core.login.api And core.login.siteto be able to see the token change of the currently logged in user.

<?php
// Before passing the HTTP METHOD to CURL
$curl  = curl_init();

$url="https://example.org/api/index.php/v1";

// Поместите Ваш токен Joomla! Api token в безопасное место,
// например, в менеджер паролей или хранилище.
// Мы не рекомендуем использовать переменные окружения
// для хранения паролей.
// Здесь описано почему: https://www.trendmicro.com/en_us/research/22/h/analyzing-hidden-danger-of-environment-variables-for-keeping-secrets.html
$token = '';

POST – Create a Joomla content in the category “Uncategorized” by REST API using cURL

<?php
// Before passing the HTTP METHOD to CURL
$curl  = curl_init();

$url="https://example.org/api/index.php/v1";

$token = '';

$categoryId = 2; // Joomla's default "Uncategorized" Category


$data = [
'title'       => 'How to add an article to Joomla via the API?',
'alias'       => 'how-to-add-article-via-joomla-api',
'articletext' => 'I have no idea...',
'catid'       => $categoryId,
'language'    => '*',
'metadesc'    => '',
'metakey'     => '',
];

$dataString = json_encode($data);

// HTTP request headers
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
'Content-Length: ' . mb_strlen($dataString),
sprintf('X-Joomla-Token: %s', trim($token)),
];

curl_setopt_array($curl, [
        CURLOPT_URL            => sprintf('%s/%s',$url,'content/articles'),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => 'utf-8',
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
        CURLOPT_CUSTOMREQUEST  => 'POST',
        CURLOPT_POSTFIELDS     => $dataString,
        CURLOPT_HTTPHEADER     => $headers,
    ]
);

$response = curl_exec($curl);
curl_close($curl);
echo $response;

GET – Retrieve a list of all Joomla content from the “Uncategorized” category using cURL via REST API

<?php
// Before passing the HTTP METHOD to CURL
$curl  = curl_init();

$url="https://example.org/api/index.php/v1";

$token = '';

$categoryId = 2; // Joomla's default "Uncategorized" Category


// HTTP request headers
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
sprintf('X-Joomla-Token: %s', trim($token)),
];

curl_setopt_array($curl, [
        CURLOPT_URL            => sprintf('%s/content/articles?filter[category]=%d',$url,$categoryId),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => 'utf-8',
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
        CURLOPT_CUSTOMREQUEST  => 'GET',
        CURLOPT_HTTPHEADER     => $headers,
    ]
);

$response = curl_exec($curl);
curl_close($curl);
echo $response;

GET – Get specific Joomla content by id using cURL (REST API)

<?php
// Before passing the HTTP METHOD to CURL
$curl  = curl_init();

$url="https://example.org/api/index.php/v1";

$token = '';

$articleId = 1; // The Article ID of a specific Article


// HTTP request headers
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
sprintf('X-Joomla-Token: %s', trim($token)),
];
curl_setopt_array($curl, [
        CURLOPT_URL            => sprintf('%s/content/articles/%d',$url,$articleId),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => 'utf-8',
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
        CURLOPT_CUSTOMREQUEST  => 'GET',
        CURLOPT_HTTPHEADER     => $headers,
    ]
);

$response = curl_exec($curl);
curl_close($curl);
echo $response;

PATCH – Change Joomla content by id using cURL (REST API)

<?php
// Before passing the HTTP METHOD to CURL
$curl  = curl_init();

$url="https://example.org/api/index.php/v1";

$token = '';

$articleId = 1; // The Article ID of a specific Article


$data = [
'id'          => $articleId,
'title'       => 'How to add an article via the Joomla 4 API?',
'introtext' => 'When using PATCH, articletext MUST be splitted in two parts or use at least just introtext in order to work properly',
'fulltext' => 'MORE CONTENT if you wish',
];

$dataString = json_encode($data);

// HTTP request headers
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
'Content-Length: ' . mb_strlen($dataString),
sprintf('X-Joomla-Token: %s', trim($token)),
];

curl_setopt_array($curl, [
        CURLOPT_URL            => sprintf('%s/content/articles/%d',$url,$articleId),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => 'utf-8',
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
        CURLOPT_CUSTOMREQUEST  => 'PATCH',
        CURLOPT_POSTFIELDS     => $dataString,
        CURLOPT_HTTPHEADER     => $headers,
    ]
);

$response = curl_exec($curl);
curl_close($curl);
echo $response;

DELETE – Deleting Joomla content by id using cURL (REST API)

<?php
// Before passing the HTTP METHOD to CURL
$curl  = curl_init();

$url="https://example.org/api/index.php/v1";

$token = '';

$articleId = 1; // The Article ID of a specific Article


// HTTP request headers
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
sprintf('X-Joomla-Token: %s', trim($token)),
];

curl_setopt_array($curl, [
        CURLOPT_URL            => sprintf('%s/content/articles/%d',$url,$articleId),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => 'utf-8',
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
        CURLOPT_CUSTOMREQUEST  => 'DELETE',
        CURLOPT_HTTPHEADER     => $headers,
    ]
);

$response = curl_exec($curl);
curl_close($curl);
echo $response;

Useful Resources

Joomla Community Resources:

Joomla on Telegram:

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *