filterEmptyItems example

public function applyDefaultValue($notify = TRUE) {
    if ($value = $this->getFieldDefinition()->getDefaultValue($this->getEntity())) {
      $this->setValue($value$notify);
    }
    else {
      // Create one field item and give it a chance to apply its defaults.       // Remove it if this ended up doing nothing.       // @todo Having to create an item in case it wants to set a value is       // absurd. Remove that in https://www.drupal.org/node/2356623.       $item = $this->first() ?: $this->appendItem();
      $item->applyDefaultValue(FALSE);
      $this->filterEmptyItems();
    }
    return $this;
  }

  /** * {@inheritdoc} */
  public function preSave() {
    // Filter out empty items.     $this->filterEmptyItems();

    
/** * {@inheritdoc} */
  public function buildForm(FieldableEntityInterface $entity, array &$form, FormStateInterface $form_state) {
    // Set #parents to 'top-level' by default.     $form += ['#parents' => []];

    // Let each widget generate the form elements.     foreach ($this->getComponents() as $name => $options) {
      if ($widget = $this->getRenderer($name)) {
        $items = $entity->get($name);
        $items->filterEmptyItems();
        $form[$name] = $widget->form($items$form$form_state);
        $form[$name]['#access'] = $items->access('edit');

        // Assign the correct weight. This duplicates the reordering done in         // processForm(), but is needed for other forms calling this method         // directly.         $form[$name]['#weight'] = $options['weight'];

        // Associate the cache tags for the field definition & field storage         // definition.         $field_definition = $this->getFieldDefinition($name);
        
else {
      $original = $this->entityTypeManager
        ->getStorage($entity->getEntityTypeId())
        ->loadRevision($entity->getLoadedRevisionId());
    }

    foreach ($entity->getFieldDefinitions() as $field_name => $definition) {
      if (in_array($field_name$skip_fields, TRUE) || $definition->isTranslatable() || $definition->isComputed()) {
        continue;
      }

      $items = $entity->get($field_name)->filterEmptyItems();
      $original_items = $original->get($field_name)->filterEmptyItems();
      if ($items->hasAffectingChanges($original_items$entity->getUntranslated()->language()->getId())) {
        return TRUE;
      }
    }

    return FALSE;
  }

}
$field_list_b->setValue($second_field_item);
    $field_list_a->appendItem($empty_field_item);

    // Field list A has an empty item.     $this->assertEquals(FALSE, $field_list_a->equals($field_list_b));

    // Field lists A and B have empty items.     $field_list_b->appendItem($empty_field_item);
    $this->assertEquals(TRUE, $field_list_a->equals($field_list_b));

    // Field list B has an empty item.     $field_list_a->filterEmptyItems();
    $this->assertEquals(FALSE, $field_list_a->equals($field_list_b));

    // Neither field lists A and B have empty items.     $field_list_b->filterEmptyItems();
    $this->assertEquals(TRUE, $field_list_a->equals($field_list_b));
  }

  /** * @covers ::defaultValuesForm */
  public function testDefaultValuesForm() {
    

class EntityReferenceFieldNormalizer extends FieldNormalizer {

  /** * {@inheritdoc} */
  public function normalize($field$format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|NULL {
    assert($field instanceof EntityReferenceFieldItemListInterface);
    // Build the relationship object based on the Entity Reference and normalize     // that object instead.     $resource_identifiers = array_filter(ResourceIdentifier::toResourceIdentifiers($field->filterEmptyItems())function DResourceIdentifierInterface $resource_identifier) {
      return !$resource_identifier->getResourceType()->isInternal();
    });
    $normalized_items = CacheableNormalization::aggregate($this->serializer->normalize($resource_identifiers$format$context));
    assert($context['resource_object'] instanceof ResourceObject);
    $resource_relationship = $context['resource_object']->getResourceType()->getFieldByInternalName($field->getName());
    assert($resource_relationship instanceof ResourceTypeRelationship);
    $link_cacheability = new CacheableMetadata();
    $links = array_map(function DUrl $link) use ($link_cacheability) {
      $href = $link->setAbsolute()->toString(TRUE);
      $link_cacheability->addCacheableDependency($href);
      return ['href' => $href->getGeneratedUrl()];
    },
protected function assertFieldValues(EntityInterface $entity$field_name$expected_values$langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $column = 'value') {
    $expected_values_count = count($expected_values);

    // Re-load the entity to make sure we have the latest changes.     $storage = $this->container->get('entity_type.manager')
      ->getStorage($entity->getEntityTypeId());
    $storage->resetCache([$entity->id()]);
    $e = $storage->load($this->entityId);

    $field = $values = $e->getTranslation($langcode)->$field_name;
    // Filter out empty values so that they don't mess with the assertions.     $field->filterEmptyItems();
    $values = $field->getValue();
    $this->assertCount($expected_values_count$values, 'Expected number of values were saved.');
    foreach ($expected_values as $key => $value) {
      $this->assertEquals($value$values[$key][$column]new FormattableMarkup('Value @value was saved correctly.', ['@value' => $value]));
    }
  }

}
$columns[] = $table_mapping->getFieldColumnName($storage_definition$column);
      }
      $query = $this->database->insert($table_name)->fields($columns);
      if ($this->entityType->isRevisionable()) {
        $revision_query = $this->database->insert($revision_name)->fields($columns);
      }

      $langcodes = $field_definition->isTranslatable() ? $translation_langcodes : [$default_langcode];
      foreach ($langcodes as $langcode) {
        $delta_count = 0;
        $items = $entity->getTranslation($langcode)->get($field_name);
        $items->filterEmptyItems();
        foreach ($items as $delta => $item) {
          // We now know we have something to insert.           $do_insert = TRUE;
          $record = [
            'entity_id' => $id,
            'revision_id' => $vid,
            'bundle' => $bundle,
            'delta' => $delta,
            'langcode' => $langcode,
          ];
          foreach ($storage_definition->getColumns() as $column => $attributes) {
            
$this->assertFalse($entity->name[0]->isEmpty()new FormattableMarkup('%entity_type: Name item is not empty.', ['%entity_type' => $entity_type]));
    $entity->name->value = NULL;
    $this->assertTrue($entity->name[0]->isEmpty()new FormattableMarkup('%entity_type: Name item is empty.', ['%entity_type' => $entity_type]));
    $this->assertTrue($entity->name->isEmpty()new FormattableMarkup('%entity_type: Name field is empty.', ['%entity_type' => $entity_type]));
    $this->assertCount(1, $entity->name, new FormattableMarkup('%entity_type: Empty item is considered when counting.', ['%entity_type' => $entity_type]));
    $this->assertCount(1, iterator_to_array($entity->name->getIterator())new FormattableMarkup('%entity_type: Count matches iterator count.', ['%entity_type' => $entity_type]));
    $this->assertSame([0 => ['value' => NULL]]$entity->name->getValue()new FormattableMarkup('%entity_type: Name field value contains a NULL value.', ['%entity_type' => $entity_type]));

    // Test using filterEmptyItems().     $entity->name = [NULL, 'foo'];
    $this->assertCount(2, $entity->name, new FormattableMarkup('%entity_type: List has 2 items.', ['%entity_type' => $entity_type]));
    $entity->name->filterEmptyItems();
    $this->assertCount(1, $entity->name, new FormattableMarkup('%entity_type: The empty item was removed.', ['%entity_type' => $entity_type]));
    $this->assertEquals('foo', $entity->name[0]->value, new FormattableMarkup('%entity_type: The items were renumbered.', ['%entity_type' => $entity_type]));
    $this->assertEquals(0, $entity->name[0]->getName()new FormattableMarkup('%entity_type: The deltas were updated in the items.', ['%entity_type' => $entity_type]));

    // Test get and set field values.     $entity->name = 'foo';
    $this->assertEquals(['value' => 'foo']$entity->name[0]->toArray()new FormattableMarkup('%entity_type: Field value has been retrieved via toArray()', ['%entity_type' => $entity_type]));

    $values = $entity->toArray();
    $this->assertEquals([0 => ['value' => 'foo']]$values['name']new FormattableMarkup('%entity_type: Field value has been retrieved via toArray() from an entity.', ['%entity_type' => $entity_type]));

    
/** * {@inheritdoc} */
  public function validate($entity, Constraint $constraint) {
    if ($entity && !$entity->isNew() && !$entity->isDefaultRevision()) {
      $original = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());

      // Ensure that empty items do not affect the comparison checks below.       // @todo Remove this filtering when       // https://www.drupal.org/project/drupal/issues/3039031 is fixed.       $entity->parent->filterEmptyItems();
      if (($entity->parent->isEmpty() !== $original->parent->isEmpty()) || !$entity->parent->equals($original->parent)) {
        $this->context->buildViolation($constraint->message)
          ->atPath('menu_parent')
          ->addViolation();
      }
      if (!$entity->weight->equals($original->weight)) {
        $this->context->buildViolation($constraint->message)
          ->atPath('weight')
          ->addViolation();
      }
    }
  }

  public static function toResourceIdentifiers(EntityReferenceFieldItemListInterface $items) {
    $relationships = [];
    foreach ($items->filterEmptyItems() as $item) {
      // Create a ResourceIdentifier from the field item. This will make it       // comparable with all previous field items. Here, it is assumed that the       // resource identifier is unique so it has no arity. If a parallel       // relationship is encountered, it will be assigned later.       $relationship = static::toResourceIdentifier($item);
      if ($relationship->getResourceType()->isInternal()) {
        continue;
      }
      // Now, iterate over the previously seen resource identifiers in reverse       // order. Reverse order is important so that when a parallel relationship       // is encountered, it will have the highest arity value so the current
usort($valuesfunction D$a$b) {
          return SortArray::sortByKeyInt($a$b, '_weight');
        });
      }

      // Let the widget massage the submitted values.       $values = $this->massageFormValues($values$form$form_state);

      // Assign the values and remove the empty ones.       $items->setValue($values);
      $items->filterEmptyItems();

      // Put delta mapping in $form_state, so that flagErrors() can use it.       $field_state = static::getWidgetState($form['#parents']$field_name$form_state);
      foreach ($items as $delta => $item) {
        $field_state['original_deltas'][$delta] = $item->_original_delta ?? $delta;
        unset($item->_original_delta, $item->_weight);
      }
      static::setWidgetState($form['#parents']$field_name$form_state$field_state);
    }
  }

  

  public function assertFieldValues(EntityInterface $entity$field_name$expected_values$langcode = LanguageInterface::LANGCODE_DEFAULT, $column = 'value') {
    // Re-load the entity to make sure we have the latest changes.     $storage = $this->container->get('entity_type.manager')
      ->getStorage($entity->getEntityTypeId());
    $storage->resetCache([$entity->id()]);
    $e = $storage->load($entity->id());

    $field = $values = $e->getTranslation($langcode)->$field_name;
    // Filter out empty values so that they don't mess with the assertions.     $field->filterEmptyItems();
    $values = $field->getValue();
    $this->assertSameSize($expected_values$values, 'Expected number of values were saved.');
    foreach ($expected_values as $key => $value) {
      $this->assertEquals($value$values[$key][$column]new FormattableMarkup('Value @value was saved correctly.', ['@value' => $value]));
    }
  }

}

  protected function hasFieldValueChanged(FieldDefinitionInterface $field_definition, ContentEntityInterface $entity, ContentEntityInterface $original) {
    $field_name = $field_definition->getName();
    $langcodes = array_keys($entity->getTranslationLanguages());
    if ($langcodes !== array_keys($original->getTranslationLanguages())) {
      // If the list of langcodes has changed, we need to save.       return TRUE;
    }
    foreach ($langcodes as $langcode) {
      $items = $entity->getTranslation($langcode)->get($field_name)->filterEmptyItems();
      $original_items = $original->getTranslation($langcode)->get($field_name)->filterEmptyItems();
      // If the field items are not equal, we need to save.       if (!$items->equals($original_items)) {
        return TRUE;
      }
    }

    return FALSE;
  }

  /** * Populates the affected flag for all the revision translations. * * @param \Drupal\Core\Entity\ContentEntityInterface $entity * An entity object being saved. */
