9 votes

Joomla - Tâche de contrôleur qui renvoie des données JSON

J'ai la tâche run dans mon contrôleur. Je veux qu'il renvoie des données JSON. Dans l'état actuel des choses, je reçois mes données JSON enveloppées dans le modèle HTML. Comment puis-je dire à Joomla de ne renvoyer que des données JSON à partir du contrôleur ? Voici la fonction que j'ai :

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 );

}

Et ceci revient :

<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>

J'aimerais obtenir :

{"foo":"bar"}

1voto

Todor Iliev Points 39

Joomla 4

Vous devez ajouter le paramètre &format=json à votre URL. Cela indique au système que vous attendez une réponse json. Le système rendra le document Json et enverra les en-têtes de navigateur corrects en guise de réponse.

index.php?option=com_foo&task=report.run&format=json

class Report extends BaseController {

   public function run() {
       $data = [
         'foo' => 'bar'
       ];

       $response = new ResponseJson($data);

       echo $response;
   }
}

Il n'est pas nécessaire de fermer l'application avec $app->close() ; car l'architecture de Joomla s'en charge pour vous.

Si vous fermez l'application, vous manquerez beaucoup de choses pendant le processus de rendu. De nombreux événements ne seront pas déclenchés. En outre, vous devrez envoyer manuellement les en-têtes pour le type de contenu.

Votre code devrait ressembler à celui-ci. Cette approche est ne pas recommander .

class Report extends BaseController {

   public function run() {

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

       $data = [
         'foo' => 'bar'
       ];

       $response = new ResponseJson($data);

       echo $response;

       $this->app->close();
   }
}

0voto

Je n'aime pas trop JResponseJson et j'aime aussi mettre les messages en file d'attente pour la prochaine requête, j'ai donc créé la méthode suivante sur le contrôleur principal de mon composant :

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();
}

Dans n'importe quelle tâche du contrôleur ou du sous-contrôleur, vous pouvez maintenant faire ce qui suit :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X