Comment obtenir la liste des types de champs?


10

Je porte un module de Drupal 7 vers Drupal 8. Dans les paramètres de configuration de ce module, j'ai besoin d'obtenir la liste des types de champs actuellement existants.

Dans Drupal 7, cela a été réalisé en utilisant la field_info_field_types()fonction.

Dans Drupal 8 (8.0.0-rc3), j'obtiens une erreur "la fonction n'existe pas", malgré les informations indiquées par une page d'aide de référence de l'API Drupal , clairement obsolète.

En enquêtant, j'ai trouvé une page DrupalContrib , où la fonction est déclarée obsolète, et propose maintenant de l'utiliser Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions().

Mais son utilisation déclenche une autre erreur "Service inconnu plugin.manager.entity.field.field_type", heureusement associée à la suggestion "Voulez-vous dire plugin.manager.field.field_type?"

J'ai donc essayé d'utiliser Drupal::service('plugin.manager.field.field_type')->getDefinitions()et wow: j'ai obtenu le tableau attendu des types de champs.

Mais chaque membre du tableau (un type de champ) est maintenant un objet (au lieu d'un tableau enfant), et les données que je recherche sont imbriquées dans des propriétés protégées, donc je ne peux pas y accéder.

À ce stade, je suis coincé. J'ai pensé qu'il pourrait exister une classe que je pourrais développer pour parcourir ces données, mais sans succès: je n'ai même pas pu comprendre quel est le composant de Drupal 8 où les définitions de types de champs sont centralisées.


Il vaut mieux regarder api.drupal.org, qui est plus à jour. En fait, il n'y a pas de page pour cette fonction .
kiamlaluno

Merci pour le conseil "regardez api.drupal.org". D'un autre côté (et c'est plutôt méta pertinent, désolé), si je comprends facilement que vous avez édité mes abréviations (D7 -> Drupal 7), je me demande pourquoi vous avez laissé tomber "Drupal 8" dans le titre? J'ai tendance à penser qu'il y aurait une règle disant qu'il est redondant avec la balise "8". Mais en tant que lecteur, j'utilise pour me trouver beaucoup plus sûrement informé par le titre que par le tag: à mes yeux, les tags traitent essentiellement du processus de recherche, alors qu'en lecture séquentielle, je leur prête rarement attention.
cFreed

Il n'est pas nécessaire de répéter les balises dans le titre, car elles sont toujours visibles partout où une question est répertoriée. Les utilisateurs de Stack Exchange prêtent attention aux balises.
kiamlaluno

Réponses:


16

Le premier niveau est un tableau. Les clés sont les identifiants des plugins. Vous pouvez les lister:

$defs = Drupal::service('plugin.manager.field.field_type')->getDefinitions();
foreach ( $defs as $key => $value ) {
   echo $key, "\n";
}

Voici le résultat:

comment
datetime
file
image
link
list_string
list_float
list_integer
path
text_with_summary
text
text_long
email
boolean
created
changed
timestamp
string_long
language
decimal
uri
float
password
string
integer
entity_reference
uuid
map
taxonomy_term_reference

Vous pouvez en choisir un et vider la définition du plugin.

var_dump($defs['comment']);

Si vous êtes intéressé par un objet spécial, vous pouvez creuser plus profondément avec l'aide de api.drupal.org. Mais ce sera plus facile, si vous recherchez le plugin dans le répertoire principal.

Pour accéder à un objet, localisez-le dans var_dump et utilisez une méthode:

$defs['comment']['description']->render();

Dans ce cas, c'est l'objet TranslatableMarkup , qui a la méthode render pour accéder à la chaîne traduite.


Merci mais c'est ce que j'ai déjà fait. Au-delà de cela, mon problème demeure: comment puis-je accéder par programmation aux données à l' intérieur de ces objets?
cFreed

