Obtenez tous les champs définis dans un ensemble

16

pour obtenir tous les champs utilisés dans un type de contenu, dans Drupal 7 j'utilise le code suivant.

$fields = field_info_instances('node', 'article');

Quel est l'équivalent pour Drupal 8?

Pravin Ajaaz
la source
1
Travaillez-vous avec une entité? Si oui: le $fields = $entity->getFieldDefinitions();fera. Je ne suis pas sûr de ce que l'équivalent de field_info_instances(), FieldStorageConfigne semble pas en avoir un
Clive
Non, je veux juste modifier le node_type_edit_form et ajouter une liste de champs définis par le type de noeud dans le formulaire. Donc, le type du nœud est le seul argument que j'ai. J'ai donc pensé qu'une fonction comme field_info_instances pourrait aider.
Pravin Ajaaz
@Clive: puis-je créer un objet entité en utilisant le nom du type d'entité. Il existe une fonction NodeType :: load ('article') qui crée un objet pour les types de nœuds.
Pravin Ajaaz
\Drupal::entityManager()->getFieldDefinitions('node', 'article')a fait le boulot :)
Pravin Ajaaz

Réponses:

31

EntityManager est obsolète à l'avenir. Les éléments suivants peuvent être utilisés à la place:

$entityFieldManager = \Drupal::service('entity_field.manager');
$fields = $entityFieldManager->getFieldDefinitions($entity_type, $bundle);
NewZeal
la source
Existe-t-il un moyen d'obtenir uniquement la liste des champs cck?
Rajesh Vishwakarma
2
Cela devrait être la réponse acceptée maintenant.
Bram
25

Je l'ai atteint en utilisant getFieldDefinitions()défini dans Class EntityManager. Donc, pour obtenir tous les champs utilisés dans un bundle particulier, voici un moyen:

$bundle_fields = \Drupal::entityManager()->getFieldDefinitions('node', 'article');

Bien que ce qui précède $bundle_fieldscontienne également des nid, uuid, revisions, langcode, etcchamps. Donc, pour obtenir une sortie précise, j'ai fait quelque chose comme ceci:

  $entity_type_id = 'node';
  $bundle = 'article';
  foreach (\Drupal::entityManager()->getFieldDefinitions($entity_type_id, $bundle) as $field_name => $field_definition) {
    if (!empty($field_definition->getTargetBundle())) {
      $bundleFields[$entity_type_id][$field_name]['type'] = $field_definition->getType();
      $bundleFields[$entity_type_id][$field_name]['label'] = $field_definition->getLabel();
    }
  }
Pravin Ajaaz
la source
2
Cela fonctionne, cependant entityManager est déconseillé. Le commentaire au-dessus de la définition de la fonction indique utiliser entityTypeManager ou si la méthode n'est pas implémentée (getFieldDefinitions ne l'est pas) "voir le \ Drupal \ Core \ Entity \ EntityManager déconseillé pour trouver l'interface ou le service correct." Je ne comprends pas ce commentaire. Où puis-je chercher pour trouver la fonction correcte à utiliser?
Felix Eve
5
Pour filtrer les champs de base ( nid, uuid, revisions, langcode, etc), vous pouvez le faireif($field->getFieldStorageDefinition()->isBaseField() == FALSE)
leon.nk
1
Existe-t-il un moyen d'obtenir les définitions de champ pour tous les types de types de contenu, pas un seul?
Matt
1
@ leon.nk yes <code> if ($ field-> getFieldStorageDefinition () -> isBaseField () == FALSE) </code> qui est plus précis que <code> if (! empty ($ field_definition-> getTargetBundle ()) ) </code> pour filtrer les champs de base.
Hanmant
6

EntityManager est obsolète et j'ai utilisé le code suivant. J'ai ajouté à la classe Controller:

 /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManager
   */
  protected $entityFieldManager;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Entity\EntityFieldManager $entity_field_manager
   *   The entity field manager.
   */
  public function __construct(EntityFieldManager $entity_field_manager) {
    $this->entityFieldManager = $entity_field_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_field.manager')
    );
  }

// Voici quelques fonctions

 /**
   * Build table rows.
   */
  protected function buildRows() {
    $entity_type_id = 'node';
    $bundle = 'article';
$fields = $this->entityFieldManager->getFieldDefinitions($entity_type_id, $bundle);
foreach ($fields as $field_name => $field_definition) {
  if (!empty($field_definition->getTargetBundle())) {               
    $listFields[$field_name]['type'] = $field_definition->getType();
    $listFields[$field_name]['label'] = $field_definition->getLabel();                  
  }
}
$rows = [];
foreach ($listFields as $field_name => $info) {
  $rows[] = $this->buildRow($info, $field_name);
}
return $rows;

}

https://www.drupal.org/node/2549139 il m'a été aidé

Maria
la source
Quelques conseils: Dans les constructeurs (et en général) utilisez toujours des interfaces. La plupart des implémentations de service drupal ont des interfaces bien définies.
ssibal