Commit 19006b5e authored by catch's avatar catch

Issue #2625212 by faline, cilefen, okay19, krishnan.n, snehi, kostyashupenko,...

Issue #2625212 by faline, cilefen, okay19, krishnan.n, snehi, kostyashupenko, tstoeckler, dawehner, alexpott, Wim Leers, cs_shadow: Add ConfigSchemaChecker to development.services.yml
parent 9d155a2a
<?php
namespace Drupal\Core\Config\Development;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigEvents;
use Drupal\Core\Config\Schema\SchemaCheckTrait;
use Drupal\Core\Config\Schema\SchemaIncompleteException;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Listens to the config save event and validates schema.
*
* If tests have the $strictConfigSchema property set to TRUE this event
* listener will be added to the container and throw exceptions if configuration
* is invalid.
*
* @see \Drupal\KernelTests\KernelTestBase::register()
* @see \Drupal\simpletest\WebTestBase::setUp()
* @see \Drupal\simpletest\KernelTestBase::containerBuild()
*/
class ConfigSchemaChecker implements EventSubscriberInterface {
use SchemaCheckTrait;
/**
* The typed config manger.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedManager;
/**
* An array of config checked already. Keyed by config name and a checksum.
*
* @var array
*/
protected $checked = array();
/**
* An array of config object names that are excluded from schema checking.
*
* @var string[]
*/
protected $exclude = array();
/**
* Constructs the ConfigSchemaChecker object.
*
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_manager
* The typed config manager.
* @param string[] $exclude
* An array of config object names that are excluded from schema checking.
*/
public function __construct(TypedConfigManagerInterface $typed_manager, array $exclude = array()) {
$this->typedManager = $typed_manager;
$this->exclude = $exclude;
}
/**
* Checks that configuration complies with its schema on config save.
*
* @param \Drupal\Core\Config\ConfigCrudEvent $event
* The configuration event.
*
* @throws \Drupal\Core\Config\Schema\SchemaIncompleteException
* Exception thrown when configuration does not match its schema.
*/
public function onConfigSave(ConfigCrudEvent $event) {
// Only validate configuration if in the default collection. Other
// collections may have incomplete configuration (for example language
// overrides only). These are not valid in themselves.
$saved_config = $event->getConfig();
if ($saved_config->getStorage()->getCollectionName() != StorageInterface::DEFAULT_COLLECTION) {
return;
}
$name = $saved_config->getName();
$data = $saved_config->get();
$checksum = hash('crc32b', serialize($data));
if (!in_array($name, $this->exclude) && !isset($this->checked[$name . ':' . $checksum])) {
$this->checked[$name . ':' . $checksum] = TRUE;
$errors = $this->checkConfigSchema($this->typedManager, $name, $data);
if ($errors === FALSE) {
throw new SchemaIncompleteException("No schema for $name");
}
elseif (is_array($errors)) {
$text_errors = [];
foreach ($errors as $key => $error) {
$text_errors[] = SafeMarkup::format('@key @error', array('@key' => $key, '@error' => $error));
}
throw new SchemaIncompleteException("Schema errors for $name with the following errors: " . implode(', ', $text_errors));
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = array('onConfigSave', 255);
return $events;
}
}
......@@ -2,14 +2,7 @@
namespace Drupal\Core\Config\Testing;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigEvents;
use Drupal\Core\Config\Schema\SchemaCheckTrait;
use Drupal\Core\Config\Schema\SchemaIncompleteException;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\Core\Config\Development\ConfigSchemaChecker as SchemaChecker;
/**
* Listens to the config save event and validates schema.
......@@ -18,89 +11,12 @@
* listener will be added to the container and throw exceptions if configuration
* is invalid.
*
* @see \Drupal\simpletest\WebTestBase::setUp()
* @see \Drupal\KernelTests\KernelTestBase::register()
* @see \Drupal\simpletest\WebTestBase::setUp()
* @see \Drupal\simpletest\KernelTestBase::containerBuild()
*
* @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0.
* Use Drupal\Core\Config\Development\ConfigSchemaChecker.
*/
class ConfigSchemaChecker implements EventSubscriberInterface {
use SchemaCheckTrait;
/**
* The typed config manger.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedManager;
/**
* An array of config checked already. Keyed by config name and a checksum.
*
* @var array
*/
protected $checked = array();
/**
* An array of config object names that are excluded from schema checking.
*
* @var string[]
*/
protected $exclude = array();
/**
* Constructs the ConfigSchemaChecker object.
*
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_manager
* The typed config manager.
* @param string[] $exclude
* An array of config object names that are excluded from schema checking.
*/
public function __construct(TypedConfigManagerInterface $typed_manager, array $exclude = array()) {
$this->typedManager = $typed_manager;
$this->exclude = $exclude;
}
/**
* Checks that configuration complies with its schema on config save.
*
* @param \Drupal\Core\Config\ConfigCrudEvent $event
* The configuration event.
*
* @throws \Drupal\Core\Config\Schema\SchemaIncompleteException
* Exception thrown when configuration does not match its schema.
*/
public function onConfigSave(ConfigCrudEvent $event) {
// Only validate configuration if in the default collection. Other
// collections may have incomplete configuration (for example language
// overrides only). These are not valid in themselves.
$saved_config = $event->getConfig();
if ($saved_config->getStorage()->getCollectionName() != StorageInterface::DEFAULT_COLLECTION) {
return;
}
$name = $saved_config->getName();
$data = $saved_config->get();
$checksum = hash('crc32b', serialize($data));
if (!in_array($name, $this->exclude) && !isset($this->checked[$name . ':' . $checksum])) {
$this->checked[$name . ':' . $checksum] = TRUE;
$errors = $this->checkConfigSchema($this->typedManager, $name, $data);
if ($errors === FALSE) {
throw new SchemaIncompleteException("No schema for $name");
}
elseif (is_array($errors)) {
$text_errors = [];
foreach ($errors as $key => $error) {
$text_errors[] = SafeMarkup::format('@key @error', array('@key' => $key, '@error' => $error));
}
throw new SchemaIncompleteException("Schema errors for $name with the following errors: " . implode(', ', $text_errors));
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = array('onConfigSave', 255);
return $events;
}
class ConfigSchemaChecker extends SchemaChecker {
}
......@@ -18,7 +18,7 @@ class SchemaConfigListenerWebTest extends WebTestBase {
public static $modules = array('config_test');
/**
* Tests \Drupal\Core\Config\Testing\ConfigSchemaChecker.
* Tests \Drupal\Core\Config\Development\ConfigSchemaChecker.
*/
public function testConfigSchemaChecker() {
$this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
......
......@@ -8,7 +8,7 @@
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Controller for testing \Drupal\Core\Config\Testing\ConfigSchemaChecker.
* Controller for testing \Drupal\Core\Config\Development\ConfigSchemaChecker.
*/
class SchemaListenerController extends ControllerBase {
......
......@@ -5,6 +5,7 @@
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Variable;
use Drupal\Core\Config\Development\ConfigSchemaChecker;
use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DrupalKernel;
......@@ -321,7 +322,7 @@ public function containerBuild(ContainerBuilder $container) {
if ($this->strictConfigSchema) {
$container
->register('simpletest.config_schema_checker', 'Drupal\Core\Config\Testing\ConfigSchemaChecker')
->register('simpletest.config_schema_checker', ConfigSchemaChecker::class)
->addArgument(new Reference('config.typed'))
->addArgument($this->getConfigSchemaExclusions())
->addTag('event_subscriber');
......
......@@ -288,7 +288,7 @@ abstract class TestBase {
/**
* Set to TRUE to strict check all configuration saved.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
*
* @var bool
*/
......
......@@ -9,6 +9,7 @@
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Development\ConfigSchemaChecker;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Database\Database;
use Drupal\Core\DrupalKernel;
......@@ -547,7 +548,7 @@ protected function prepareSettings() {
$content = file_get_contents($directory . '/services.yml');
$services = $yaml->parse($content);
$services['services']['simpletest.config_schema_checker'] = [
'class' => 'Drupal\Core\Config\Testing\ConfigSchemaChecker',
'class' => ConfigSchemaChecker::class,
'arguments' => ['@config.typed', $this->getConfigSchemaExclusions()],
'tags' => [['name' => 'event_subscriber']]
];
......
......@@ -21,7 +21,7 @@ class ConfigCRUDTest extends KernelTestBase {
/**
* Exempt from strict schema checking.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
*
* @var bool
*/
......
......@@ -14,7 +14,7 @@ class ConfigEntityUnitTest extends KernelTestBase {
/**
* Exempt from strict schema checking.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
*
* @var bool
*/
......
......@@ -15,7 +15,7 @@ class ConfigFileContentTest extends KernelTestBase {
/**
* Exempt from strict schema checking.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
*
* @var bool
*/
......
......@@ -7,6 +7,7 @@
use Drupal\Component\FileCache\FileCacheFactory;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Config\Development\ConfigSchemaChecker;
use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
......@@ -181,7 +182,7 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser
/**
* Set to TRUE to strict check all configuration saved.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
*
* @var bool
*/
......@@ -608,7 +609,7 @@ public function register(ContainerBuilder $container) {
if ($this->strictConfigSchema) {
$container
->register('simpletest.config_schema_checker', 'Drupal\Core\Config\Testing\ConfigSchemaChecker')
->register('simpletest.config_schema_checker', ConfigSchemaChecker::class)
->addArgument(new Reference('config.typed'))
->addArgument($this->getConfigSchemaExclusions())
->addTag('event_subscriber');
......
......@@ -13,7 +13,7 @@
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Testing\ConfigSchemaChecker;
use Drupal\Core\Config\Development\ConfigSchemaChecker;
use Drupal\Core\Database\Database;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Serialization\Yaml;
......@@ -163,7 +163,7 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
/**
* Set to TRUE to strict check all configuration saved.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
*
* @var bool
*/
......
......@@ -10,7 +10,7 @@
trait SchemaConfigListenerTestTrait {
/**
* Tests \Drupal\Core\Config\Testing\ConfigSchemaChecker.
* Tests \Drupal\Core\Config\Development\ConfigSchemaChecker.
*/
public function testConfigSchemaChecker() {
// Test a non-existing schema.
......
......@@ -7,3 +7,8 @@ parameters:
services:
cache.backend.null:
class: Drupal\Core\Cache\NullBackendFactory
config.schema_checker:
class: Drupal\Core\Config\Development\ConfigSchemaChecker
arguments: ['@config.typed']
tags:
- { name: event_subscriber }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment