web-dev-qa-db-fra.com

Un moyen sûr et élégant d'accéder aux entités imbriquées via les champs

J'ai vu une variété d'approches pour accéder aux valeurs d'entité dans la couche thématique. Le code ci-dessous n'est qu'un exemple simple utilisant des méthodes magiques. Il suppose que toutes les valeurs sont définies - si une partie de celle-ci renvoie un NULL, alors, selon mon expérience, des erreurs s'ensuivent.

$value = $node->field_paragraph
    ->entity->field_media
    ->entity->field_file
    ->entity->field_text->value;

Il existe des méthodes comme ->hasField Et ->count() pour vérifier les choses, et j'ai une variété dans mes thèmes. Je peux faire le travail, mais parfois ça me semble laid. Je suis intéressé par les modèles de codage que les développeurs utilisent pour explorer en toute sécurité et élégance les références d'entité.

7
simesy

Suggestion, créez un objet de domaine qui a la logique.

Normalement, ces entités représentent quelque chose qui correspond à votre domaine d'activité.

Par exemple, dans votre instance, le nœud peut être un événement.

Vous pouvez donc modéliser un objet de domaine appelé EventWrapper.

<?php

namespace Drupal\my_domain;
use Drupal\node\NodeInterface;
use Drupal\media\MediaInterface;
use Drupal\file\FileInterface;

class EventWrapper {
  protected $node;
  public static function fromNode(NodeInterface $node): EventWrapper {
    $instance = new static();
    $instance->node = $node;
    return $instance;
  }
  public function getMedia() : ?MediaInterface {
    if ($this->node->hasField('field_media') && !$this->node->get('field_media')->isEmpty()) {
      return $this->node->field_media->entity;
    }
    return NULL;
  }
  public function getMediaImage() : ?FileInterface {
    if (($media = this->getMedia()) && $media->hasField('field_file') && !$media->get('field_file')->isEmpty()) {
      return $media->field_file->entity;
    }
    return NULL;
  }
  public function getImageCaption(): ?string {
    if (($file = this->getMediaImage()) && $file->hasField('field_text') && !$file->get('field_text')->isEmpty()) {
      return $file->field_text->value;
    }
    return NULL;
  }
}

Puis dans votre code:

<?php

$image_caption = EventWrapper::fromNode($node)->getImageCaption();
7
larowlan

Bien que vous rendiez normalement les paragraphes de manière récursive, vous pouvez récupérer une structure fixe de manière non récursive en la recréant avec des boucles foreach:

foreach ($node->field_paragraph->referencedEntities() as $paragraph) {
  foreach ($paragraph->field_media->referencedEntities() as $media) {
    ...
  }
}

Cela évite d'accéder aux champs vides et est capable de traiter des champs à valeurs multiples.

5
4k4