/** * Create test views from config. * * @param string $class * The name of the test class. * @param array $modules * The module directories to look in for test views. */ public static function createTestViews($class, array $modules) { $views = array(); while ($class) { if (property_exists($class, 'testViews')) { $views = array_merge($views, $class::$testViews); } $class = get_parent_class($class); } if (!empty($views)) { $storage = \Drupal::entityManager()->getStorage('view'); $module_handler = \Drupal::moduleHandler(); foreach ($modules as $module) { $config_dir = drupal_get_path('module', $module) . '/test_views'; if (!is_dir($config_dir) || !$module_handler->moduleExists($module)) { continue; } $file_storage = new FileStorage($config_dir); foreach ($file_storage->listAll('views.view.') as $config_name) { $id = str_replace('views.view.', '', $config_name); if (in_array($id, $views)) { $storage->create($file_storage->read($config_name))->save(); } } } } }
/** * Create test views from config. * * @param string $class * The name of the test class. Installs the listed test views *in order*. * @param array $modules * The module directories to look in for test views. */ public static function createTestViews($class, array $modules) { $views = array(); while ($class) { if (property_exists($class, 'testViews')) { $views = array_merge($views, $class::$testViews); } $class = get_parent_class($class); } if (!empty($views)) { $storage = \Drupal::entityManager()->getStorage('view'); $module_handler = \Drupal::moduleHandler(); foreach ($modules as $module) { $config_dir = drupal_get_path('module', $module) . '/test_views'; if (!is_dir($config_dir) || !$module_handler->moduleExists($module)) { continue; } $file_storage = new FileStorage($config_dir); $available_views = $file_storage->listAll('views.view.'); foreach ($views as $id) { $config_name = 'views.view.' . $id; if (in_array($config_name, $available_views)) { $storage->create($file_storage->read($config_name))->save(); } } } } // Rebuild the router once. \Drupal::service('router.builder')->rebuild(); }
/** * Tests install profile config changes. */ function testInstallProfileConfigOverwrite() { $config_name = 'system.cron'; // The expected configuration from the system module. $expected_original_data = array('threshold' => array('autorun' => 0, 'requirements_warning' => 172800, 'requirements_error' => 1209600)); // The expected active configuration altered by the install profile. $expected_profile_data = array('threshold' => array('autorun' => 0, 'requirements_warning' => 259200, 'requirements_error' => 1209600)); // Verify that the original data matches. We have to read the module config // file directly, because the install profile default system.cron.yml // configuration file was used to create the active configuration. $config_dir = drupal_get_path('module', 'system') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY; $this->assertTrue(is_dir($config_dir)); $source_storage = new FileStorage($config_dir); $data = $source_storage->read($config_name); $this->assertIdentical($data, $expected_original_data); // Verify that active configuration matches the expected data, which was // created from the testing install profile's system.cron.yml file. $config = $this->config($config_name); $this->assertIdentical($config->get(), $expected_profile_data); // Ensure that the configuration entity has the expected dependencies and // overrides. $action = Action::load('user_block_user_action'); $this->assertEqual($action->label(), 'Overridden block the selected user(s)'); $action = Action::load('user_cancel_user_action'); $this->assertEqual($action->label(), 'Cancel the selected user account(s)', 'Default configuration that is not overridden is not affected.'); // Ensure that optional configuration can be overridden. $tour = Tour::load('language'); $this->assertEqual(count($tour->getTips()), 1, 'Optional configuration can be overridden. The language tour only has one tip'); $tour = Tour::load('language-add'); $this->assertEqual(count($tour->getTips()), 3, 'Optional configuration that is not overridden is not affected.'); // Ensure that optional configuration from a profile is created if // dependencies are met. $this->assertEqual(Tour::load('testing_config_overrides')->label(), 'Config override test'); // Ensure that optional configuration from a profile is not created if // dependencies are not met. Cannot use the entity system since the entity // type does not exist. $optional_dir = drupal_get_path('module', 'testing_config_overrides') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY; $optional_storage = new FileStorage($optional_dir); foreach (['config_test.dynamic.dotted.default', 'config_test.dynamic.override', 'config_test.dynamic.override_unmet'] as $id) { $this->assertTrue(\Drupal::config($id)->isNew(), "The config_test entity {$id} contained in the profile's optional directory does not exist."); // Make that we don't get false positives from the assertion above. $this->assertTrue($optional_storage->exists($id), "The config_test entity {$id} does exist in the profile's optional directory."); } // Install the config_test module and ensure that the override from the // install profile is not used. Optional configuration can not override // configuration in a modules config/install directory. $this->container->get('module_installer')->install(['config_test']); $this->rebuildContainer(); $config_test_storage = \Drupal::entityManager()->getStorage('config_test'); $this->assertEqual($config_test_storage->load('dotted.default')->label(), 'Default', 'The config_test entity is not overridden by the profile optional configuration.'); // Test that override of optional configuration does work. $this->assertEqual($config_test_storage->load('override')->label(), 'Override', 'The optional config_test entity is overridden by the profile optional configuration.'); // Test that override of optional configuration which introduces an unmet // dependency does not get created. $this->assertNull($config_test_storage->load('override_unmet'), 'The optional config_test entity with unmet dependencies is not created.'); // Installing dblog creates the optional configuration. $this->container->get('module_installer')->install(['dblog']); $this->rebuildContainer(); $this->assertEqual($config_test_storage->load('override_unmet')->label(), 'Override', 'The optional config_test entity is overridden by the profile optional configuration and is installed when its dependencies are met.'); }
/** * {@inheritdoc} */ protected function setUpSyncForm() { // Create a new sync directory. drupal_mkdir($this->sync_dir); // Extract the tarball into the sync directory. $archiver = new ArchiveTar($this->tarball, 'gz'); $files = array(); foreach ($archiver->listContent() as $file) { $files[] = $file['filename']; } $archiver->extractList($files, $this->sync_dir); // Change the user.settings::register so that we can test that // standard_install() does not override it. $sync = new FileStorage($this->sync_dir); $user_settings = $sync->read('user.settings'); $user_settings['register'] = USER_REGISTER_ADMINISTRATORS_ONLY; $sync->write('user.settings', $user_settings); $this->drupalPostForm(NULL, array('sync_directory' => drupal_realpath($this->sync_dir)), 'Save and continue'); }
/** * Tests if installed config is equal to the exported config. * * @dataProvider providerTestModuleConfig */ public function testModuleConfig($module) { // System and user are required in order to be able to install some of the // other modules. Therefore they are put into static::$modules, which though // doesn't install config files, so import those config files explicitly. switch ($module) { case 'system': case 'user': $this->installConfig([$module]); break; } $module_path = drupal_get_path('module', $module) . '/'; /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */ $module_installer = $this->container->get('module_installer'); // @todo https://www.drupal.org/node/2308745 Rest has an implicit dependency // on the Node module remove once solved. if (in_array($module, ['rest', 'hal'])) { $module_installer->install(['node']); } // Work out any additional modules and themes that need installing to create // and optional config. $optional_config_storage = new FileStorage($module_path . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION); $modules_to_install = [$module]; $themes_to_install = []; foreach ($optional_config_storage->listAll() as $config_name) { $data = $optional_config_storage->read($config_name); if (isset($data['dependencies']['module'])) { $modules_to_install = array_merge($modules_to_install, $data['dependencies']['module']); } if (isset($data['dependencies']['theme'])) { $themes_to_install = array_merge($themes_to_install, $data['dependencies']['theme']); } } $module_installer->install(array_unique($modules_to_install)); $this->container->get('theme_installer')->install($themes_to_install); // Test configuration in the module's config/install directory. $module_config_storage = new FileStorage($module_path . InstallStorage::CONFIG_INSTALL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION); $this->doTestsOnConfigStorage($module_config_storage); // Test configuration in the module's config/optional directory. $this->doTestsOnConfigStorage($optional_config_storage); }
/** * Reverts an entity to its default values. */ public function revert() { $config_installer = \Drupal::service('config.installer'); $default_install_path = drupal_get_path('module', 'metatag') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY; $storage = new FileStorage($default_install_path, StorageInterface::DEFAULT_COLLECTION); $default_config_data = $storage->read('metatag.metatag_defaults.' . $this->id()); if ($default_config_data) { $this->set('tags', $default_config_data['tags']); $this->save(); } }
/** * {@inheritdoc} */ protected function read($name) { $data = $this->cache->get($name); // Cache misses fall through to the underlying storage. return $data ? $data->data : $this->fileStorage->read($name); }
/** * Test configuration value data type enforcement using schemas. */ public function testConfigSaveWithSchema() { $untyped_values = array('string' => 1, 'empty_string' => '', 'null_string' => NULL, 'integer' => '100', 'null_integer' => '', 'boolean' => 1, 'no_type' => 1, 'mapping' => array('string' => 1), 'float' => '3.14', 'null_float' => '', 'sequence' => array(1, 0, 1), 'sequence_bc' => array(1, 0, 1), 'not_present_in_schema' => TRUE, 'config_schema_test_integer' => '1', 'config_schema_test_integer_empty_string' => ''); $untyped_to_typed = $untyped_values; $typed_values = array('string' => '1', 'empty_string' => '', 'null_string' => NULL, 'integer' => 100, 'null_integer' => NULL, 'boolean' => TRUE, 'no_type' => 1, 'mapping' => array('string' => '1'), 'float' => 3.14, 'null_float' => NULL, 'sequence' => array(TRUE, FALSE, TRUE), 'sequence_bc' => array(TRUE, FALSE, TRUE), 'not_present_in_schema' => TRUE, 'config_schema_test_integer' => 1, 'config_schema_test_integer_empty_string' => NULL); // Save config which has a schema that enforces types. $this->config('config_schema_test.schema_data_types')->setData($untyped_to_typed)->save(); $this->assertIdentical($this->config('config_schema_test.schema_data_types')->get(), $typed_values); // Save config which does not have a schema that enforces types. $this->config('config_schema_test.no_schema_data_types')->setData($untyped_values)->save(); $this->assertIdentical($this->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($this->config('config_schema_test.ignore')->get(), $original_data); }
/** * Tests serialization of configuration to file. */ function testSerialization() { $name = $this->randomMachineName(10) . '.' . $this->randomMachineName(10); $config_data = array('numeric keys' => array('i', 'n', 'd', 'e', 'x', 'e', 'd'), 'nested keys' => array('HTML' => '<strong> <bold> <em> <blockquote>', 'UTF-8' => 'FrançAIS is ÜBER-åwesome', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ' => 'αβγδεζηθικλμνξοσὠ'), 'invalid xml' => '</title><script type="text/javascript">alert("Title XSS!");</script> & < > " \' '); // Encode and write, and reload and decode the configuration data. $filestorage = new FileStorage(config_get_config_directory(CONFIG_SYNC_DIRECTORY)); $filestorage->write($name, $config_data); $config_parsed = $filestorage->read($name); $key = 'numeric keys'; $this->assertIdentical($config_data[$key], $config_parsed[$key]); $key = 'nested keys'; $this->assertIdentical($config_data[$key], $config_parsed[$key]); $key = 'HTML'; $this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); $key = 'UTF-8'; $this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); $key = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ'; $this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); $key = 'invalid xml'; $this->assertIdentical($config_data[$key], $config_parsed[$key]); }
/** * Tests install profile config changes. */ function testInstallProfileConfigOverwrite() { $config_name = 'system.cron'; // The expected configuration from the system module. $expected_original_data = array('threshold' => array('autorun' => 0, 'requirements_warning' => 172800, 'requirements_error' => 1209600)); // The expected active configuration altered by the install profile. $expected_profile_data = array('threshold' => array('autorun' => 0, 'requirements_warning' => 259200, 'requirements_error' => 1209600)); // Verify that the original data matches. We have to read the module config // file directly, because the install profile default system.cron.yml // configuration file was used to create the active configuration. $config_dir = drupal_get_path('module', 'system') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY; $this->assertTrue(is_dir($config_dir)); $source_storage = new FileStorage($config_dir); $data = $source_storage->read($config_name); $this->assertIdentical($data, $expected_original_data); // Verify that active configuration matches the expected data, which was // created from the testing install profile's system.cron.yml file. $config = \Drupal::config($config_name); $this->assertIdentical($config->get(), $expected_profile_data); // Turn on the test module, which will attempt to replace the // configuration data. This attempt to replace the active configuration // should be ignored. \Drupal::moduleHandler()->install(array('config_existing_default_config_test')); // Verify that the test module has not been able to change the data. $config = \Drupal::config($config_name); $this->assertIdentical($config->get(), $expected_profile_data); // Disable and uninstall the test module. \Drupal::moduleHandler()->uninstall(array('config_existing_default_config_test')); // Verify that the data hasn't been altered by removing the test module. $config = \Drupal::config($config_name); $this->assertIdentical($config->get(), $expected_profile_data); }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { global $config_directories, $install_state; $sync_directory = $form_state->getValue('sync_directory'); if ($sync_directory != config_get_config_directory(CONFIG_SYNC_DIRECTORY)) { $settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) array('value' => $sync_directory, 'required' => TRUE); drupal_rewrite_settings($settings); $config_directories[CONFIG_SYNC_DIRECTORY] = $sync_directory; } if ($path = $form_state->getValue('import_tarball')) { // Ensure that we have an empty directory if we're going. $sync = new FileStorage($sync_directory); $sync->deleteAll(); try { $archiver = new ArchiveTar($path, 'gz'); $files = array(); foreach ($archiver->listContent() as $file) { $files[] = $file['filename']; } $archiver->extractList($files, config_get_config_directory(CONFIG_SYNC_DIRECTORY)); drupal_set_message($this->t('Your configuration files were successfully uploaded, ready for import.')); } catch (\Exception $e) { drupal_set_message($this->t('Could not extract the contents of the tar file. The error message is <em>@message</em>', array('@message' => $e->getMessage())), 'error'); } drupal_unlink($path); } // Change the langcode to the site default langcode provided by the // configuration. $config_storage = new FileStorage(config_get_config_directory(CONFIG_SYNC_DIRECTORY)); $install_state['parameters']['langcode'] = $config_storage->read('system.site')['langcode']; }
/** * Creates a snapshot of a given configuration item as provided by an * extension. * * @param FileStorage $extension_storage * An extension's configuration file storage. * @param string $item_name * The name of the configuration item. */ function createItemSnapshot(FileStorage $extension_storage, $item_name) { // Snapshot the configuration item as provided by the extension. $extension_value = $extension_storage->read($item_name); $this->snapshotExtensionStorage->write($item_name, $extension_value); // Snapshot the configuration item as installed in the active storage. $active_value = $this->activeStorage->read($item_name); $this->snapshotActiveStorage->write($item_name, $active_value); }