Que voulez-vous trouver dans les définitions de champ? En général, vous recherchez les propriétés et les méthodes d'un objet dans l'api, puis vous y accédez avec `-> '. Les définitions de champ sont plus faciles à rechercher dans la source.
4k4

J'extrais label, descriptionet moduleet les afficher sous forme de configuration dans laquelle l'utilisateur peut vérifier ceux pour lesquels il veut mon module ( MMS ) crée clonées jetons pour les domaines connexes.
cFreed

J'ajoute un exemple.
4k4

Oups! J'ai vu votre dernier commentaire, mais je n'ai pas remarqué votre modification, j'ai donc continué d'attendre. J'essaierai votre suggestion. Merci.
cFreed

4

Chaque chaîne passée par t () est maintenant un objet. Vous pouvez y accéder sous forme de chaînes, en fait, vous devriez le faire.

Il n'y a que très peu d'exceptions où vous ne pouvez pas simplement utiliser un tel objet tel quel, par exemple des clés de tableau, pour celles-ci, vous devez les convertir en chaîne. Tout le reste devrait simplement fonctionner.

PS: La documentation officielle de l'API est http://api.drupal.org/api/drupal/8 . Utilisez cela pour le noyau.

Une autre bonne ressource sont les enregistrements de changement: https://www.drupal.org/list-changes/published?keywords_description=field_info_field_types&to_branch=&version=&created_op=%3E%3D&created%5Bvalue%5D=&created%5Bmin%5D=&created%5Bmax% 5D =

Edit: En réponse à votre commentaire, je ne comprends pas très bien ce que vous voulez dire. Toutes les informations dont vous avez besoin sont là, utilisez-les.

$definitions = Drupal::service('plugin.manager.field.field_type')->getDefinitions();
foreach ( $definitions as $field_type => $definition) {
  print $definition['label'];
  print $definition['description'];
  print $definition['provider'];
}

Encore une fois, ignorez simplement que l'étiquette / la description sont des objets. Ils ont des méthodes __toString () qui sont automatiquement appelées lorsque vous les imprimez / les utilisez.


Merci pour cette réponse. Votre dernier lien proposé semble très prometteur et je vais enquêter sur la base de ces informations. En bref dit, je me trompe si je suppose que pour mes besoins (extrait label, description, les modulechaînes de chaque type de terrain) je: 1) obtenir la liste de Drupal::service('plugin.manager.field.field_type')->getDefinitions()comme déjà fait; 2) puis utiliser chaque clé du tableau retourné (le nom du type de champ) pour invoquer une classe spécifique (trouver laquelle et où dois-je approfondir) qui fournira des méthodes pour obtenir les informations nécessaires? TIA pour cette précision.
cFreed

Mis à jour ma réponse.
Berdir

Oups ... je ne comprends pas! Ce que vous avez proposé dans votre montage est simplement ce que j'ai fait dans D7. Et cela ne fonctionne PAS en D8, car il $definitionne s'agit pas d'un tableau de chaînes en D8, mais d'un tableau d'objets! Je dpm () pour les examiner, et a vu que chacune des chaînes nécessaires apparaît imbriqué cette façon: 'label' => array(..., 'label' => Drupal\Core\StringTranslation\TranslatableMarkup Object {..., string, ...}, ...). Suis-je en train de manquer quelque chose d'évident?
cFreed

Je viens de découvrir (dernièrement) la dernière édition de 4k4, qui fonctionne. En fait, le problème pour moi était de savoir où trouver la TranslatableMarkupclasse et la disponibilité de la render()méthode. Enfin, la bonne façon d'obtenir mes données est print $definition['label']->render();. Néanmoins, merci pour vos autres informations.
cFreed

Non, encore une fois, vous n'avez pas besoin de -> render (). utilisez $ definition ['label'], ça marche, croyez-moi :)
Berdir

1

Version mise à jour pour la réponse @Berdir. Utilisation en coquille.

$definitions = Drupal::service('plugin.manager.field.field_type')->getDefinitions();
foreach ( $definitions as $field_type => $definition) {
  print 'Label: '. $definition['label']. PHP_EOL;
  print 'Machine name: '. $field_type. PHP_EOL;
  print 'Descritpion: '. $definition['description']. PHP_EOL;
  print 'Provider: '. $definition['provider']. PHP_EOL . ' ---' . PHP_EOL;
}

Sortie ici: https://gist.github.com/sobi3ch/70635cc62defff606242


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.