Basic usage

Last updated on
23 March 2018

Changed Fields API is built on "Observer" pattern. The idea is pretty simple: attach observers to an entity subject which will notify all of them about changes in entity fields.

Observer

Define class that implements ObserverInterface interface. This interface provides two methods: ObserverInterface::getInfo() and ObserverInterface::update(SplSubject $entitySubject). First method should return an associative array keyed by entity type names which in turn contain a list of bundles and field names you want to observe. Second method is a place where you can react on changed fields and do something with an entity. It will be called only if some of listed fields were changed.

<?php

namespace Drupal\changed_fields_basic_usage;

use Drupal\changed_fields\ObserverInterface;
use SplSubject;

/**
 * Class BasicUsageObserver.
 */
class BasicUsageObserver implements ObserverInterface {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    return [
      'node' => [
        'article' => [
          'title',
          'body',
        ],
      ],
      'user' => [
        'user' => [
          'name',
          'mail',
        ],
      ],
      'taxonomy_term' => [
        'tags' => [
          'name',
          'description',
        ],
      ],
      'comment' => [
        'comment' => [
          'subject',
          'comment_body',
        ],
      ],
      'shortcut' => [
        'default' => [
          'title',
          'link',
        ],
      ],
      'menu_link_content' => [
        'menu_link_content' => [
          'title',
          'link',
        ],
      ],
      'media' => [
        'image' => [
          'name',
          'field_media_image',
        ],
      ],
      'block_content' => [
        'basic' => [
          'info',
          'body',
        ],
      ],
      'aggregator_feed' => [
        'aggregator_feed' => [
          'title',
          'refresh',
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function update(SplSubject $entity_subject) {
    $entity = $entity_subject->getEntity();
    $changed_fields = $entity_subject->getChangedFields();

    // Do something with $entity depends on $changed_fields.
  }

}

Entity presave

In order to detect changed fields in an entity we need to do several steps:

  1. Wrap an entity object into instance of EntitySubject and set up the field comparator. Field comparator is an object which checks needed fields and returns differences between old and new field values. Default comparator is default_field_comparator but you can define your own by extending default one. 
  2. Then attach your observer BasicUsageObserver to instance of EntitySubject
  3. Finally execute EntitySubject::notify() method and react on this event in BasicUsageObserver::update(SplSubject $entitySubject) if some of field values of registered entity types have been changed.
<?php

use Drupal\changed_fields\EntitySubject;
use Drupal\changed_fields_basic_usage\BasicUsageObserver;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;

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

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

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

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_basic_usage module for more information.

Help improve this page

Page status: No known problems

You can: