Issue #2264179 by Gábor Hojtsy, vijaycs85, alexpott, benjy: Clarify use of property/undefined and add an ignore type in configuration schema.
parent
51edc990be
commit
4451ee6a80
|
@ -1,3 +1,23 @@
|
||||||
|
# Base types provided by Drupal core.
|
||||||
|
|
||||||
|
# Read https://drupal.org/node/1905070 for more details about configuration
|
||||||
|
# schema, types and type resolution.
|
||||||
|
|
||||||
|
# Undefined type used by the system to assign to elements at any level where
|
||||||
|
# configuration schema is not defined. Using explicitly has the same effect as
|
||||||
|
# not defining schema, so there is no point in doing that.
|
||||||
|
undefined:
|
||||||
|
label: 'Undefined'
|
||||||
|
class: '\Drupal\Core\Config\Schema\Undefined'
|
||||||
|
|
||||||
|
# Explicit type to use when no data typing is possible. Instead of using this
|
||||||
|
# type, we strongly suggest you use configuration structures that can be
|
||||||
|
# described with other structural elements of schema, and describe your schema
|
||||||
|
# with those elements.
|
||||||
|
ignore:
|
||||||
|
label: 'Ignore'
|
||||||
|
class: '\Drupal\Core\Config\Schema\Ignore'
|
||||||
|
|
||||||
# Basic scalar data types from typed data.
|
# Basic scalar data types from typed data.
|
||||||
boolean:
|
boolean:
|
||||||
label: 'Boolean'
|
label: 'Boolean'
|
||||||
|
@ -18,10 +38,7 @@ uri:
|
||||||
label: 'Uri'
|
label: 'Uri'
|
||||||
class: '\Drupal\Core\TypedData\Plugin\DataType\Uri'
|
class: '\Drupal\Core\TypedData\Plugin\DataType\Uri'
|
||||||
|
|
||||||
# Basic data types for configuration.
|
# Container data types for lists with known and unknown keys.
|
||||||
undefined:
|
|
||||||
label: 'Undefined'
|
|
||||||
class: '\Drupal\Core\Config\Schema\Property'
|
|
||||||
mapping:
|
mapping:
|
||||||
label: Mapping
|
label: Mapping
|
||||||
class: '\Drupal\Core\Config\Schema\Mapping'
|
class: '\Drupal\Core\Config\Schema\Mapping'
|
||||||
|
@ -29,11 +46,6 @@ sequence:
|
||||||
label: Sequence
|
label: Sequence
|
||||||
class: '\Drupal\Core\Config\Schema\Sequence'
|
class: '\Drupal\Core\Config\Schema\Sequence'
|
||||||
|
|
||||||
# Default mapping for unknown types or types not found.
|
|
||||||
default:
|
|
||||||
type: undefined
|
|
||||||
label: 'Unknown'
|
|
||||||
|
|
||||||
# Simple extended data types:
|
# Simple extended data types:
|
||||||
|
|
||||||
# Human readable string that must be plain text and editable with a text field.
|
# Human readable string that must be plain text and editable with a text field.
|
||||||
|
@ -59,6 +71,11 @@ date_format:
|
||||||
label: 'PHP date format'
|
label: 'PHP date format'
|
||||||
translatable: true
|
translatable: true
|
||||||
|
|
||||||
|
# HTML color value.
|
||||||
|
color_hex:
|
||||||
|
type: string
|
||||||
|
label: 'Color'
|
||||||
|
|
||||||
# Complex extended data types:
|
# Complex extended data types:
|
||||||
|
|
||||||
# Mail text with subject and body parts.
|
# Mail text with subject and body parts.
|
||||||
|
@ -194,11 +211,6 @@ route:
|
||||||
- type: string
|
- type: string
|
||||||
label: 'Param'
|
label: 'Param'
|
||||||
|
|
||||||
# HTML color value.
|
|
||||||
color_hex:
|
|
||||||
type: string
|
|
||||||
label: 'Color'
|
|
||||||
|
|
||||||
# Config dependencies.
|
# Config dependencies.
|
||||||
config_dependencies:
|
config_dependencies:
|
||||||
type: mapping
|
type: mapping
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\Config\Schema\Ignore.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\Config\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration property to ignore.
|
||||||
|
*/
|
||||||
|
class Ignore extends Element {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}.
|
||||||
|
*/
|
||||||
|
public function validate() {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Contains \Drupal\Core\Config\Schema\Sequence.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Drupal\Core\Config\Schema;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic configuration property.
|
|
||||||
*/
|
|
||||||
class Property extends Element {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements TypedDataInterface::validate().
|
|
||||||
*/
|
|
||||||
public function validate() {
|
|
||||||
return isset($this->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\Config\Schema\Undefined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\Config\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undefined configuration element.
|
||||||
|
*/
|
||||||
|
class Undefined extends Element {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}.
|
||||||
|
*/
|
||||||
|
public function validate() {
|
||||||
|
return isset($this->value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,10 +8,12 @@
|
||||||
namespace Drupal\Core\Config;
|
namespace Drupal\Core\Config;
|
||||||
|
|
||||||
use Drupal\Component\Utility\String;
|
use Drupal\Component\Utility\String;
|
||||||
|
use Drupal\Core\Config\Schema\Ignore;
|
||||||
use Drupal\Core\Config\Schema\SchemaIncompleteException;
|
use Drupal\Core\Config\Schema\SchemaIncompleteException;
|
||||||
use Drupal\Core\TypedData\PrimitiveInterface;
|
use Drupal\Core\TypedData\PrimitiveInterface;
|
||||||
use Drupal\Core\TypedData\Type\FloatInterface;
|
use Drupal\Core\TypedData\Type\FloatInterface;
|
||||||
use Drupal\Core\TypedData\Type\IntegerInterface;
|
use Drupal\Core\TypedData\Type\IntegerInterface;
|
||||||
|
use Drupal\Core\Config\Schema\Undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a base class for configuration objects with storage support.
|
* Provides a base class for configuration objects with storage support.
|
||||||
|
@ -167,37 +169,36 @@ abstract class StorableConfigBase extends ConfigBase {
|
||||||
* Exception on unsupported/undefined data type deducted.
|
* Exception on unsupported/undefined data type deducted.
|
||||||
*/
|
*/
|
||||||
protected function castValue($key, $value) {
|
protected function castValue($key, $value) {
|
||||||
if ($value === NULL) {
|
$element = FALSE;
|
||||||
$value = NULL;
|
try {
|
||||||
|
$element = $this->getSchemaWrapper()->get($key);
|
||||||
}
|
}
|
||||||
elseif (is_scalar($value)) {
|
catch (SchemaIncompleteException $e) {
|
||||||
try {
|
// @todo Consider making schema handling more strict by throwing
|
||||||
$element = $this->getSchemaWrapper()->get($key);
|
// SchemaIncompleteException for all incomplete schema conditions *and*
|
||||||
if ($element instanceof PrimitiveInterface) {
|
// throwing it forward. See https://drupal.org/node/2183983.
|
||||||
// Special handling for integers and floats since the configuration
|
// Until then, we need to handle the Undefined case below.
|
||||||
// system is primarily concerned with saving values from the Form API
|
}
|
||||||
// we have to special case the meaning of an empty string for numeric
|
// Do not cast value if it is unknown or defined to be ignored.
|
||||||
// types. In PHP this would be casted to a 0 but for the purposes of
|
if ($element && ($element instanceof Undefined || $element instanceof Ignore)) {
|
||||||
// configuration we need to treat this as a NULL.
|
return $value;
|
||||||
if ($value === '' && ($element instanceof IntegerInterface || $element instanceof FloatInterface)) {
|
}
|
||||||
$value = NULL;
|
if ((is_scalar($value) || $value === NULL)) {
|
||||||
}
|
if ($element && $element instanceof PrimitiveInterface) {
|
||||||
else {
|
// Special handling for integers and floats since the configuration
|
||||||
$value = $element->getCastedValue();
|
// system is primarily concerned with saving values from the Form API
|
||||||
}
|
// we have to special case the meaning of an empty string for numeric
|
||||||
|
// types. In PHP this would be casted to a 0 but for the purposes of
|
||||||
|
// configuration we need to treat this as a NULL.
|
||||||
|
$empty_value = $value === '' && ($element instanceof IntegerInterface || $element instanceof FloatInterface);
|
||||||
|
|
||||||
|
if ($value === NULL || $empty_value) {
|
||||||
|
$value = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Config only supports primitive data types. If the config schema
|
$value = $element->getCastedValue();
|
||||||
// does define a type $element will be an instance of
|
|
||||||
// \Drupal\Core\Config\Schema\Property. Convert it to string since it
|
|
||||||
// is the safest possible type.
|
|
||||||
$value = $element->getString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SchemaIncompleteException $e) {
|
|
||||||
// @todo throw an exception due to an incomplete schema.
|
|
||||||
// Fix as part of https://drupal.org/node/2183983.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Throw exception on any non-scalar or non-array value.
|
// Throw exception on any non-scalar or non-array value.
|
||||||
|
|
|
@ -152,9 +152,8 @@ class TypedConfigManager extends PluginManagerBase implements TypedConfigManager
|
||||||
$type = $name;
|
$type = $name;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If we don't have definition, return the 'default' element.
|
// If we don't have definition, return the 'undefined' element.
|
||||||
// This should map to 'undefined' type by default, unless overridden.
|
$type = 'undefined';
|
||||||
$type = 'default';
|
|
||||||
}
|
}
|
||||||
$definition = $definitions[$type];
|
$definition = $definitions[$type];
|
||||||
// Check whether this type is an extension of another one and compile it.
|
// Check whether this type is an extension of another one and compile it.
|
||||||
|
@ -326,10 +325,9 @@ class TypedConfigManager extends PluginManagerBase implements TypedConfigManager
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function hasConfigSchema($name) {
|
public function hasConfigSchema($name) {
|
||||||
// The schema system falls back on the Property class for unknown types.
|
// The schema system falls back on the Undefined class for unknown types.
|
||||||
// See http://drupal.org/node/1905230
|
|
||||||
$definition = $this->getDefinition($name);
|
$definition = $this->getDefinition($name);
|
||||||
return is_array($definition) && ($definition['class'] != '\Drupal\Core\Config\Schema\Property');
|
return is_array($definition) && ($definition['class'] != '\Drupal\Core\Config\Schema\Undefined');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
namespace Drupal\config\Tests;
|
namespace Drupal\config\Tests;
|
||||||
|
|
||||||
|
use Drupal\Core\Config\FileStorage;
|
||||||
|
use Drupal\Core\Config\InstallStorage;
|
||||||
use Drupal\Core\TypedData\Type\IntegerInterface;
|
use Drupal\Core\TypedData\Type\IntegerInterface;
|
||||||
use Drupal\Core\TypedData\Type\StringInterface;
|
use Drupal\Core\TypedData\Type\StringInterface;
|
||||||
use Drupal\simpletest\DrupalUnitTestBase;
|
use Drupal\simpletest\DrupalUnitTestBase;
|
||||||
|
@ -40,15 +42,15 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
|
||||||
* Tests the basic metadata retrieval layer.
|
* Tests the basic metadata retrieval layer.
|
||||||
*/
|
*/
|
||||||
function testSchemaMapping() {
|
function testSchemaMapping() {
|
||||||
// Nonexistent configuration key will have Unknown as metadata.
|
// Nonexistent configuration key will have Undefined as metadata.
|
||||||
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key'));
|
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key'));
|
||||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key');
|
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key');
|
||||||
$expected = array();
|
$expected = array();
|
||||||
$expected['label'] = 'Unknown';
|
$expected['label'] = 'Undefined';
|
||||||
$expected['class'] = '\Drupal\Core\Config\Schema\Property';
|
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
|
||||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.');
|
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.');
|
||||||
|
|
||||||
// Configuration file without schema will return Unknown as well.
|
// Configuration file without schema will return Undefined as well.
|
||||||
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema'));
|
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema'));
|
||||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.noschema');
|
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.noschema');
|
||||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with no schema.');
|
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with no schema.');
|
||||||
|
@ -68,13 +70,13 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
|
||||||
$definition = $config['testitem']->getDataDefinition();
|
$definition = $config['testitem']->getDataDefinition();
|
||||||
$expected = array();
|
$expected = array();
|
||||||
$expected['label'] = 'Test item';
|
$expected['label'] = 'Test item';
|
||||||
$expected['class'] = '\Drupal\Core\Config\Schema\Property';
|
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
|
||||||
$expected['type'] = 'undefined';
|
$expected['type'] = 'undefined';
|
||||||
$this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
|
$this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
|
||||||
$definition = $config['testlist']->getDataDefinition();
|
$definition = $config['testlist']->getDataDefinition();
|
||||||
$expected = array();
|
$expected = array();
|
||||||
$expected['label'] = 'Test list';
|
$expected['label'] = 'Test list';
|
||||||
$expected['class'] = '\Drupal\Core\Config\Schema\Property';
|
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
|
||||||
$expected['type'] = 'undefined';
|
$expected['type'] = 'undefined';
|
||||||
$this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
|
$this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
|
||||||
|
|
||||||
|
@ -93,6 +95,40 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
|
||||||
);
|
);
|
||||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance');
|
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance');
|
||||||
|
|
||||||
|
// Mixed schema with ignore elements.
|
||||||
|
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.ignore');
|
||||||
|
$expected = array();
|
||||||
|
$expected['label'] = 'Ignore test';
|
||||||
|
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||||
|
$expected['mapping']['label'] = array(
|
||||||
|
'label' => 'Label',
|
||||||
|
'type' => 'label',
|
||||||
|
);
|
||||||
|
$expected['mapping']['irrelevant'] = array(
|
||||||
|
'label' => 'Irrelevant',
|
||||||
|
'type' => 'ignore',
|
||||||
|
);
|
||||||
|
$expected['mapping']['indescribable'] = array(
|
||||||
|
'label' => 'Indescribable',
|
||||||
|
'type' => 'ignore',
|
||||||
|
);
|
||||||
|
$expected['mapping']['weight'] = array(
|
||||||
|
'label' => 'Weight',
|
||||||
|
'type' => 'integer',
|
||||||
|
);
|
||||||
|
$this->assertEqual($definition, $expected);
|
||||||
|
|
||||||
|
// The ignore elements themselves.
|
||||||
|
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('irrelevant')->getDataDefinition();
|
||||||
|
$expected = array();
|
||||||
|
$expected['type'] = 'ignore';
|
||||||
|
$expected['label'] = 'Irrelevant';
|
||||||
|
$expected['class'] = '\Drupal\Core\Config\Schema\Ignore';
|
||||||
|
$this->assertEqual($definition, $expected);
|
||||||
|
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition();
|
||||||
|
$expected['label'] = 'Indescribable';
|
||||||
|
$this->assertEqual($definition, $expected);
|
||||||
|
|
||||||
// More complex case, generic type. Metadata for image style.
|
// More complex case, generic type. Metadata for image style.
|
||||||
$definition = \Drupal::service('config.typed')->getDefinition('image.style.large');
|
$definition = \Drupal::service('config.typed')->getDefinition('image.style.large');
|
||||||
$expected = array();
|
$expected = array();
|
||||||
|
@ -138,7 +174,7 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
|
||||||
|
|
||||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium');
|
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium');
|
||||||
|
|
||||||
// More complex, multiple filesystem marker test.
|
// More complex, several level deep test.
|
||||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection');
|
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection');
|
||||||
// This should be the schema of config_schema_test.someschema.somemodule.*.*.
|
// This should be the schema of config_schema_test.someschema.somemodule.*.*.
|
||||||
$expected = array();
|
$expected = array();
|
||||||
|
@ -254,7 +290,7 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
|
||||||
'integer' => '100',
|
'integer' => '100',
|
||||||
'null_integer' => '',
|
'null_integer' => '',
|
||||||
'boolean' => 1,
|
'boolean' => 1,
|
||||||
// If the config schema doesn't have a type it should be casted to string.
|
// If the config schema doesn't have a type it shouldn't be casted.
|
||||||
'no_type' => 1,
|
'no_type' => 1,
|
||||||
'mapping' => array(
|
'mapping' => array(
|
||||||
'string' => 1
|
'string' => 1
|
||||||
|
@ -277,7 +313,7 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
|
||||||
'integer' => 100,
|
'integer' => 100,
|
||||||
'null_integer' => NULL,
|
'null_integer' => NULL,
|
||||||
'boolean' => TRUE,
|
'boolean' => TRUE,
|
||||||
'no_type' => '1',
|
'no_type' => 1,
|
||||||
'mapping' => array(
|
'mapping' => array(
|
||||||
'string' => '1'
|
'string' => '1'
|
||||||
),
|
),
|
||||||
|
@ -300,6 +336,14 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
|
||||||
->setData($untyped_values)
|
->setData($untyped_values)
|
||||||
->save();
|
->save();
|
||||||
$this->assertIdentical(\Drupal::config('config_schema_test.no_schema_data_types')->get(), $untyped_values);
|
$this->assertIdentical(\Drupal::config('config_schema_test.no_schema_data_types')->get(), $untyped_values);
|
||||||
|
|
||||||
|
// Ensure that configuration objects with keys marked as ignored are not
|
||||||
|
// changed when saved. The 'config_schema_test.ignore' will have been saved
|
||||||
|
// during the installation of configuration in the setUp method.
|
||||||
|
$extension_path = drupal_get_path('module', 'config_schema_test');
|
||||||
|
$install_storage = new FileStorage($extension_path . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY);
|
||||||
|
$original_data = $install_storage->read('config_schema_test.ignore');
|
||||||
|
$this->assertIdentical(\Drupal::config('config_schema_test.ignore')->get(), $original_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Drupal\config\Tests;
|
namespace Drupal\config\Tests;
|
||||||
|
|
||||||
use Drupal\Core\Config\Schema\ArrayElement;
|
use Drupal\Core\Config\Schema\ArrayElement;
|
||||||
use Drupal\Core\Config\Schema\Property;
|
|
||||||
use Drupal\Core\Config\TypedConfigManagerInterface;
|
use Drupal\Core\Config\TypedConfigManagerInterface;
|
||||||
use Drupal\Core\TypedData\Type\BooleanInterface;
|
use Drupal\Core\TypedData\Type\BooleanInterface;
|
||||||
use Drupal\Core\TypedData\Type\StringInterface;
|
use Drupal\Core\TypedData\Type\StringInterface;
|
||||||
|
@ -84,36 +83,34 @@ abstract class ConfigSchemaTestBase extends WebTestBase {
|
||||||
* Returns mixed value.
|
* Returns mixed value.
|
||||||
*/
|
*/
|
||||||
protected function checkValue($key, $value) {
|
protected function checkValue($key, $value) {
|
||||||
|
$element = FALSE;
|
||||||
try {
|
try {
|
||||||
$element = $this->schema->get($key);
|
$element = $this->schema->get($key);
|
||||||
}
|
}
|
||||||
catch (SchemaIncompleteException $e) {
|
catch (SchemaIncompleteException $e) {
|
||||||
$this->fail("{$this->configName}:$key has no schema.");
|
if (is_scalar($value) || $value === NULL) {
|
||||||
|
$this->fail("{$this->configName}:$key has no schema.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Do not check value if it is defined to be ignored.
|
||||||
|
if ($element && $element instanceof Ignore) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_scalar($value) || $value === NULL) {
|
if (is_scalar($value) || $value === NULL) {
|
||||||
$success = FALSE;
|
$success = FALSE;
|
||||||
$type = gettype($value);
|
$type = gettype($value);
|
||||||
if ($element instanceof PrimitiveInterface) {
|
if ($element instanceof PrimitiveInterface) {
|
||||||
if ($type == 'integer' && $element instanceof IntegerInterface) {
|
$success =
|
||||||
$success = TRUE;
|
($type == 'integer' && $element instanceof IntegerInterface) ||
|
||||||
}
|
($type == 'double' && $element instanceof FloatInterface) ||
|
||||||
if ($type == 'double' && $element instanceof FloatInterface) {
|
($type == 'boolean' && $element instanceof BooleanInterface) ||
|
||||||
$success = TRUE;
|
($type == 'string' && $element instanceof StringInterface) ||
|
||||||
}
|
// Null values are allowed for all types.
|
||||||
if ($type == 'boolean' && $element instanceof BooleanInterface) {
|
($value === NULL);
|
||||||
$success = TRUE;
|
|
||||||
}
|
|
||||||
if ($type == 'string' && ($element instanceof StringInterface || $element instanceof Property)) {
|
|
||||||
$success = TRUE;
|
|
||||||
}
|
|
||||||
// Null values are allowed for all scalar types.
|
|
||||||
if ($value === NULL) {
|
|
||||||
$success = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$class = get_class($element);
|
||||||
if (!$success) {
|
if (!$success) {
|
||||||
$class = get_class($element);
|
|
||||||
$this->fail("{$this->configName}:$key has the wrong schema. Variable type is $type and schema class is $class.");
|
$this->fail("{$this->configName}:$key has the wrong schema. Variable type is $type and schema class is $class.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
label: 'Label string'
|
||||||
|
irrelevant: 123
|
||||||
|
indescribable:
|
||||||
|
abc: 789
|
||||||
|
def:
|
||||||
|
- 456
|
||||||
|
- 'abc'
|
||||||
|
xyz: 13.4
|
||||||
|
weight: 27
|
|
@ -132,3 +132,20 @@ config_schema_test.schema_in_install:
|
||||||
config_schema_test_integer:
|
config_schema_test_integer:
|
||||||
type: integer
|
type: integer
|
||||||
label: 'Config test integer'
|
label: 'Config test integer'
|
||||||
|
|
||||||
|
config_schema_test.ignore:
|
||||||
|
type: mapping
|
||||||
|
label: 'Ignore test'
|
||||||
|
mapping:
|
||||||
|
label:
|
||||||
|
type: label
|
||||||
|
label: 'Label'
|
||||||
|
irrelevant:
|
||||||
|
type: ignore
|
||||||
|
label: 'Irrelevant'
|
||||||
|
indescribable:
|
||||||
|
type: ignore
|
||||||
|
label: 'Indescribable'
|
||||||
|
weight:
|
||||||
|
type: integer
|
||||||
|
label: 'Weight'
|
||||||
|
|
Loading…
Reference in New Issue