10

I'm porting a module from Drupal 7 to Drupal 8. In this module's configuration settings I need to get the list of the currently existing field-types.

In Drupal 7, this was achieved using the field_info_field_types() function.

In Drupal 8 (8.0.0-rc3), I get an error "function does not exist", despite the information stated by a Drupal API Reference Help page, clearly out of date.

Then investigating I found a DrupalContrib page, where the function is declared deprecated, and proposing to now use Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions().

But using it fires another error "Unknown service plugin.manager.entity.field.field_type", fortunately associated to the suggestion "Do you mean plugin.manager.field.field_type?"

So I tried using Drupal::service('plugin.manager.field.field_type')->getDefinitions() and wow: I got the expected array of field-types.

But each array member (one field-type) is now an object (instead of a child array), and the data I'm looking for is nested within protected properties, so I can't access them.

At this stage, I'm stuck. I considered it might exist some class I could expand to navigate through these data, but with no luck: I notably couldn't even figure out which is the component in Drupal 8 where field-types definitions is centralized.

  • It's better you look at api.drupal.org, which is more update. In fact, there isn't a page for that function. – kiamlaluno Nov 9 '15 at 16:45
  • Thanks for the tip "look at api.drupal.org". In the other hand (and this is rather meta relevant, sorry), if I easily understand you edited my abbreviations (D7 -> Drupal 7), I'm wondering why you dropped "Drupal 8" in the title? I tend to think that there would be some rule saying that it's redondant with the "8" tag. But as a reader I use to find me much more surely informed by the title than the tag: at my eyes, tags essentially address searching process, while sequentially reading I rarely pay attention to them. – cFreed Nov 9 '15 at 17:35
  • There is no need to repeat tags in title, as those are always visible wherever a question is listed. Stack Exchange users pay attention to tags. – kiamlaluno Nov 9 '15 at 18:50
16

The first level is an array. The keys are the plugin id's. You can list them:

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

This is the result:

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

You can pick one and dump the plugin definition.

var_dump($defs['comment']);

If you are interested in a special object, you can digg deeper with the help of api.drupal.org. But it will be easier, if you search for the plugin in the core directory.

To access an object, locate it in the var_dump and use a method:

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

In this case it is the object TranslatableMarkup, which has the method render to access the translated string.

  • Thanks but this is what I already did. Beyond that, my problem remains: how can I programatically access the data inside these objects? – cFreed Nov 9 '15 at 17:28
  • What do you want to find in the field definitions? In general you look up the properties and methods of an object in api and then you access them with `->' . Field definitions are easier to look up in source. – 4k4 Nov 9 '15 at 17:35
  • I extract label, description and module and display them in a configuration form where the user can check the ones for which it wants my module (MMS) creates cloned tokens for the related fields. – cFreed Nov 9 '15 at 17:40
  • I add an example. – 4k4 Nov 9 '15 at 17:50
  • Oops! I saw your last comment, but did not notice your edit, so I keeped waiting. I will try your suggestion. Thanks. – cFreed Nov 9 '15 at 19:43
4

Every string that is passed through t() is an object now. You can access them as strings, in fact, you should do so.

There are only very few exceptions where you can't just use such an object as-is, for example array keys, for those, you need to cast them to a string. Anything else should just work.

PS: The official API documentation is http://api.drupal.org/api/drupal/8. Use that for core.

Another good resource are change records: 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: Responding to your comment, I don't quite understand what you mean. All the information you need is right there, just use it.

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

Again, just ignore that label/description are objects. They have __toString() methods that are automatically called when you print/use them.

  • Thanks for this answer. Your last proposed link looks very promising and I will investigate based on this information. Briefly said, am I wrong if I guess that for my needs (extract label, description, module strings of each field-type) I should: 1) get list from Drupal::service('plugin.manager.field.field_type')->getDefinitions() like already done; 2) then use each key of returned array (the field-type name) for invoking a specific class (find which one, and where, is what I must examine deeper) that will provide methods to get the needed infos? TIA for this precision. – cFreed Nov 9 '15 at 19:01
  • Updated my answer. – Berdir Nov 9 '15 at 19:19
  • Oops... don't understand! What you proposed in your edit is merely what I did in D7. And it does NOT work in D8, since $definition is not an array of strings in D8, but an array of objects! I used dpm() to examine them, and saw that each of the needed strings appears nested this way: 'label' => array(..., 'label' => Drupal\Core\StringTranslation\TranslatableMarkup Object {..., string, ...}, ...). Am I missing something obvious? – cFreed Nov 9 '15 at 19:40
  • Just discovered (lately) the last edit of 4k4, which works. In fact the issue for me was to know where to find the TranslatableMarkup class, and the availibility of the render() method,. Finally the correct way to get my data is print $definition['label']->render();. Nevertheless, thanks for your other informations. – cFreed Nov 9 '15 at 19:53
  • No, again, you do not need ->render(). use $definition['label'], it just works, trust me :) – Berdir Nov 9 '15 at 20:38
1

Updated version for @Berdir answer. Use in shell.

$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;
}

Output here: https://gist.github.com/sobi3ch/70635cc62defff606242

1

Google seems to find this Question when searching for these

If you are using Drupal Console you can also use:

drupal plugin:debug field.field_type

There is also this on Drupal.org which can also help:

Defining and using Content Entity Field definitions

Its not easy finding examples of useable though

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.