web-dev-qa-db-fra.com

Comment recevoir des données JSON dans le contrôleur avec Drupal 8?

J'utilise AngularJS l'une des pages de paramètres de mon module, j'ai donc un objet javascript côté client comme modèle. Quelqu'un pourrait-il m'aider s'il vous plaît, comment capturer ces données dans un contrôleur si je les envoie en JSON avec ajax?

Voici le modèle que j'ai assemblé est angulaire:

var model = {
  title: 'This is a title',
  url: '/random-custom-url',
  description: 'little descrp',
  blocks: [
    {id: 1, name: 'block1', description: 'blockdecrtiption1', terms: [{"tid":"1","name":"term1","vid":"tags"}]},
    {id: null, name: 'block2', description: 'blockdecrtiption2', terms: []},
    {id: 3, name: 'block3', description: 'blockdecrtiption3', terms: []}
  ]
};

Je voudrais "l'attraper" dans la fonction d'un contrôleur (comme un tableau associatif php), donc je peux le traiter et l'enregistrer dans la base de données (j'ai une propre table dans la base de données, créée dans le hook_schema () du module). Quelle est la bonne configuration d'itinéraire pour cela? Dans la fonction du contrôleur, comment puis-je obtenir les données publiées avec ajax et comment les convertir en tableau associatif?

Merci beaucoup!

5
Peter Hurtony

Autrement dit: ne faites pas ça! Ne créez pas votre propre table; ce n'est pas le cas dans Drupal 8. De préférence, ayez votre propre type d'entité. Voir https://drupal.stackexchange.com/a/95208/49 - https://www.drupal.org/developing/api/entityhttps://api.drupal.org/api/drupal/core%21modules%21system%21core.api.php/group/entity_api/8 pour en savoir plus. Le contrôleur de stockage va générer le schéma SQL pour vous et faire tout le travail de stockage. Le module REST gérera ce dont vous avez besoin. Et ainsi de suite .

Edit: Pour un cas générique pour recevoir et répondre avec JSON. Assurez-vous d'abord qu'il n'y a pas Drupal API pour cela. Probablement qu'il y en a. REST vous donne des entités, Views vous donne des listes d'entités (et des listes de plus)) .

Sinon, vous devez écrire un contrôleur personnalisé avec la demande comme argument. (voir Paramètres dans les routes pour plus) en ajoutant simplement Request $request comme argument.

Pour répondre avec JSON, tout objet Response, parmi eux JsonResponse. Vérifiez TimezoneController :: getTimeZone et l'entrée de routage appropriée dans core/modules/system/system.routing.yml .

Donc:

class MyController {
  public function myJson(Request $request) {
    $params = array();
    $content = $request->getContent();
    if (!empty($content)) {
      // 2nd param to get as array
      $params = json_decode($content, TRUE);
    }
    // Process $params...
    return new JsonResponse($params);
  }
}
6
user49

Dans le cas où vous souhaitez le faire plus à la manière D8, voici un aperçu de ce que vous pourriez faire, ce qui vous permet d'être flexible sans avoir à tout faire par vous-même. Une bonne intégration de repos vous oblige à travailler avec tous les différents codes de statut HTTP, champs d'en-tête, etc. Reste s'occupe en partie de cela

Le module de repos fournit une abstraction générique pour REST, pas serré aux entités en premier lieu. Les entités ne sont qu'un exemple.

Vous devez d'abord enregistrer votre plugin de repos, comme tous les autres plugins:

namespace Drupal\pinguin\Plugin\rest\resource;

use Drupal\rest\Plugin\ResourceBase;

/**
 * Provides a resource for database watchdog log entries.
 *
 * @RestResource(
 *   id = "pinguin",
 *   label = @Translation("Example rest plugin for pinguins"),
 *   uri_paths = {
 *     "canonical" = "/pinguin/{id}"
 *   },
 *   serialization_class = "Drupal\pinguin\PingInterface"
 * )
 */
class Pinguin extends ResourceBase {
}

Si vous faites une demande de mise à jour comme Push ou UPDATE, il utilise composant sérialiseur pour convertir vos données en un tableau/objet php. Pour ce faire, il utilise deux étapes. Tout d'abord, les données entrantes sont décodées, par exemple de JSON dans un tableau PHP. L'étape suivante est la dénormalisation. Cette étape convertit les données dénormalisées (tableau PHP) en objet de domaine, par exemple le Ping (un seul pingouin).

La première étape consiste à spécifier la classe résultante dans l'annotation (voir ci-dessus). Pour enregistrer une nouvelle dénormalisation, vous ajoutez l'entrée suivante dans votre .services.yml:

services:
  pinguin.denormalizer.pinguin:
    class: Drupal\pinguin\normalizer\PinguinDenormalizer
    tags:
      - { name: normalizer }

Ce normaliseur spécifie vers quelle interface il peut se convertir:

<?php

namespace Drupal\pinguin\normalizer;

use \Drupal\serialization\Normalizer\NormalizerBase;

class PinguinDenormalizer extends NormalizerBase {

   // IMPORTANT
   /**
    * The interface or class that this Normalizer supports.
    *
    * @var array
    */
    protected $supportedInterfaceOrClass = array('Drupal\pinguin\PingInterface');

    /**
    * {@inheritdoc}
    */
    public function denormalize($data, $class, $format = NULL, array $context  = array()) {     
      // Validate the data.
      if (empty($data['location']) || $data['location'] == 'northpole') {
        throw new \UnexpectedValueException("this can't be real pinguins");
      }

      // create the domain object.
      return new Ping($data['name'], $data['location'], $data['family']);
    }
 }

Une fois cette sérialisation effectuée, elle appelle une méthode nommée d'après la méthode HTTP sur la classe du plugin, donc par exemple "post". Là, vous pouvez faire ce que vous voulez.

<?php
class Pinguin extends ResourceBase {
  public function post(PingInterface $ping) {
    // deal with the data, save it for example.
    $ping_storage->save($ping):
  }
}

Les avantages de ces abstractions sont que vous n'avez pas à gérer le format entrant, mais d'un autre côté, il a besoin d'un tas de code pour commencer.

10
Daniel Wehner

Dans la fonction du contrôleur, comment puis-je obtenir les données publiées avec ajax et comment les convertir en tableau associatif?

use Drupal\Component\Serialization\Json;
//...
class MyController {
  public function myPostAction(Request $request) {
    $params = Json::decode($request->getContent());
    //...
  }
}
4
Trupal

Pourquoi ces exemples suggèrent-ils la méthode $request->getContent()? Cela retournera un corps de requête brut (clé de chaîne de requête: paires de valeurs).

Je pense que $request->request->all() est plus approprié car il vous donnera déjà le tableau. Il vous suffit de vous assurer que votre demande AJAX a un formulaire approprié.

0
bpile