Adding Properties to Drupal 8 Configuration Entities

Submitted by djevans on Thu, 08/10/2017 - 07:02

I'm currently working on porting the Views Save module to Drupal 8. Users can save searches executed as Views, and can choose to publish them (making them accessible to other users), or keep them private.

The Saved Views can be of different types, and an administrator should be able to specify whether new Saved Views of a particular type should be published by default. I've created a SavedViewType class, which is a configuration entity that acts as a bundle for SavedView.

First, I declared some getters and setters on the interface.

/**
 * Provides an interface for defining Saved View type entities.
 */
interface SavedViewTypeInterface extends ConfigEntityInterface {

  /**
   * Get the options for this entity.
   *
   * @return array
   *   An associative array of options.
   */
  public function getOptions();

  /**
   * Set the options for this config entity.
   *
   * @param array $options
   *   An array of options.
   *
   * @return \Drupal\views_save\Entity\SavedViewTypeInterface
   *   The called SavedViewType entity.
   */
  public function setOptions(array $options);

}

Then I added a property to the SavedViewType class, along with some getters and setters:

class SavedViewType extends ConfigEntityBundleBase implements SavedViewTypeInterface {

  /**
   * The options for the Saved View.
   *
   * @var array
   */
  protected $options;

  /**
   * {@inheritdoc}
   */
  public function getOptions() {
    return $this->options;
  }

  /**
   * {@inheritdoc}
   */
  public function setOptions(array $options) {
    $this->options = $options;
    return $this;
  }

}

Finally, I added some elements to the entity form.

class SavedViewTypeForm extends EntityForm {

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {

    // <snip>

    /** @var \Drupal\views_save\Entity\SavedViewType $saved_view_type */
    $saved_view_type = $this->entity;
    $options = $saved_view_type->getOptions();

    $form['options'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Options'),
    ];

    $form['options']['published'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Published by default'),
      '#description' => $this->t('If enabled, saved views of this type will be published by default.'),
      '#default_value' => !empty($options['published']),
    ];

    return $form;
  }
}

When I tried to create some Saved View Types through the UI, though, the value for the 'published' property wasn't being saved.

It turns it I should have defined the property in the configuration schema!

In /config/schema/entity_type.schema.inc:

views_save.saved_view_type.*:
  type: config_entity
  label: 'Saved View type config'
  mapping:
    id:
      type: string
      label: 'ID'
    label:
      type: label
      label: 'Label'
    options:
      type: mapping
        label: 'Options'
        mapping:
          published:
            type: boolean
            label: 'Published'
    uuid:
      type: string

The Saved View Type then saved correctly.

The moral of the story is: don't forget the schema!