- <?php
-
- * Return an array for setting up a Batch API job to sync all configuration.
- */
- function config_sync_batch($config_statuses = NULL) {
- if (empty($config_statuses)) {
- $config_statuses = config_get_statuses();
- }
- $operations[] = array('_config_sync_start', array($config_statuses));
- $operations[] = array('_config_sync_validate', array());
- $operations[] = array('_config_sync_import', array());
- $batch = array(
- 'operations' => $operations,
- 'title' => t('Importing configuration'),
- 'init_message' => t('Starting import'),
- 'error_message' => t('An error occurred while importing the configuration.'),
- 'file' => backdrop_get_path('module', 'config') . '/config.sync.inc',
- 'finished' => '_config_sync_finished',
- );
- return $batch;
- }
-
- * Batch API callback. Start the config import.
- */
- function _config_sync_start($config_statuses, &$context) {
- state_set('config_sync', REQUEST_TIME);
-
-
-
- $context['results']['all_configs'] = $config_statuses;
- $context['results']['pending_changes'] = array_filter($config_statuses);
- $context['results']['completed_changes'] = array();
- }
-
- * Batch API callback. Validate the changes before attempting to sync.
- * Reports all discovered issues in a message.
- */
- function _config_sync_validate(&$context) {
- if (!isset($context['sandbox']['batch_size'])) {
- $context['sandbox']['batch_size'] = config_get('system.core', 'config_sync_batch_size');
- $context['sandbox']['total_size'] = count($context['results']['pending_changes']);
- $context['sandbox']['current_index'] = 0;
- }
-
- $config_files = array_slice($context['results']['pending_changes'], $context['sandbox']['current_index'], $context['sandbox']['batch_size']);
- foreach ($config_files as $config_file => $config_change_type) {
- try {
- config_sync_validate_file($config_file, $config_change_type, $context['results']['all_configs']);
- }
- catch (ConfigValidateException $e) {
- $context['results']['errors'][] = $e->getMessage();
- }
- $context['sandbox']['current_index']++;
- }
-
- $context['finished'] = $context['sandbox']['total_size'] ? $context['sandbox']['current_index'] / $context['sandbox']['total_size'] : 1;
- }
-
- * Batch API callback. Import the individual config files.
- */
- function _config_sync_import(&$context) {
-
- if (isset($context['results']['errors'])) {
- $context['finished'] = 1;
- return;
- }
-
- if (!isset($context['sandbox']['batch_size'])) {
- $context['sandbox']['batch_size'] = config_get('system.core', 'config_sync_batch_size');
- $context['sandbox']['total_size'] = count($context['results']['pending_changes']);
- $context['sandbox']['current_index'] = 0;
- }
-
- $config_files = array_slice($context['results']['pending_changes'], 0, $context['sandbox']['batch_size']);
- foreach ($config_files as $config_file => $config_change_type) {
- config_sync_file($config_file, $config_change_type);
- unset($context['results']['pending_changes'][$config_file]);
- $context['results']['completed_changes'][$config_file] = $config_change_type;
- $context['sandbox']['current_index']++;
- }
-
- $context['finished'] = $context['sandbox']['total_size'] ? $context['sandbox']['current_index'] / $context['sandbox']['total_size'] : 1;
- }
-
- * Batch API callback. Finish the config import.
- */
- function _config_sync_finished($status, $results, $operations) {
- if ($status === FALSE) {
- backdrop_set_message(t('Configuration sync failed. Check that the configuration files are properly formatted.'), 'error');
- }
- if (!empty($results['errors'])) {
- backdrop_set_message(t('Configuration sync failed. The following errors were reported:') . ' ' . theme('item_list', array('items' => $results['errors'])), 'error');
- }
- if (!empty($results['completed_changes'])) {
- backdrop_set_message(t('Configuration sync completed. @files configuration files synced.', array('@files' => count($results['completed_changes']))));
- if (config_get('system.core', 'config_sync_clear_staging')) {
-
- $config_dir = config_get_config_directory('staging');
- $config_storage = new ConfigFileStorage($config_dir);
- $config_storage->deleteAll();
- }
- }
- backdrop_flush_all_caches();
- state_del('config_sync');
- }
-
- * Validate an individual configuration to ensure it's safe to import.
- *
- * Calls all the necessary hooks to allow modules to validate a set of
- * configuration changes. If any module encounters a validation problem, it
- * should throw a ConfigValidateException exception.
- *
- * @param string $config_name
- * The name of the config file being synced.
- * @param string $config_change_type
- * The type of change occurring to this config file. Must be one of the
- * following values: "create", "update", or "delete".
- * @param array|NULL $all_changes
- * If this file is being changed with a group of other configuration files,
- * pass in the complete set of files that are anticipated to be changed during
- * the sync. If doing a typical sync between staging and live directories,
- * this value can be retrieved from config_get_statuses(). If syncing a single
- * configuration file, this value should be NULL.
- * @param array $data
- * The configuration data to be validated if the data is coming from a source
- * other than the staging configuration storage.
- *
- * @throws ConfigValidateException
- *
- * @see hook_config_create_validate().
- * @see hook_config_update_validate().
- * @see hook_config_delete_validate().
- */
- function config_sync_validate_file($config_name, $config_change_type, $all_changes = NULL, $config_data = NULL) {
-
- if (is_null($config_data)) {
- $staging_config = config($config_name, 'staging')->load();
- }
-
-
-
- else {
- $staging_config = config($config_name, 'staging')->setData($config_data);
- }
-
-
-
-
-
- $config_info = config_get_info($config_name);
- if (empty($config_info)) {
- if ($config_change_type === 'delete') {
- $message = t('The configuration "@name" is not owned by any enabled module, so it cannot be deleted. If you have disabled this module, either <a href="!enable">enable the module</a> and try the import again, or <a href="!uninstall">uninstall the module entirely</a> to clean up left-over configuration.', array('@name' => $config_name, '!enable' => url('admin/modules'), '!uninstall' => url('admin/modules/uninstall')));
- }
- else {
- $message = t('The configuration "@name" is not owned by any module. Try enabling the module that provides this configuration, then importing again.', array('@name' => $config_name));
- }
- throw new ConfigValidateException($message);
- }
-
- switch ($config_change_type) {
- case 'create':
- $staging_config->validateData();
- module_invoke_all('config_create_validate', $staging_config, $all_changes);
- break;
- case 'update':
- $staging_config->validateData();
- $active_config = config($config_name, 'active')->load();
- module_invoke_all('config_update_validate', $staging_config, $active_config, $all_changes);
- break;
- case 'delete':
- $active_config = config($config_name, 'active')->load();
- module_invoke_all('config_delete_validate', $active_config, $all_changes);
- break;
- }
- }
-
- * Save an individual configuration.
- *
- * Calls all the necessary hooks to allow modules to modify any configuration
- * changes before they are saved.
- *
- * @param string $config_file
- * The name of the config file being synced.
- * @param string $config_change_type
- * The type of change occurring to this config file. Must be one of the
- * following values: "create", "update", or "delete".
- * @param string $config_contents
- * The configuration file's contents.
- *
- * @see hook_config_create().
- * @see hook_config_update().
- * @see hook_config_delete().
- */
- function config_sync_file($config_file, $config_change_type, $config_contents = NULL) {
- $active_config = config($config_file, 'active');
-
-
- if (is_null($config_contents)) {
- $staging_config = config($config_file, 'staging')->load();
- }
-
-
-
- else {
- $staging_config = config($config_file, 'staging')->setData($config_contents);
- }
-
- switch ($config_change_type) {
- case 'create':
- $active_config->setData($staging_config->get());
- module_invoke_all('config_create', $active_config);
- $active_config->save();
- break;
- case 'update':
- $active_config->load();
- module_invoke_all('config_update', $staging_config, $active_config);
- $active_config->setData($staging_config->get())->save();
- break;
- case 'delete':
- $active_config->load();
- module_invoke_all('config_delete', $active_config);
- $active_config->delete();
- break;
- }
- }