Joomla-задача контроллера, возвращающая данные JSON

у меня задание run в мой контроллер. Я хочу, чтобы он вернул данные JSON. В настоящее время я получаю данные JSON, завернутые в шаблон HTML. Как сказать Joomla просто вернуть данные JSON с контроллера? Это функция, которую я имею:

public function run  ( ) {

    JFactory::getDocument()->setMimeEncoding( 'application/json' );

    JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');

    JRequest::setVar('tmpl','component');

    $data = array(
        'foo' => 'bar'
    );

    echo json_encode( $data );

}

и это возвращает:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" dir="ltr">
...
</head>
<body class="contentpane">

<div id="system-message-container">
</div>
    {"foo":"bar"}
</body>
</html>

Я хотел бы получить:

{"foo":"bar"}

6 ответов


вам не нужно создавать специальный вид JSON (view.json.php; или контроллер progressreports.json.php), чтобы добиться этого. Единственное, что вам нужно сделать, это повторить строку JSON и закрыть приложение.

public function run( )
{
    JFactory::getDocument()->setMimeEncoding( 'application/json' );
    JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');

    $data = array(
        'foo' => 'bar'
    );
    echo json_encode( $data );
    JFactory::getApplication()->close(); // or jexit();
}

вам нужен только отдельный вид (или контроллер), если вы хотите предоставить то же самое функция с выходом HTML и JSON (выбирается вызывающим).


получил ответ.

Мне нужно было сделать новый контроллер. В моем случае был вызван оригинальный контроллер progressreports.php-я сделал новый контроллер под названием progressreports.необработанный.РНР.

затем при вызове url-адреса добавьте format=raw. т. е.

index.php?option=com_foo&task=progressreports.run&format=raw

вам нужно использовать jexit () для возврата данных json без вывода Joomla.

public function run  ( ) {

    $data = array(
        'foo' => 'bar'
    );

    echo json_encode( $data );
    jexit();

}

в зависимости от того, что вы делаете, вы можете сделать документ json, что угодно.формат JSON.php вместо чего угодно.формат html.РНР.


Я проверил принятый ответ, он не работал с joomla 3.4.3. Если у кого-то есть такая же проблема, вот решение для более низких версий Joomla:

$data = array(
    'foo' => 'bar'
);
header('content-type: application/json; charset=utf-8');
echo json_encode($data);
JFactory::getApplication()->close();

заголовок content-disposition необходим, только если вы хотите предложить файл для загрузки.

выкл: Я просто хочу закончить этот проект и выпить что-нибудь, чтобы забыть об этом. Даже начинать с нуля и писать новую CMS было бы менее болезненно. : S


мне не нравится много JResponseJson, а также мне нравится запрашивать сообщения для следующего запроса, поэтому я сделал следующий метод на главном контроллере моего компонента:

public function returnJson($data)
{
    $app = Factory::getApplication();

    // Persist messages if they exist. (Same as CMSApplication->redirect)
    $session = \JFactory::getSession();
    $session->set('application.queue', $app->getMessageQueue());

    // Send json mime type.
    $app->mimeType = 'application/json';
    $app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet);
    $app->sendHeaders();

    echo json_encode($data);

    $app->close();
}

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

public function sampleTask()
{
    $app = Factory::getApplication();
    $app->enqueueMessage("Done (for the next user's request)", 'success');
    $this->returnJson("json data");
}