1

Conceptually and for performance purposes it is advisable to reuse existing fields in Drupal. This is very easy to do manually, but my question is, how can I do this programmatically? I have the following code:

$all_bundle_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('taxonomy_term', $vid);

if (!isset($all_bundle_fields['field_image'])) {
  FieldStorageConfig::create(array(      
    'field_name' => 'field_image',
    'entity_type' => 'taxonomy_term',
    'type' => 'entity_reference',
    'settings' => [
      'target_type' => 'media',
    ], 
    'cardinality' => 1      
  ))->save();

  FieldConfig::create(array(      
    'field_name' => 'field_image',
    'entity_type' => 'taxonomy_term',
    'bundle' => $vid,
    'label' => 'Logo',
    'description' => 'Logo to represent the term.',
    'required' => FALSE,
  ))->save();
}

In this example, I extract all the fields from the vocabulary and only create the field if and only if it does not exist previously in this vocabulary. The above code works.

What does not work here is if that field has already been created for another entity or vocabulary. This is what I would like to find out in order to make a complete reuse of the fields.

Thanks in advance.

1
  • By design Drupal is reusing fields because the field storage is not bundle specific. You can check for existing field storages with FieldStorageConfig::loadByName. This question, for a different but related issue, contains the code drupal.stackexchange.com/questions/298957/… – 4k4 Jan 2 at 9:43
0

Until someone tells me how an existing field can be reused I have got a remedy. As my "need" was to reuse fields that I have been creating in various vocabularies, what I have done is the following:

  1. Create a function that goes through all the existing vocabularies and checks if a certain field, passed by parameter, exists.
  2. If so, it returns me the name of the vocabulary where it already exists. This saves me from creating the corresponding database table.
  3. Then I check if the vocabulary where the field exists is my own vocabulary. In case it is not, I link it.

This would be the final result. First, the function:

function existsField($field) {
  $vocabularies = taxonomy_vocabulary_get_names();

  foreach($vocabularies as $vocabulary) {
     $all_bundle_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('taxonomy_term', $vocabulary);
     if (isset($all_bundle_fields[$field])) {
        return $vocabulary;
     }
  }
}

Next, the final code:

$vocabulary = existsField('field_image');

if (empty($vocabulary)) {
  FieldStorageConfig::create(array(      
     'field_name' => 'field_image',
     'entity_type' => 'taxonomy_term',
     'type' => 'entity_reference',
     'settings' => [
        'target_type' => 'media',
     ], 
     'cardinality' => 1      
  ))->save();
}

if (empty($vocabulary) || $vocabulary != $vid) {
  FieldConfig::create(array(      
     'field_name' => 'field_image',
     'entity_type' => 'taxonomy_term',
     'bundle' => $vid,
     'label' => 'Logo',
     'description' => 'Logo to represent the term.',
     'required' => FALSE,
  ))->save();
}

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.