367 lines
12 KiB
PHP
367 lines
12 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Webform install helper functions.
|
|
*/
|
|
|
|
use Drupal\Core\Render\Element;
|
|
use Drupal\Core\Serialization\Yaml;
|
|
use Drupal\system\Entity\Action;
|
|
use Drupal\webform\Entity\Webform;
|
|
use Drupal\webform\WebformInterface;
|
|
|
|
/**
|
|
* Update admin settings to reflect changes in the default settings.
|
|
*
|
|
* If you are moving or updating any admin settings this must be explicitly
|
|
* done via an update hook.
|
|
*
|
|
* @param bool $reset
|
|
* If set TRUE old admin settings will be completely deleted.
|
|
*
|
|
* @see drush_webform_repair()
|
|
*/
|
|
function _webform_update_admin_settings($reset = FALSE) {
|
|
$admin_config = \Drupal::configFactory()->getEditable('webform.settings');
|
|
|
|
$current_settings = $admin_config->getRawData();
|
|
$admin_settings = Yaml::decode(file_get_contents(drupal_get_path('module', 'webform') . '/config/install/webform.settings.yml'));
|
|
// Note, admin settings are always grouped into associative array,
|
|
// except for the langcode.
|
|
foreach ($admin_settings as $group => $settings) {
|
|
// Handle the rare case the we are adding a new group the admin settings.
|
|
if (!isset($current_settings[$group])) {
|
|
continue;
|
|
}
|
|
|
|
// Completely copy the format, langcode, and third_party_settings.
|
|
if (in_array($group, ['format', 'langcode', 'third_party_settings'])) {
|
|
if (isset($current_settings[$group])) {
|
|
$admin_settings[$group] = $current_settings[$group];
|
|
}
|
|
}
|
|
elseif ($reset) {
|
|
// Copy only group's settings that are defined in admin settings.
|
|
// This will cause old settings to be completely deleted.
|
|
foreach ($settings as $name => $value) {
|
|
if (isset($current_settings[$group][$name])) {
|
|
$admin_settings[$group][$name] = $current_settings[$group][$name];
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// Loop through the group's settings and apply all existing settings to
|
|
// the default admin settings.
|
|
foreach ($current_settings[$group] as $name => $value) {
|
|
$admin_settings[$group][$name] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If not reset, make sure all the current settings are preserved.
|
|
if (!$reset) {
|
|
$admin_settings += $current_settings;
|
|
}
|
|
|
|
$admin_config->setData($admin_settings)->save();
|
|
}
|
|
|
|
/**
|
|
* Update webform settings to reflect changes in the default settings.
|
|
*
|
|
* This function can be used to apply new webform settings to all existing
|
|
* webforms.
|
|
*
|
|
* @see \Drupal\webform\Entity\Webform::setSettings
|
|
*/
|
|
function _webform_update_webform_settings() {
|
|
$config_factory = \Drupal::configFactory();
|
|
foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
|
|
$webform_config = $config_factory->getEditable($webform_config_name);
|
|
$data = $webform_config->getRawData();
|
|
$data = _webform_update_webform_setting($data);
|
|
$webform_config->setData($data)->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update webform setting to reflect changes in the default settings.
|
|
*
|
|
* @param array $data
|
|
* A webform's raw configuration data from webform.webform.*.yml.
|
|
*
|
|
* @return array
|
|
* Updated raw configuration data.
|
|
*/
|
|
function _webform_update_webform_setting(array $data) {
|
|
$default_properties = [
|
|
'langcode' => 'en',
|
|
'status' => WebformInterface::STATUS_OPEN,
|
|
'dependencies' => [],
|
|
'open' => NULL,
|
|
'close' => NULL,
|
|
'weight' => 0,
|
|
'uid' => '',
|
|
'template' => FALSE,
|
|
'archive' => FALSE,
|
|
'id' => '',
|
|
'title' => '',
|
|
'description' => '',
|
|
'category' => '',
|
|
'elements' => '',
|
|
'css' => '',
|
|
'javascript' => '',
|
|
'settings' => [],
|
|
'access' => [],
|
|
'handlers' => [],
|
|
];
|
|
|
|
$default_settings = Webform::getDefaultSettings();
|
|
|
|
// Always apply the default properties.
|
|
$properties = $default_properties;
|
|
// Now apply defined properties.
|
|
foreach ($data as $name => $value) {
|
|
$properties[$name] = $value;
|
|
}
|
|
// Set properties.
|
|
$data = $properties;
|
|
|
|
// Always apply the default settings.
|
|
$settings = $default_settings;
|
|
// Now apply custom settings.
|
|
foreach ($data['settings'] as $name => $value) {
|
|
$settings[$name] = $value;
|
|
}
|
|
// Set settings.
|
|
$data['settings'] = $settings;
|
|
|
|
// Set access.
|
|
/** @var \Drupal\webform\WebformAccessRulesManagerInterface $access_rules_manager */
|
|
$access_rules_manager = \Drupal::service('webform.access_rules_manager');
|
|
$data['access'] += $access_rules_manager->getDefaultAccessRules();
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Update webform handler settings to reflect changes in a handler's default configuration.
|
|
*
|
|
* @see \Drupal\webform\Plugin\WebformHandlerInterface
|
|
*/
|
|
function _webform_update_webform_handler_settings() {
|
|
// Issue #2863986: Allow updating modules with new service dependencies.
|
|
\Drupal::service('kernel')->rebuildContainer();
|
|
|
|
// Get the default configuration (aka settings) for all handlers provided
|
|
// by the Webform module.
|
|
/** @var \Drupal\webform\Plugin\WebformHandlerManagerInterface $handler_manager */
|
|
$handler_manager = \Drupal::service('plugin.manager.webform.handler');
|
|
$definitions = $handler_manager->getDefinitions();
|
|
$default_handler_settings = [];
|
|
foreach ($definitions as $plugin_id => $definition) {
|
|
if (strpos($definition['provider'], 'webform_test_') === 0 || in_array($definition['provider'], ['webform', 'webform_scheduled_email'])) {
|
|
$default_handler_settings[$plugin_id] = $handler_manager->createInstance($plugin_id)->defaultConfiguration();
|
|
}
|
|
}
|
|
|
|
$config_factory = \Drupal::configFactory();
|
|
// Update 'webform.webform.*' configuration.
|
|
foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
|
|
$webform_config = $config_factory->getEditable($webform_config_name);
|
|
|
|
// Get data.
|
|
$data = $webform_config->getRawData();
|
|
|
|
// Apply the default handler settings.
|
|
$has_handler = FALSE;
|
|
foreach ($data['handlers'] as &$handler) {
|
|
if (!isset($default_handler_settings[$handler['id']])) {
|
|
continue;
|
|
}
|
|
|
|
$settings = $default_handler_settings[$handler['id']];
|
|
foreach ($handler['settings'] as $settings_key => $setting_value) {
|
|
$settings[$settings_key] = $setting_value;
|
|
}
|
|
|
|
if ($handler['settings'] != $settings) {
|
|
$has_handler = TRUE;
|
|
$handler['settings'] = $settings;
|
|
}
|
|
}
|
|
|
|
if ($has_handler) {
|
|
$webform_config->setData($data)->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update webform options setting to reflect changes in the default settings.
|
|
*
|
|
* This function can be used to apply new webform options configuration to
|
|
* all existing webforms options.
|
|
*
|
|
* @see \Drupal\webform\Entity\WebformOptions
|
|
*/
|
|
function _webform_update_options_settings() {
|
|
$default_properties = [
|
|
'langcode' => 'en',
|
|
'status' => TRUE,
|
|
'dependencies' => [],
|
|
'id' => '',
|
|
'label' => '',
|
|
'category' => '',
|
|
'options' => '',
|
|
];
|
|
|
|
$config_factory = \Drupal::configFactory();
|
|
// Update 'webform.webform_options.*' configuration.
|
|
foreach ($config_factory->listAll('webform.webform_options.') as $webform_config_name) {
|
|
$webform_options_config = $config_factory->getEditable($webform_config_name);
|
|
|
|
// Get data.
|
|
$data = $webform_options_config->getRawData();
|
|
|
|
// Always apply the default properties.
|
|
$properties = $default_properties;
|
|
// Now apply defined properties.
|
|
foreach ($data as $name => $value) {
|
|
$properties[$name] = $value;
|
|
}
|
|
|
|
// Set properties.
|
|
$data = $properties;
|
|
|
|
// Save data.
|
|
$webform_options_config->setData($data)->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update or install any new system.actions.* config entities.
|
|
*/
|
|
function _webform_update_actions() {
|
|
$files = file_scan_directory(drupal_get_path('module', 'webform') . '/config', '/^system.action..*\.yml$/');
|
|
foreach ($files as $path => $file) {
|
|
$action_id = str_replace('system.action.', '', $file->name);
|
|
$action = Action::load($action_id);
|
|
if (!$action) {
|
|
// Install new action.
|
|
$data = Yaml::decode(file_get_contents($path));
|
|
$action = Action::create($data);
|
|
$action->trustData()->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update webform field storage definitions.
|
|
*
|
|
* @see \Drupal\webform\Plugin\Field\FieldType\WebformEntityReferenceItem::schema
|
|
*/
|
|
function _webform_update_field_storage_definitions() {
|
|
$manager = \Drupal::entityDefinitionUpdateManager();
|
|
/** @var \Drupal\field\FieldStorageConfigInterface[] $fields */
|
|
$fields = \Drupal::entityTypeManager()
|
|
->getStorage('field_storage_config')
|
|
->loadByProperties(['type' => 'webform']);
|
|
foreach ($fields as $field) {
|
|
$field_name = $field->getName();
|
|
$entity_type = $field->getTargetEntityTypeId();
|
|
$manager->updateFieldStorageDefinition($manager->getFieldStorageDefinition($field_name, $entity_type));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update webform submission storage schema.
|
|
*
|
|
* @see \Drupal\webform\WebformSubmissionStorageSchema
|
|
*/
|
|
function _webform_update_webform_submission_storage_schema() {
|
|
$manager = \Drupal::entityDefinitionUpdateManager();
|
|
$manager->updateEntityType($manager->getEntityType('webform_submission'));
|
|
}
|
|
|
|
/**
|
|
* Replace string in webform.settings.yml and webform.webform.*.yml.
|
|
*
|
|
* @param string $search
|
|
* String to be search for.
|
|
* @param string $replace
|
|
* String to be replace with.
|
|
*/
|
|
function _webform_update_string_replace($search, $replace) {
|
|
$config_factory = \Drupal::configFactory();
|
|
|
|
// Update 'webform.settings' configuration.
|
|
$settings_config = \Drupal::configFactory()->getEditable('webform.settings');
|
|
$yaml = Yaml::encode($settings_config->getRawData());
|
|
if (strpos($yaml, $search) !== FALSE) {
|
|
$yaml = str_replace($search, $replace, $yaml);
|
|
$settings_config->setData(Yaml::decode($yaml));
|
|
$settings_config->save();
|
|
}
|
|
|
|
// Update 'webform.webform.*' configuration.
|
|
foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
|
|
$webform_config = $config_factory->getEditable($webform_config_name);
|
|
$yaml = Yaml::encode($webform_config->getRawData());
|
|
if (strpos($yaml, $search) !== FALSE) {
|
|
$yaml = str_replace($search, $replace, $yaml);
|
|
$webform_config->setData(Yaml::decode($yaml));
|
|
$webform_config->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear/remove selected webform element properties.
|
|
*
|
|
* @param array $properties
|
|
* An associative array of webform element properties.
|
|
*/
|
|
function _webform_update_elements_clear_properties(array $properties) {
|
|
$pattern = '/(?:' . implode('|', array_keys($properties)) . ')/';
|
|
$config_factory = \Drupal::configFactory();
|
|
foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
|
|
$webform_config = $config_factory->getEditable($webform_config_name);
|
|
$data = $webform_config->getRawData();
|
|
|
|
// Make sure elements contains the properties.
|
|
if (!preg_match($pattern, $data['elements'])) {
|
|
continue;
|
|
}
|
|
|
|
$elements = Yaml::decode($data['elements']);
|
|
_webform_update_elements_clear_properties_recursive($elements, $properties);
|
|
$data['elements'] = Yaml::encode($elements);
|
|
|
|
$webform_config->setData($data);
|
|
$webform_config->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Recursively clear/remove selected webform element properties.
|
|
*
|
|
* @param array $element
|
|
* An element.
|
|
* @param array $properties
|
|
* An associative array of webform element properties.
|
|
*/
|
|
function _webform_update_elements_clear_properties_recursive(array &$element, array $properties) {
|
|
foreach ($properties as $property_name => $property_value) {
|
|
if (isset($element[$property_name]) && $element[$property_name] === $property_value) {
|
|
unset($element[$property_name]);
|
|
}
|
|
}
|
|
foreach (Element::children($element) as $key) {
|
|
if (is_array($element[$key])) {
|
|
_webform_update_elements_clear_properties_recursive($element[$key], $properties);
|
|
}
|
|
}
|
|
}
|