Advanced usage: support for extra or custom fields

Last updated on
23 March 2018

By default Changed Field API comes with default_field_comparator class which supports all the core Drupal's field types.

But what if you have a field type from a contrib module that is not listed above or you have your own field type from a custom module? Changed Fields API have to know how to compare that fields. In order to do that you have to write a custom field comparator.

Custom field comparator

In Drupal 8 version of the module field comparators are plugins and they should be placed intomodule_name/src/Plugin/FieldComparator directory. Define a class, extend it from DefaultFieldComparator and override method DefaultFieldComparator::getDefaultComparableProperties(FieldDefinitionInterface $fieldDefinition). All that you need is return field properties to compare depends on a field type. For example for text_with_summary fields API returns array('value', 'summary').

<?php

/**
 * @file
 * Contains ExtendedFieldComparator.php.
 */

namespace Drupal\changed_fields_extended_field_comparator\Plugin\FieldComparator;

use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\changed_fields\Plugin\FieldComparator\DefaultFieldComparator;

/**
 * @Plugin(
 *   id = "extended_field_comparator"
 * )
 */
class ExtendedFieldComparator extends DefaultFieldComparator {

  /**
   * {@inheritdoc}
   */
  public function getDefaultComparableProperties(FieldDefinitionInterface $fieldDefinition) {
    $properties = [];

    // Return comparable field properties for extra or custom field type.
    if ($fieldDefinition->getType() == 'some_field_type') {
      $properties = [
        'some_field_property_1',
        'some_field_property_2',
      ];
    }

    return $properties;
  }

}

Entity presave

When we are done with custom field comparator we need to tell API that we want to use it instead of default one. This step is almost the same as in "Basic usage" chapter but we need to pass id of new field comparator into EntitySubject::__construct() -  extended_field_comparator.

<?php

use Drupal\changed_fields\EntitySubject;
use Drupal\changed_fields_extended_field_comparator\ExtendedFieldComparatorObserver;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_entity_presave().
 */
function changed_fields_extended_field_comparator_entity_presave(EntityInterface $entity) {
  if ($entity instanceof ContentEntityInterface) {
    // Create EntitySubject object that will check entity fields by DefaultFieldComparator.
    $entity_subject = new EntitySubject($entity, 'extended_field_comparator');

    // Add your observer object to EntitySubject.
    $entity_subject->attach(new ExtendedFieldComparatorObserver());

    // Check if entity fields have been changed.
    $entity_subject->notify();
  }
}

 After that when API will compare old and new field values it will take into consideration fields of a new field type which we've described in our custom field comparator.

Dependencies

Do not forget to include a file with defined observer and add dependency to Changed Fields API module to your *.info.yml file:

dependencies:
  - changed_fields

More info

See changed_fields_extended_field_comparator module for more information.

Help improve this page

Page status: No known problems

You can: