configName = $config_name; if (!$typed_config->hasConfigSchema($config_name)) { return FALSE; } $this->schema = $typed_config->createFromNameAndData($config_name, $config_data); $errors = []; foreach ($config_data as $key => $value) { $errors = array_merge($errors, $this->checkValue($key, $value)); } if (empty($errors)) { return TRUE; } return $errors; } /** * Helper method to check data type. * * @param string $key * A string of configuration key. * @param mixed $value * Value of given key. * * @return array * List of errors found while checking with the corresponding schema. */ protected function checkValue($key, $value) { $error_key = $this->configName . ':' . $key; $element = $this->schema->get($key); if ($element instanceof Undefined) { return [$error_key => 'missing schema']; } // Do not check value if it is defined to be ignored. if ($element && $element instanceof Ignore) { return []; } if ($element && is_scalar($value) || $value === NULL) { $success = FALSE; $type = gettype($value); if ($element instanceof PrimitiveInterface) { $success = ($type == 'integer' && $element instanceof IntegerInterface) || // Allow integer values in a float field. (($type == 'double' || $type == 'integer') && $element instanceof FloatInterface) || ($type == 'boolean' && $element instanceof BooleanInterface) || ($type == 'string' && $element instanceof StringInterface) || // Null values are allowed for all primitive types. ($value === NULL); } // Array elements can also opt-in for allowing a NULL value. elseif ($element instanceof ArrayElement && $element->isNullable() && $value === NULL) { $success = TRUE; } $class = get_class($element); if (!$success) { return [$error_key => "variable type is $type but applied schema class is $class"]; } } else { $errors = []; if (!$element instanceof TraversableTypedDataInterface) { $errors[$error_key] = 'non-scalar value but not defined as an array (such as mapping or sequence)'; } // Go on processing so we can get errors on all levels. Any non-scalar // value must be an array so cast to an array. if (!is_array($value)) { $value = (array) $value; } // Recurse into any nested keys. foreach ($value as $nested_value_key => $nested_value) { $errors = array_merge($errors, $this->checkValue($key . '.' . $nested_value_key, $nested_value)); } return $errors; } // No errors found. return []; } }