555 lines
18 KiB
Plaintext
555 lines
18 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Install, update and uninstall functions for the Webform module.
|
|
*/
|
|
|
|
use Drupal\Component\Render\FormattableMarkup;
|
|
use Drupal\Core\Database\Database;
|
|
use Drupal\Core\Serialization\Yaml;
|
|
use Drupal\Core\Render\Element;
|
|
use Drupal\system\Entity\Action;
|
|
use Drupal\webform\Entity\Webform;
|
|
use Drupal\webform\WebformInterface;
|
|
use Drupal\webform\Plugin\WebformElement\ManagedFile;
|
|
|
|
/**
|
|
* Implements hook_uninstall().
|
|
*/
|
|
function webform_uninstall() {
|
|
// Issue #2793597: uninstall error You have requested a non-existent service
|
|
// "webform.email_provider".
|
|
// Workaround: Don't use the webform.email_provider in hook_uninstall().
|
|
// @see \Drupal\webform\WebformEmailProvider::uninstall()
|
|
$config = \Drupal::configFactory()->getEditable('system.mail');
|
|
$mail_plugins = $config->get('interface');
|
|
unset($mail_plugins['webform']);
|
|
$config->set('interface', $mail_plugins)->save();
|
|
}
|
|
|
|
/**
|
|
* Implements hook_requirements().
|
|
*/
|
|
function webform_requirements($phase) {
|
|
if ($phase != 'runtime') {
|
|
return [];
|
|
}
|
|
|
|
$requirements = [];
|
|
|
|
// Check HTML email handling.
|
|
/** @var \Drupal\webform\WebformEmailProviderInterface $email_provider */
|
|
$email_provider = \Drupal::service('webform.email_provider');
|
|
$email_provider->check();
|
|
$module = $email_provider->getModuleName();
|
|
$mail_plugin_id = $email_provider->getMailPluginId();
|
|
$mail_plugin_definition = $email_provider->getMailPluginDefinition();
|
|
if ($module || $mail_plugin_id) {
|
|
$t_args = [
|
|
'@module' => $module,
|
|
'@plugin_id' => $mail_plugin_id,
|
|
'@plugin_label' => $mail_plugin_definition['label'],
|
|
'@plugin_description' => $mail_plugin_definition['description'],
|
|
];
|
|
$requirements['webform_email'] = [
|
|
'title' => t('Webform: HTML email support'),
|
|
'value' => ($module) ? t('Provided by the @module module.', $t_args) : t('Provided by @plugin_id mail plugin.', $t_args),
|
|
'description' => new FormattableMarkup('@plugin_label: @plugin_description', $t_args),
|
|
'severity' => REQUIREMENT_OK,
|
|
];
|
|
}
|
|
else {
|
|
$requirements['webform_email'] = [
|
|
'title' => t('Webform: HTML email support'),
|
|
'value' => t('Unable to determine email module and/or provider'),
|
|
'severity' => REQUIREMENT_ERROR,
|
|
];
|
|
}
|
|
|
|
// Check private file upload.
|
|
$scheme_options = ManagedFile::getVisibleStreamWrappers();
|
|
if (isset($scheme_options['private'])) {
|
|
$requirements['webform_file_private'] = [
|
|
'title' => t('Webform: Private files'),
|
|
'value' => t('Private file system is set.'),
|
|
];
|
|
}
|
|
else {
|
|
$requirements['webform_file_private'] = [
|
|
'title' => t('Webform: Private files'),
|
|
'value' => t('Private file system is not set.'),
|
|
'description' => t('This must be changed in <a href="https://www.drupal.org/documentation/modules/file">settings.php</a>. For more information see: <a href="https://www.drupal.org/psa-2016-003">DRUPAL-PSA-2016-003</a>'),
|
|
'severity' => REQUIREMENT_WARNING,
|
|
];
|
|
}
|
|
|
|
// Check third party libraries status.
|
|
/** @var \Drupal\webform\WebformLibrariesManagerInterface $libraries_manager */
|
|
$libraries_manager = \Drupal::service('webform.libraries_manager');
|
|
$requirements += $libraries_manager->requirements();
|
|
|
|
return $requirements;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// Helper functions
|
|
/******************************************************************************/
|
|
|
|
/**
|
|
* Update admin settings to reflect changes in the default settings.
|
|
*
|
|
* This function is used to apply new admin settings (in webform.settings.yml).
|
|
* If you are moving or updating any admin settings this must be explicitly
|
|
* done via an update hook.
|
|
*/
|
|
function _webform_update_admin_settings() {
|
|
$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];
|
|
}
|
|
}
|
|
else {
|
|
// Loop through the group's settings and apply all existing settings to
|
|
// the default admin settings.
|
|
foreach ($settings as $name => $value) {
|
|
if (isset($current_settings[$group][$name])) {
|
|
$admin_settings[$group][$name] = $current_settings[$group][$name];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$admin_config->setData($admin_settings)->save();
|
|
}
|
|
|
|
/**
|
|
* Update webform setting 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_form_settings() {
|
|
$default_properties = [
|
|
'langcode' => 'en',
|
|
'status' => WebformInterface::STATUS_OPEN,
|
|
'open' => NULL,
|
|
'close' => NULL,
|
|
'dependencies' => [],
|
|
'uid' => '',
|
|
'template' => FALSE,
|
|
'id' => '',
|
|
'title' => '',
|
|
'description' => '',
|
|
'elements' => '',
|
|
'css' => '',
|
|
'javascript' => '',
|
|
'settings' => [],
|
|
'access' => [],
|
|
'handlers' => [],
|
|
];
|
|
|
|
$default_settings = Webform::getDefaultSettings();
|
|
$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();
|
|
|
|
// 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;
|
|
|
|
// Save data.
|
|
$webform_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 hooks.
|
|
/******************************************************************************/
|
|
|
|
/**
|
|
* Issue #2834203: Convert webform field target_id to 32 characters.
|
|
*/
|
|
function webform_update_8001() {
|
|
$database_schema = \Drupal::database()->schema();
|
|
$schema = \Drupal::keyValue('entity.storage_schema.sql')->getAll();
|
|
foreach ($schema as $item_name => $item) {
|
|
foreach ($item as $table_name => $table_schema) {
|
|
foreach ($table_schema as $schema_key => $schema_data) {
|
|
if ($schema_key == 'fields') {
|
|
foreach ($schema_data as $field_name => $field_data) {
|
|
if (preg_match('/_target_id$/', $field_name) && $field_data['description'] == 'The ID of the webform entity.' && $schema[$item_name][$table_name]['fields'][$field_name]['length'] === 255) {
|
|
$schema[$item_name][$table_name]['fields'][$field_name]['length'] = 32;
|
|
if ($database_schema->tableExists($table_name)) {
|
|
$database_schema->changeField($table_name, $field_name, $field_name, $schema[$item_name][$table_name]['fields'][$field_name]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
\Drupal::keyValue('entity.storage_schema.sql')->setMultiple($schema);
|
|
}
|
|
|
|
/**
|
|
* Issue #2834572: Refactor and improve token management.
|
|
*/
|
|
function webform_update_8002() {
|
|
$config_factory = \Drupal::configFactory();
|
|
|
|
// Update 'webform.settings' configuration.
|
|
$settings_config = \Drupal::configFactory()->getEditable('webform.settings');
|
|
$yaml = Yaml::encode($settings_config->getRawData());
|
|
$yaml = str_replace('[webform_submission:', '[webform_submission:', $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());
|
|
$yaml = str_replace('[webform_submission:', '[webform_submission:', $yaml);
|
|
$webform_config->setData(Yaml::decode($yaml));
|
|
$webform_config->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Issue #2834654: Add close button to messages.
|
|
*/
|
|
function webform_update_8003() {
|
|
// Change webform.* to webform.* state.
|
|
$webforms = Webform::loadMultiple();
|
|
foreach ($webforms as $webform) {
|
|
$state = \Drupal::state()->get('webform.' . $webform->id(), NULL);
|
|
if ($state !== NULL) {
|
|
\Drupal::state()->set('webform.webform.' . $webform->id(), $state);
|
|
\Drupal::state()->delete('webform.' . $webform->id());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Issue #2836948: Problem with autocomplete field. Change '#autocomplete_options' to '#autocomplete_items'.
|
|
*/
|
|
function webform_update_8004() {
|
|
$config_factory = \Drupal::configFactory();
|
|
foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
|
|
$webform_config = $config_factory->getEditable($webform_config_name);
|
|
$elements = $webform_config->get('elements');
|
|
if (strpos($elements, '#autocomplete_options') !== FALSE) {
|
|
$elements = str_replace('#autocomplete_options', '#autocomplete_items', $elements);
|
|
$webform_config->set('elements', $elements);
|
|
$webform_config->save(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Issue #2837090: Undefined function call webform_schema.
|
|
*/
|
|
function webform_update_8005() {
|
|
// @see webform_update_8006() which fixes this broken hook.
|
|
}
|
|
|
|
/**
|
|
* Issue #2837090: Undefined function call webform_schema.
|
|
*/
|
|
function webform_update_8006() {
|
|
// Fix key_value.collection which was no updated during the migration.
|
|
$module_handler = \Drupal::moduleHandler();
|
|
$database_type = Database::getConnection('default')->databaseType();
|
|
if ($module_handler->moduleExists('webform') && !$module_handler->moduleExists('yamlform') && $database_type == 'mysql') {
|
|
$database = \Drupal::database();
|
|
|
|
$select = $database->select('key_value', 'kv');
|
|
$select->fields('kv', ['collection', 'name', 'value']);
|
|
$select->condition('collection', '%yamlform%', 'LIKE');
|
|
$result = $select->execute();
|
|
while ($record = $result->fetchAssoc()) {
|
|
$old_collection = $record['collection'];
|
|
$new_collection = str_replace('yamlform', 'webform', $record['collection']);
|
|
|
|
$collection_select = $database->select('key_value', 'kv');
|
|
$collection_select->fields('kv', ['collection', 'name', 'value']);
|
|
$collection_select->condition('collection', $new_collection);
|
|
$collection_result = $collection_select->execute();
|
|
|
|
// Only insert the new record if there the collection does not exist.
|
|
if (!$collection_result->fetchAll()) {
|
|
$record['collection'] = $new_collection;
|
|
$database->insert('key_value')
|
|
->fields(['collection', 'name', 'value'])
|
|
->values(array_values($record))
|
|
->execute();
|
|
}
|
|
|
|
// Delete the old record.
|
|
$database->delete('key_value')
|
|
->condition('collection', $old_collection)
|
|
->execute();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Issue #2840521: Add support for global CSS and JS.
|
|
*/
|
|
function webform_update_8007() {
|
|
_webform_update_admin_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2839615: Disabling message about viewing user's previous submissions.
|
|
*/
|
|
function webform_update_8008() {
|
|
_webform_update_form_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2844020: Add admin and form specific setting to allow submit button to be clicked only once.
|
|
*/
|
|
function webform_update_8009() {
|
|
_webform_update_admin_settings();
|
|
_webform_update_form_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2843400: Automated purging of submissions.
|
|
*/
|
|
function webform_update_8010() {
|
|
_webform_update_admin_settings();
|
|
_webform_update_form_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2845028: Refactor and rework element formatting to better support multiple values.
|
|
*/
|
|
function webform_update_8011() {
|
|
// Update admin.settings format to support
|
|
// 'formats.{element_type}.item' and 'formats.{element_type}.items'.
|
|
$admin_config = \Drupal::configFactory()->getEditable('webform.settings');
|
|
$data = $admin_config->getRawData();
|
|
if (!empty($data['format'])) {
|
|
foreach ($data['format'] as $element_type => $element_format) {
|
|
if (is_string($element_format)) {
|
|
$data['format'][$element_type] = ['item' => $element_format];
|
|
}
|
|
}
|
|
$admin_config->setData($data)->save();
|
|
}
|
|
|
|
// Update webform element to support #format_items.
|
|
$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();
|
|
if (strpos($data['elements'], "'#format'") === FALSE) {
|
|
continue;
|
|
}
|
|
|
|
$elements = Yaml::decode($data['elements']);
|
|
_webform_update_8011($elements);
|
|
|
|
$data['elements'] = Yaml::encode($elements);
|
|
$webform_config->setData($data);
|
|
$webform_config->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Move $element['#format'] to $element['#format_items'].
|
|
*
|
|
* Applies to ol, ul, comma, and semicolon.
|
|
*
|
|
* @param array $element
|
|
* A form element.
|
|
*/
|
|
function _webform_update_8011(array &$element) {
|
|
if (isset($element['#format'])) {
|
|
/** @var \Drupal\webform\WebformElementManagerInterface $element_manager */
|
|
$element_manager = \Drupal::service('plugin.manager.webform.element');
|
|
$webform_element = $element_manager->getElementInstance($element);
|
|
|
|
$format = $element['#format'];
|
|
$item_formats = $webform_element->getItemFormats();
|
|
$items_formats = $webform_element->getItemsFormats();
|
|
if (!isset($item_formats[$format]) && isset($items_formats[$format])) {
|
|
unset($element['#format']);
|
|
$element['#format_items'] = $format;
|
|
}
|
|
}
|
|
|
|
foreach (Element::children($element) as $key) {
|
|
if (is_array($element[$key])) {
|
|
_webform_update_8011($element[$key]);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Issue #2845776: Improve #multiple handling.
|
|
*/
|
|
function webform_update_8012() {
|
|
_webform_update_admin_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2840858: Create Webform and Webform Submission Action plugins.
|
|
*/
|
|
function webform_update_8013() {
|
|
_webform_update_actions();
|
|
}
|
|
|
|
/**
|
|
* Issue #2848042: Rework #type shorthand prefix handling.
|
|
*/
|
|
function webform_update_8014() {
|
|
$config_factory = \Drupal::configFactory();
|
|
foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
|
|
$webform_config = $config_factory->getEditable($webform_config_name);
|
|
|
|
// Get data, get elements, and update elements #type.
|
|
$data = $webform_config->getRawData();
|
|
$elements = Yaml::decode($data['elements']);
|
|
// Make sure $elements has been decoded into an array.
|
|
if (is_array($elements)) {
|
|
_webform_update_8014($elements);
|
|
|
|
// Set elements, set data, and save data.
|
|
$data['elements'] = Yaml::encode($elements);
|
|
$webform_config->setData($data);
|
|
$webform_config->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add 'webform_' prefix to #type.
|
|
*
|
|
* @param array $element
|
|
* A form element.
|
|
*/
|
|
function _webform_update_8014(array &$element) {
|
|
/** @var \Drupal\webform\WebformElementManagerInterface $element_manager */
|
|
$element_manager = \Drupal::service('plugin.manager.webform.element');
|
|
|
|
// Add 'webform_' prefix to #type.
|
|
if (isset($element['#type']) && !$element_manager->hasDefinition($element['#type']) && $element_manager->hasDefinition('webform_' . $element['#type'])) {
|
|
$element['#type'] = 'webform_' . $element['#type'];
|
|
}
|
|
|
|
foreach (Element::children($element) as $key) {
|
|
if (is_array($element[$key])) {
|
|
_webform_update_8014($element[$key]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Issue #2850247: Experiment with system tray integration.
|
|
*/
|
|
function webform_update_8015() {
|
|
_webform_update_admin_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2850455: Add lookup_keys to webform config entity. Flush cache entity definitions.
|
|
*/
|
|
function webform_update_8016() {
|
|
drupal_flush_all_caches();
|
|
}
|
|
|
|
/**
|
|
* Issue #2850455: Add lookup_keys to webform config entity. Update Webform lookup keys.
|
|
*/
|
|
function webform_update_8017() {
|
|
// Must resave all Webform config lookup keys.
|
|
// @see \Drupal\Core\Config\Entity\Query\QueryFactory::updateConfigKeyStore
|
|
$webforms = Webform::loadMultiple();
|
|
foreach ($webforms as $webform) {
|
|
$webform->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Issue #2850885: Add ability to disable autocomplete for form and/or element.
|
|
*/
|
|
function webform_update_8018() {
|
|
_webform_update_admin_settings();
|
|
_webform_update_form_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2853302: Allow confirmation page title to be customized.
|
|
*/
|
|
function webform_update_8019() {
|
|
_webform_update_form_settings();
|
|
}
|
|
|
|
/**
|
|
* Issue #2845724: Add webform opening and closing date/time.
|
|
*/
|
|
function webform_update_8020() {
|
|
// Resave all webforms to convert status boolean to string.
|
|
$webforms = Webform::loadMultiple();
|
|
foreach ($webforms as $webform) {
|
|
$webform->setStatus($webform->get('status'))->save();
|
|
}
|
|
_webform_update_form_settings();
|
|
}
|