Общая информация
Класс JResponseJson
появился в CMS версии 3.x. Он предоставляет общий интерфейс для переменных ответа (например, на Ajax запросы). Класс расположен в директории /libraries/cms/response.
В основном он используется в контроллерах компонентов и дает следующие преимущества:
- Используя флаг
success
, JavaScript код (Mootools JRequest.JSON или jQuery.getJSON) может проверить, удачно ли завершилась задача. Если запрос неудачен, может быть использовано событие ошибки JavaScript API. - Данные (если есть) будут доступны в свойстве
data
в виде JSON-объекта - Дополнительно можно установить сообщение ответа через свойство
message
. - Все собранные сообщения очереди
JApplication
будут автоматически направлены в свойствоmessages
.
Еде одним преимуществом является то, что больше нет надобности в закрытии приложения ($app->close()
), если Ajax запрос был сделан с помощью format=json
. За вас это сделает Joomla API.
Как использовать
Наиболее распространённый случай
Рассмотрим пример контроллера:
class MyController extends JControllerLegacy
{
public function someTask()
{
try
{
$anyParam = $this->input->get('anyparam');
$result = $this->getModel('example')->createSomething($anyParam);
echo new JResponseJson($result);
}
catch(Exception $e)
{
echo new JResponseJson($e);
}
}
}
Здесь возвращаемое значение $result
просто передается в новый объект JResponseJson
и выводится с помощью echo
. Это автоматически создает строку в формате JSON:
{"success":true,"message":null,"messages":null,"data":{"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
В data
вы можете передавать массив, объект или значение, при этом флаг success
будет автоматически установлен в true
.
В нашем случае, если случится какое-то исключение в модели, то оно просто передается напрямую в объект JResponseJson
, что приведет к следующим выходным данным:
{"success":false,"message":"Это сообщение исключения","messages":null,"data":null}
Так как это исключение, флаг success
был автоматически установлен в false
, и сообщение исключения стало основным сообщением ответа.
Дополнительные опции
Если первым аргументом конструктора объекта JResponseJson
передается не исключение, то вы можете указать произвольное основное сообщение ответа, передавая его вторым аргументом $message
:
echo new JResponseJson($result, JText::_('COM_COMPONENT_MY_TASK_SUCCESS'));
Это создаст следующее:
{"success":true,"message":"Запрос завершен успешно.","messages":null,"data":{"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
Вы можете вручную установить флаг ошибки в false
с помощью третьего аргумента $error
:
echo new JResponseJson($result, JText::_('COM_COMPONENT_MY_TASK_ERROR'), true);
Вот что мы получим на выходе:
{"success":false,"message":"Произошла ошибка.","messages":null,"data":{"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
Обратите внимание на то, что таким образом вы можете передать назад данные.
Независимо от того, был ли ответ с ошибкой или удачным, класс JResponseJson
отправляет все сообщения обратно клиенту, где они собираются в объекте приложения:
$app = JFactory::getApplication();
//Какой-то код ($result = ...)
$app->enqueueMessage('Эта часть выполнена успешна');
// Еще код
$app->enqueueMessage('А здесь было предупреждение','warning');
echo new JResponseJson($result, 'Главное сообщение ответа');
Вот как будет выглядеть ответ:
{"success":true,"message":"Главное сообщение ответа","messages":"<<все сообщения приложения>>","data":{"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
Преимущество такого подхода вы увидите ниже в разделе JavaScript.
Если же вы не хотите посылать назад сообщения, просто установите четвертый аргумент $ignoreMessages
конструктора в значение true
.
Соответствующий JavaScript код
Ниже приведены примеры JavaScript кода, который может быть использован на клиентской стороне вместе с JResponseJson
на стороне сервера.
Пример на MooTools
var req = new Request.JSON({
method: 'post',
url: 'index.php?option=com_component&task=mycontroller.someTask&format=json',
onSuccess: function(r)
{
if (!r.success && r.message)
{
// Флаг успеха установлен в 'false' и есть основное сообщение ответа.
// Вы можете вывести его в alert или в HTML элемент.
alert(r.message);
}
if (r.messages)
{
// Все сообщения очереди объекта приложения могут быть выведены с помощью
// соответствующей функции Joomla API. Они автоматически отобразятся
// в секции messages шаблона.
Joomla.renderMessages(r.messages);
}
if (r.data)
{
// Получаем доступ к данным вашего ответа
alert(r.data.myfirstcustomparam);
alert(r.data.mysecondcustomparam);
}
}.bind(this),
onFailure: function(xhr)
{
// Ajax запрос был неуспешен. JResponseJson не вызван.
alert('Ошибка Ajax запроса!');
}.bind(this),
onError: function(text, error)
{
// Получен ответ от сервера, но это не валидные JSON данные
// (иногда такое случается при ошибках PHP во время запроса).
alert(error + "\n\n" + text);
}.bind(this)
});
req.post('anyparam=myvalue');
Пример на jQuery
$.getJSON('index.php?option=com_component&task=mycontroller.someTask&format=json', {
data: data
})
.done(function(r) {
if (!r.success && r.message)
{
alert(r.message);
}
if (r.messages)
{
Joomla.renderMessages(r.messages);
}
if (r.data)
{
alert(r.data.myfirstcustomparam);
alert(r.data.mysecondcustomparam);
}
})
.fail(function() {
alert('Ошибка Ajax запроса!');
})
.always(function() {
alert('Ajax запрос завершен');
});
Лучшие практики
Как мы видели выше, код контроллера может быть очень простым, благодаря классу JResponseJson
. Модель обрабатывает данные, которые потом могут быть направлены непосредственно в объект JResponseJson
. Контроллер лучше всего сохранять в файле mycontroller.json.php
и размещать его в папке controllers
. Таким образом, этот контроллер будет вызван автоматически, если URL содержит format=json
.
Также не забывайте, что в случае использования .json
контроллера, нет надобности в закрытии приложения (например, $app->close()
), так как Joomla API сделает это за вас. Также API установит корректные JSON заголовки ответа.
Удачной разработки!