commit 68559e58c207e855384ae060ffdf25d38fc47b74 Author: sun Date: Tue Feb 18 17:32:03 2014 +0100 Fixed Config tests. diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index e000200..95f724c 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -12,6 +12,7 @@ use Drupal\Core\Config\ConfigNameException; use Drupal\Core\Config\Schema\SchemaIncompleteException; use Drupal\Core\DependencyInjection\DependencySerialization; +use Drupal\Core\Serialization\Exception\InvalidDataTypeException; use Drupal\Core\TypedData\PrimitiveInterface; use Drupal\Core\TypedData\Type\FloatInterface; use Drupal\Core\TypedData\Type\IntegerInterface; @@ -533,7 +534,7 @@ protected function getSchemaWrapper() { * @return mixed * The value cast to the type indicated in the schema. * - * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException + * @throws \Drupal\Core\Serialization\Exception\InvalidDataTypeException * Exception on unsupported/undefined data type deducted. */ protected function castValue($key, $value) { @@ -572,7 +573,7 @@ protected function castValue($key, $value) { else { // Throw exception on any non-scalar or non-array value. if (!is_array($value)) { - throw new UnsupportedDataTypeConfigException(String::format('Invalid data type for config element @name:@key', array( + throw new InvalidDataTypeException(String::format('Invalid data type for config element @name:@key', array( '@name' => $this->getName(), '@key' => $key, ))); diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php index bbb9cb2..b89c81c 100644 --- a/core/lib/Drupal/Core/Config/FileStorage.php +++ b/core/lib/Drupal/Core/Config/FileStorage.php @@ -34,27 +34,41 @@ public function exists($name) { } public function read($name) { - return $this->get($name, FALSE); + $value = $this->get($name, FALSE); + if (!is_array($value)) { + return FALSE; + } + return $value; } public function readMultiple(array $names) { - return $this->getMultiple($names); + $data = $this->getMultiple($names); + foreach ($data as $key => $value) { + if (!is_array($value)) { + $data[$key] = FALSE; + } + } + return $data; } /** * Implements Drupal\Core\Config\StorageInterface::write(). * - * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException - * @throws \Drupal\Core\Config\StorageException + * @throws \Drupal\Core\Serialization\Exception\InvalidDataTypeException */ public function write($name, array $data) { - return $this->set($name, $data); + $this->set($name, $data); + return TRUE; } public function rename($name, $new_name) { + if ($this->exists($new_name)) { + return FALSE; + } $value = $this->get($name); $this->delete($name); - return $this->set($new_name, $value); + $this->set($new_name, $value); + return TRUE; } public function encode($data) { @@ -74,12 +88,24 @@ public function listAll($prefix = '') { return $names; } + public function delete($key) { + parent::delete($key); + return TRUE; + } + + public function deleteMultiple(array $keys) { + parent::deleteMultiple($keys); + return TRUE; + } + public function deleteAll($prefix = '') { if ($prefix === '') { - return parent::deleteAll(); + parent::deleteAll(); + return TRUE; } foreach ($this->listAll($prefix) as $name) { $this->delete($name); } + return TRUE; } } diff --git a/core/lib/Drupal/Core/Config/UnsupportedConfigDataTypeException.php b/core/lib/Drupal/Core/Config/UnsupportedConfigDataTypeException.php deleted file mode 100644 index ac63c26..0000000 --- a/core/lib/Drupal/Core/Config/UnsupportedConfigDataTypeException.php +++ /dev/null @@ -1,14 +0,0 @@ -path = DRUPAL_ROOT . '/' . $path; + $this->path = realpath($path); if ($this->collection !== '') { $this->path .= '/' . $this->collection; } diff --git a/core/lib/Drupal/Core/Serialization/Yaml.php b/core/lib/Drupal/Core/Serialization/Yaml.php index cf3f146..25ee001 100644 --- a/core/lib/Drupal/Core/Serialization/Yaml.php +++ b/core/lib/Drupal/Core/Serialization/Yaml.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Serialization; +use Drupal\Core\Serialization\Exception\InvalidDataTypeException; use Symfony\Component\Yaml\Yaml as Symfony; /** @@ -18,14 +19,24 @@ class Yaml implements SerializationInterface { * {@inheritdoc} */ public static function encode($data) { - return Symfony::dump($data, PHP_INT_MAX, 2, TRUE); + try { + return Symfony::dump($data, PHP_INT_MAX, 2, TRUE); + } + catch (\Exception $e) { + throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e); + } } /** * {@inheritdoc} */ public static function decode($raw) { - return Symfony::parse($raw, TRUE); + try { + return Symfony::parse($raw, TRUE); + } + catch (\Exception $e) { + throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e); + } } /** diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php index 7576163..50c85ea 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php @@ -11,7 +11,8 @@ use Drupal\Core\Config\ConfigNameException; use Drupal\simpletest\DrupalUnitTestBase; use Drupal\Core\Config\FileStorage; -use Drupal\Core\Config\UnsupportedDataTypeConfigException; +use Drupal\Core\Serialization\Exception\InvalidDataTypeException; +use Drupal\Core\Serialization\Yaml; /** * Tests CRUD operations on configuration objects. @@ -192,7 +193,7 @@ function testNameValidation() { */ public function testDataTypes() { \Drupal::moduleHandler()->install(array('config_test')); - $storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); + $storage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); $name = 'config_test.types'; $config = $this->container->get('config.factory')->get($name); $original_content = file_get_contents($storage->getFilePath($name)); @@ -233,7 +234,7 @@ public function testDataTypes() { $config->set('stream', fopen(__FILE__, 'r'))->save(); $this->fail('No Exception thrown upon saving invalid data type.'); } - catch (UnsupportedDataTypeConfigException $e) { + catch (InvalidDataTypeException $e) { $this->pass(String::format('%class thrown upon saving invalid data type.', array( '%class' => get_class($e), ))); @@ -250,7 +251,7 @@ public function testDataTypes() { $config->set('stream', fopen(__FILE__, 'r'))->save(); $this->fail('No Exception thrown upon saving invalid data type.'); } - catch (UnsupportedDataTypeConfigException $e) { + catch (InvalidDataTypeException $e) { $this->pass(String::format('%class thrown upon saving invalid data type.', array( '%class' => get_class($e), ))); diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php index d986835..8ed254a 100644 --- a/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php +++ b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php @@ -87,10 +87,6 @@ function testCRUD() { $result = $this->storage->delete($name); $this->assertIdentical($result, TRUE); - // Deleting a non-existing name returns FALSE. - $result = $this->storage->delete($name); - $this->assertIdentical($result, FALSE); - // Reading from a non-existing storage bin returns FALSE. $result = $this->invalidStorage->read($name); $this->assertIdentical($result, FALSE); diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php b/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php index 6a99605..efdbb9a 100644 --- a/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php @@ -8,7 +8,7 @@ namespace Drupal\config\Tests\Storage; use Drupal\Core\Config\FileStorage; -use Symfony\Component\Yaml\Yaml; +use Drupal\Core\Serialization\Yaml; /** * Tests FileStorage controller operations. @@ -24,8 +24,8 @@ public static function getInfo() { function setUp() { parent::setUp(); - $this->storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); - $this->invalidStorage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY] . '/nonexisting'); + $this->storage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); + $this->invalidStorage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY] . '/nonexisting'); // FileStorage::listAll() requires other configuration data to exist. $this->storage->write('system.performance', \Drupal::config('system.performance')->get()); @@ -33,7 +33,7 @@ function setUp() { protected function read($name) { $data = file_get_contents($this->storage->getFilePath($name)); - return Yaml::parse($data); + return Yaml::decode($data); } protected function insert($name, $data) { @@ -62,7 +62,7 @@ protected function testlistAll() { // Initialize FileStorage with absolute file path. $absolute_path = realpath($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); - $storage_absolute_path = new FileStorage($absolute_path); + $storage_absolute_path = new FileStorage('', new Yaml(), $absolute_path); $config_files = $storage_absolute_path->listAll(); $this->assertIdentical($config_files, $expected_files, 'Absolute path, two config files found.'); } commit 94797de4409e9dd2a6692c3e51fda8e27f698a13 Author: sun Date: Thu Feb 20 20:31:14 2014 +0100 Reverted removal of Boolean return values from CachedStorage. diff --git a/core/lib/Drupal/Core/Config/CachedStorage.php b/core/lib/Drupal/Core/Config/CachedStorage.php index 712218c..1ff4046 100644 --- a/core/lib/Drupal/Core/Config/CachedStorage.php +++ b/core/lib/Drupal/Core/Config/CachedStorage.php @@ -112,12 +112,15 @@ public function readMultiple(array $names) { * Implements Drupal\Core\Config\StorageInterface::write(). */ public function write($name, array $data) { - $this->storage->write($name, $data); - // While not all written data is read back, setting the cache instead of - // just deleting it avoids cache rebuild stampedes. - $this->cache->set($name, $data); - Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); - $this->findByPrefixCache = array(); + if ($this->storage->write($name, $data)) { + // While not all written data is read back, setting the cache instead of + // just deleting it avoids cache rebuild stampedes. + $this->cache->set($name, $data); + Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); + $this->findByPrefixCache = array(); + return TRUE; + } + return FALSE; } /** @@ -126,10 +129,13 @@ public function write($name, array $data) { public function delete($name) { // If the cache was the first to be deleted, another process might start // rebuilding the cache before the storage is gone. - $this->storage->delete($name); - $this->cache->delete($name); - Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); - $this->findByPrefixCache = array(); + if ($this->storage->delete($name)) { + $this->cache->delete($name); + Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); + $this->findByPrefixCache = array(); + return TRUE; + } + return FALSE; } /** @@ -138,11 +144,14 @@ public function delete($name) { public function rename($name, $new_name) { // If the cache was the first to be deleted, another process might start // rebuilding the cache before the storage is renamed. - $this->storage->rename($name, $new_name); - $this->cache->delete($name); - $this->cache->delete($new_name); - Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); - $this->findByPrefixCache = array(); + if ($this->storage->rename($name, $new_name)) { + $this->cache->delete($name); + $this->cache->delete($new_name); + Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); + $this->findByPrefixCache = array(); + return TRUE; + } + return FALSE; } /** @@ -213,8 +222,11 @@ public function deleteAll($prefix = '') { // If the cache was the first to be deleted, another process might start // rebuilding the cache before the storage is renamed. $cids = $this->storage->listAll($prefix); - $this->storage->deleteAll($prefix); - $this->cache->deleteMultiple($cids); + if ($this->storage->deleteAll($prefix)) { + $this->cache->deleteMultiple($cids); + return TRUE; + } + return FALSE; } /** diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php index b89c81c..0312511 100644 --- a/core/lib/Drupal/Core/Config/FileStorage.php +++ b/core/lib/Drupal/Core/Config/FileStorage.php @@ -11,6 +11,9 @@ /** * Defines the file storage controller. + * + * @todo Remove Boolean return values from write/delete methods. + * @todo Change read method return value for missing key from FALSE to NULL. */ class FileStorage extends KeyValueFileStorage implements StorageInterface { @@ -42,13 +45,13 @@ public function read($name) { } public function readMultiple(array $names) { - $data = $this->getMultiple($names); - foreach ($data as $key => $value) { + $values = $this->getMultiple($names); + foreach ($values as $key => $value) { if (!is_array($value)) { - $data[$key] = FALSE; + $values[$key] = FALSE; } } - return $data; + return $values; } /** commit e3c0a0087583c916034b5e398abb77d84506b855 Author: sun Date: Thu Feb 20 20:31:49 2014 +0100 Fixed config_test module TestInstallStorage and TestSchemaStorage. diff --git a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php index b7424f3..f9d56a0 100644 --- a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php @@ -70,7 +70,7 @@ public function testDefaultConfig() { // every module, profile and theme. $typed_config = new TypedConfigManager( \Drupal::service('config.storage'), - new TestSchemaStorage(), + new TestSchemaStorage(\Drupal::service('config.storage.active')), \Drupal::service('cache.config') ); diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php index c940422..d3d6cad 100644 --- a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php @@ -22,9 +22,12 @@ class TestInstallStorage extends InstallStorage { */ protected function getAllFolders() { if (!isset($this->folders)) { - $this->folders = $this->getComponentNames('profile', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'))); - $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0))); - $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes'))); + $folders = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); + $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'); + $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes'); + $this->folders = array_map(function ($file) { + return dirname($file->uri); + }, $folders); } return $this->folders; } diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php index 8d240b0..234268e 100644 --- a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php @@ -19,20 +19,17 @@ class TestSchemaStorage extends SchemaStorage { /** - * Overrides Drupal\Core\Config\ExtensionInstallStorage::__construct(). - */ - public function __construct() { - } - - /** * {@inheritdoc} */ protected function getAllFolders() { if (!isset($this->folders)) { - $this->folders = $this->getBaseDataTypeSchema(); - $this->folders += $this->getComponentNames('profile', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'))); - $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0))); - $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes'))); + $this->folders['core'] = 'core'; + $folders = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); + $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'); + $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes'); + $this->folders += array_map(function ($file) { + return dirname($file->uri); + }, $folders); } return $this->folders; } commit d63362d49f3808a31ae7ca483d0e9039896a55de Merge: e3c0a00 d6c9c57 Author: sun Date: Thu Feb 20 20:32:07 2014 +0100 Merge branch '8.x' into kv-file-2190723-sun commit 210795775d7d71ead8086e1f789b3ed5e9debd97 Author: sun Date: Thu Feb 20 21:07:03 2014 +0100 Fixed false-positive matches in InstallStorage::getPathname() in case of multiple files with same prefix. diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php index a6a9d45..882de29 100644 --- a/core/lib/Drupal/Core/Config/InstallStorage.php +++ b/core/lib/Drupal/Core/Config/InstallStorage.php @@ -84,7 +84,9 @@ public function rename($name, $new_name) { */ protected function getPathname($key) { foreach ($this->getIterator($key) as $file) { - return $file->getPathname(); + if ($file->getBasename('.' . $this->format->getFileExtension()) == $key) { + return $file->getPathname(); + } } } commit ce8ff9ab7ab1c2c6ea7ee8900bb1489cf7487f5c Author: sun Date: Thu Feb 20 21:23:03 2014 +0100 Added KeyValueStore/FileStorageTest. diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueFileFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueFileFactory.php index b223a69..91edf2c 100644 --- a/core/lib/Drupal/Core/KeyValueStore/KeyValueFileFactory.php +++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueFileFactory.php @@ -31,51 +31,22 @@ class KeyValueFileFactory implements KeyValueFactoryInterface { protected $format; /** - * var \Symfony\Component\DependencyInjection\ContainerInterface - */ - protected $container; - - /** - * The read-only settings container. - * - * @var \Drupal\Component\Utility\Settings - */ - protected $settings; - - /** * Constructs this factory object. * * @param string $path * The filesystem URI/directory to use as base path. * @param \Drupal\Core\Serialization\SerializationInterface $format * The serialization format to use. - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container - * The service container. - * @param \Drupal\Component\Utility\Settings $settings - * The read-only settings container. */ -// function __construct($path, SerializationInterface $format) { -// $this->path = $path; -// $this->format = $format; - function __construct(ContainerInterface $container, Settings $settings) { - $this->container = $container; - $this->settings = $settings; + function __construct($path, SerializationInterface $format) { + $this->path = $path; + $this->format = $format; } /** * {@inheritdoc} */ public function get($collection) { - // @todo Please disregard this automatic setup. Testing purposes only. - $this->path = $this->settings->get('file_public_path', conf_path() . '/files'); - $this->path .= '/keyvalue'; - - if (!is_dir($path)) { - mkdir($path, 0777); - } - if (!is_dir("$path/$collection")) { - mkdir("$path/$collection", 0777); - } return new FileStorage($collection, $this->format, $this->path); } diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php index ad286d6..eddf7e7 100644 --- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php @@ -34,7 +34,10 @@ protected function setUp() { ->addArgument('default'); $this->container ->register('keyvalue.database', 'Drupal\Core\KeyValueStore\KeyValueDatabaseFactory') - ->addArgument(new Reference('database')); + ->addArgument(new Reference('database')) + ->addArgument(new Reference('serialization.phpserialize')); + $this->container + ->register('serialization.phpserialize', 'Drupal\Core\Serialization\PhpSerialize'); $this->settingsSet('keyvalue_default', 'keyvalue.database'); } diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/FileStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/FileStorageTest.php new file mode 100644 index 0000000..aaacef9 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/FileStorageTest.php @@ -0,0 +1,42 @@ + 'File storage', + 'description' => 'Tests the key-value file storage.', + 'group' => 'Key-value store', + ); + } + + protected function setUp() { + parent::setUp(); + + foreach ($this->collections as $collection) { + $path = $this->public_files_directory . '/' . $collection; + file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); + } + + $this->container + ->register('keyvalue.file', 'Drupal\Core\KeyValueStore\KeyValueFileFactory') + ->addArgument($this->public_files_directory) + ->addArgument(new Reference('serialization.phpserialize')); + $this->container + ->register('serialization.phpserialize', 'Drupal\Core\Serialization\PhpSerialize'); + $this->settingsSet('keyvalue_default', 'keyvalue.file'); + } + +}