function ContentEntityStorageBase::invokeFieldMethod

Same name in other branches
  1. 9 core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php \Drupal\Core\Entity\ContentEntityStorageBase::invokeFieldMethod()
  2. 8.9.x core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php \Drupal\Core\Entity\ContentEntityStorageBase::invokeFieldMethod()
  3. 11.x core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php \Drupal\Core\Entity\ContentEntityStorageBase::invokeFieldMethod()

Invokes a method on the Field objects within an entity.

Any argument passed will be forwarded to the invoked method.

Parameters

string $method: The name of the method to be invoked.

\Drupal\Core\Entity\ContentEntityInterface $entity: The entity object.

Return value

array A multidimensional associative array of results, keyed by entity translation language code and field name.

4 calls to ContentEntityStorageBase::invokeFieldMethod()
ContentEntityStorageBase::deleteRevision in core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
Delete a specific entity revision.
ContentEntityStorageBase::doDelete in core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
Performs storage-specific entity deletion.
ContentEntityStorageBase::invokeFieldPostSave in core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
Invokes the post save method on the Field objects within an entity.
ContentEntityStorageBase::invokeHook in core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
Invokes a hook on behalf of the entity.

File

core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php, line 917

Class

ContentEntityStorageBase
Base class for content entity storage handlers.

Namespace

Drupal\Core\Entity

Code

protected function invokeFieldMethod($method, ContentEntityInterface $entity) {
    $result = [];
    $args = array_slice(func_get_args(), 2);
    $langcodes = array_keys($entity->getTranslationLanguages());
    // Ensure that the field method is invoked as first on the current entity
    // translation and then on all other translations.
    $current_entity_langcode = $entity->language()
        ->getId();
    if (reset($langcodes) != $current_entity_langcode) {
        $langcodes = array_diff($langcodes, [
            $current_entity_langcode,
        ]);
        array_unshift($langcodes, $current_entity_langcode);
    }
    foreach ($langcodes as $langcode) {
        $translation = $entity->getTranslation($langcode);
        // For non translatable fields, there is only one field object instance
        // across all translations and it has as parent entity the entity in the
        // default entity translation. Therefore field methods on non translatable
        // fields should be invoked only on the default entity translation.
        $fields = $translation->isDefaultTranslation() ? $translation->getFields() : $translation->getTranslatableFields();
        foreach ($fields as $name => $items) {
            // call_user_func_array() is way slower than a direct call so we avoid
            // using it if have no parameters.
            $result[$langcode][$name] = $args ? call_user_func_array([
                $items,
                $method,
            ], $args) : $items->{$method}();
        }
    }
    // We need to call the delete method for field items of removed
    // translations.
    if ($method == 'postSave' && !empty($entity->original)) {
        $original_langcodes = array_keys($entity->original
            ->getTranslationLanguages());
        foreach (array_diff($original_langcodes, $langcodes) as $removed_langcode) {
            
            /** @var \Drupal\Core\Entity\ContentEntityInterface $translation */
            $translation = $entity->original
                ->getTranslation($removed_langcode);
            // Fields may rely on the isDefaultTranslation() method to determine
            // what is going to be deleted - the whole entity or a particular
            // translation.
            if ($translation->isDefaultTranslation()) {
                if (method_exists($translation, 'setDefaultTranslationEnforced')) {
                    $translation->setDefaultTranslationEnforced(FALSE);
                }
                else {
                    @trigger_error('Not providing a setDefaultTranslationEnforced() method when implementing \\Drupal\\Core\\TypedData\\TranslatableInterface is deprecated in drupal:10.2.0 and is required from drupal:11.0.0. See https://www.drupal.org/node/3376146', E_USER_DEPRECATED);
                }
            }
            $fields = $translation->getTranslatableFields();
            foreach ($fields as $name => $items) {
                $items->delete();
            }
        }
    }
    return $result;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.