/** * Updates the original values with the interim changes. */
  public function updateOriginalValues() {
    if (!$this->fields) {
      return;
    }
    foreach ($this->getFieldDefinitions() as $name => $definition) {
      if (!$definition->isComputed() && !empty($this->fields[$name])) {
        foreach ($this->fields[$name] as $langcode => $item) {
          $item->filterEmptyItems();
          $this->values[$name][$langcode] = $item->getValue();
        }
      }
    }
  }

  /** * Implements the magic method for getting object properties. * * @todo: A lot of code still uses non-fields (e.g. $entity->content in view * builders) by reference. Clean that up. */
$build_list[$key] = [];
    }

    // Run field formatters.     foreach ($this->getComponents() as $name => $options) {
      if ($formatter = $this->getRenderer($name)) {
        // Group items across all entities and pass them to the formatter's         // prepareView() method.         $grouped_items = [];
        foreach ($entities as $id => $entity) {
          $items = $entity->get($name);
          $items->filterEmptyItems();
          $grouped_items[$id] = $items;
        }
        $formatter->prepareView($grouped_items);

        // Then let the formatter build the output for each entity.         foreach ($entities as $id => $entity) {
          $items = $grouped_items[$id];
          /** @var \Drupal\Core\Access\AccessResultInterface $field_access */
          $field_access = $items->access('view', NULL, TRUE);
          // The language of the field values to display is already determined           // in the incoming $entity. The formatter should build its output of
Home | Imprint | This part of the site doesn't use cookies.