5

I try to list all fields where a paragraph type is referenced (to find all contents which have paragraphs of a specific type).

My problem: I do a EntityQuery on field_config entity type to find the fields. But, the condition on which paragraph_type are targeted doesn't work correctly and return all fields which can content a paragraph disregarding the type.

Here my code:

// Recover my paragraph_type selected in my form.
$paragraph_type = $form_state->getValue('paragraph_type');

// List all field_config which referred this paragraph_type.
$query = \Drupal::entityQuery('field_config')
  ->condition('field_type', 'entity_reference_revisions')
  ->condition('settings.handler', 'default:paragraph')
  ->condition('settings.handler_settings.target_bundles', $paragraph_type, 'IN');

$field_config = $query->execute();

For exemple, I have a paragraph type "press_release_about" which can be add only in press release in a specific field. But for this paragraph (and all others), it's all fields which can contains a paragraph in the system which are returned.

When I inspect a field_config which referred paragraph, I can see that settings.handler_settings.target_bundles is an array of the paragraph types which can be add with this field. The format is:

[settings:protected] => Array
    (
        [handler] => 'default:paragraph'
        [handler_settings] => Array
            (
                [target_bundles] => Array
                    (
                        [1col_text] => 1col_text
                        [1col_image] => 1col_image
                        [1col_quote] => 1col_quote
                        [1_col_graphique] => 1_col_graphique
                        [2_cols_texte_media] => 2_cols_texte_media
                        [2_cols_texte_graphique] => 2_cols_texte_graphique
                        [2_cols_text] => 2_cols_text
                    )
              )
         )

If I remove the condition ->condition('settings.handler_settings.target_bundles', $paragraph_type, 'IN'), this change nothing. And if I change the INby NOT IN, I have no result.

I don't know if I don't write my condition correctly or if my error is elsewhere.

2 Answers 2

5

try to use an array instead of the value of $paragraph_type.

that would be like this :

->condition('settings.handler_settings.target_bundles', [$paragraph_type], 'IN')
1

Unfortunately, this cannot be achieved directly with IN or other default operators atm.

This will throw an error like this:

PHP Warning:  mb_strtolower() expects parameter 1 to be string, array given in /var/www/bayer/docroot/core/lib/Drupal/Core/Config/Entity/Query/Condition.php on line 171

There is an open issue queue exactly for this: https://www.drupal.org/project/drupal/issues/2248567

Meanwhile, if you want to achieve this somehow, then we can do something like this:

Example: Consider if the settings.handler_settings.target_bundles key in some field_config config has values like these:

[
  'article'=> 'article', 
  'faq' => 'faq', 
  // etc... 
]

Then we can use entityQuery something like this to add a condition based on these.

// Recover my paragraph_type selected in my form.
$paragraph_type = $form_state->getValue('paragraph_type');

// List all field_config which referred this paragraph_type.
$query = \Drupal::entityQuery('field_config')
  ->condition('field_type', 'entity_reference_revisions')
  ->condition('settings.handler', 'default:paragraph')
  // We can write some logic to make 'article' dynamically via a variable.
  ->condition('settings.handler_settings.target_bundles.article', 'article');

$field_config = $query->execute();
1
  • The linked issue above has a comment which I believe is the ideal solution to query a field containing an array: ->condition('settings.handler_settings.target_bundles.*', $paragraph_type) Apr 15, 2022 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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