Validating Drupal 8 Config

Validating Drupal 8 Config

Did you know Drupal 8 has a new system to manage config? sure, everyone does by now.
But, did you know you can validate the import of config? Maybe not, that's a bit more of a hidden gem.

If you're writing a module that uses config entities or config for settings, you might want to make sure that the config is valid when imported. This came up recently in the core Content Moderation module. We wanted to make sure that when config for Workflows are imported they don't end up removing moderation states which are in use by other entities. For this we added an event subscriber, ConfigImportSubscriber, which is now part of Drupal 8.4.x.

To add one of these to your modules first you will need to add a service to your modules services.yml file:


content_moderation.config_import_subscriber:
class: Drupal\content_moderation\EventSubscriber\ConfigImportSubscriber
arguments: ['@config.manager', '@entity_type.manager']
tags:
- { name: event_subscriber }

Here you will see, for content moderation, we have the service name, the class, a couple of arguments, and it's tagged as an event subscriber.

You will then need to add you subscriber class within your module add the namespace added in services.yml.

<?php

namespace Drupal\content_moderation\EventSubscriber;

use Drupal\Core\Config\ConfigImporterEvent;
use Drupal\Core\Config\ConfigImportValidateEventSubscriberBase;

/**
* Check moderation states are not being used before updating workflow config.
*/
class ConfigImportSubscriber extends ConfigImportValidateEventSubscriberBase {

/**
* {@inheritdoc}
*/
public function onConfigImporterValidate(ConfigImporterEvent $event) {
if ($this->isWorkflowInUse($event) {
$event->getConfigImporter()->logError($this->t('The workflow @workflow_label is being used, and cannot be deleted.', ['@workflow_label' => $workflow->label()]));
}
}

}

Here, with a lot of the logic removed for simplicity, we're extending ConfigImportValidateEventSubscriberBase, which is the base class for all validation of config at import. Then we override the onConfigImporterValidate() method, which passes in the $event object. From that object we need to determine if the config is valid or not, then log an error if not.

This can also be tested in a kernel test:
$this->config('workflows.workflow.editorial')->get(); will get us the existing config for the editorial workflow entity.
\Drupal::service('config.storage.sync')->write('workflows.workflow.editorial', $config_data); will allow us to update that config.
$this->configImporter()->reset()->import(); will then run an import, imported the updated config. This will need to be wrapped in a try/catch because a failing import will throw an exception. In the catch part of the statement we can pass or fail the test depending on the intended result.

For more information take a look at the full event subscriber: http://cgit.drupalcode.org/drupal/tree/core/modules/content_moderation/…
Also the full test: http://cgit.drupalcode.org/drupal/tree/core/modules/content_moderation/…

timmillwood Sun, 30/07/2017 - 20:10

Add new comment