You are here

yamlform.install in YAML Form 8

Install, update and uninstall functions for the YAML Form module.

File

yamlform.install
View source
<?php

/**
 * @file
 * Install, update and uninstall functions for the YAML Form module.
 */
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Database\Database;
use Drupal\Core\Serialization\Yaml;
use Drupal\yamlform\Entity\YamlForm;
use Drupal\yamlform\Plugin\YamlFormElement\ManagedFile;
include_once 'includes/yamlform.update.inc';

/**
 * Implements hook_uninstall().
 */
function yamlform_uninstall() {

  // Issue #2793597: uninstall error You have requested a non-existent service
  // "yamlform.email_provider".
  // Workaround: Don't use the yamlform.email_provider in hook_uninstall().
  // @see \Drupal\yamlform\YamlFormEmailProvider::uninstall()
  $config = \Drupal::configFactory()
    ->getEditable('system.mail');
  $mail_plugins = $config
    ->get('interface');
  unset($mail_plugins['yamlform']);
  $config
    ->set('interface', $mail_plugins)
    ->save();
}

/**
 * Implements hook_requirements().
 */
function yamlform_requirements($phase) {
  if ($phase != 'runtime') {
    return [];
  }
  $requirements = [];

  // Check HTML email handling.

  /** @var \Drupal\yamlform\YamlFormEmailProviderInterface $email_provider */
  $email_provider = \Drupal::service('yamlform.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['yamlform_email'] = [
      'title' => t('YAML Form: 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['yamlform_email'] = [
      'title' => t('YAML Form: 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['yamlform_file_private'] = [
      'title' => t('YAML Form: Private files'),
      'value' => t('Private file system is set.'),
    ];
  }
  else {
    $requirements['yamlform_file_private'] = [
      'title' => t('YAML Form: 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\yamlform\YamlFormLibrariesManagerInterface $libraries_manager */
  $libraries_manager = \Drupal::service('yamlform.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 yamlform.settings.yml).
 * If you are moving or updating any admin settings this must be explicitly
 * done via an update hook.
 */
function _yamlform_update_admin_settings() {
  $admin_config = \Drupal::configFactory()
    ->getEditable('yamlform.settings');
  $current_settings = $admin_config
    ->getRawData();
  $admin_settings = Yaml::decode(file_get_contents(drupal_get_path('module', 'yamlform') . '/config/install/yamlform.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 form setting to reflect changes in the default settings.
 *
 * This function can be used to apply new form settings to all existing
 * forms.
 *
 * @see \Drupal\yamlform\Entity\YamlForm::setSettings
 */
function _yamlform_update_form_settings() {
  $default_properties = [
    'langcode' => 'en',
    'status' => TRUE,
    'dependencies' => [],
    'uid' => '',
    'template' => FALSE,
    'id' => '',
    'title' => '',
    'description' => '',
    'elements' => '',
    'css' => '',
    'javascript' => '',
    'settings' => [],
    'access' => [],
    'handlers' => [],
  ];
  $default_settings = YamlForm::getDefaultSettings();
  $config_factory = \Drupal::configFactory();

  // Update 'yamlform.yamlform.*' configuration.
  foreach ($config_factory
    ->listAll('yamlform.yamlform.') as $yamlform_config_name) {
    $yamlform_config = $config_factory
      ->getEditable($yamlform_config_name);

    // Get data.
    $data = $yamlform_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.
    $yamlform_config
      ->setData($data)
      ->save();
  }
}

/**
 * Issue #2834203: Convert yamlform field target_id to 32 characters.
 */
function yamlform_update_8075() {
  $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 form 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 yamlform_update_8076() {
  $config_factory = \Drupal::configFactory();

  // Update 'yamlform.settings' configuration.
  $settings_config = \Drupal::configFactory()
    ->getEditable('yamlform.settings');
  $yaml = Yaml::encode($settings_config
    ->getRawData());
  $yaml = str_replace('[yamlform_submission:', '[yamlform_submission:', $yaml);
  $settings_config
    ->setData(Yaml::decode($yaml));
  $settings_config
    ->save();

  // Update 'yamlform.yamlform.*' configuration.
  foreach ($config_factory
    ->listAll('yamlform.yamlform.') as $yamlform_config_name) {
    $yamlform_config = $config_factory
      ->getEditable($yamlform_config_name);
    $yaml = Yaml::encode($yamlform_config
      ->getRawData());
    $yaml = str_replace('[yamlform_submission:', '[yamlform_submission:', $yaml);
    $yamlform_config
      ->setData(Yaml::decode($yaml));
    $yamlform_config
      ->save();
  }
}

/**
 * Issue #2834654: Add close button to messages.
 */
function yamlform_update_8077() {

  // Change yamlform.* to yamlform.* state.
  $yamlforms = YamlForm::loadMultiple();
  foreach ($yamlforms as $yamlform) {
    $state = \Drupal::state()
      ->get('yamlform.' . $yamlform
      ->id(), NULL);
    if ($state !== NULL) {
      \Drupal::state()
        ->set('yamlform.yamlform.' . $yamlform
        ->id(), $state);
      \Drupal::state()
        ->delete('yamlform.' . $yamlform
        ->id());
    }
  }
}

/**
 * Issue #2836948: Problem with autocomplete field. Change '#autocomplete_options' to '#autocomplete_items'.
 */
function yamlform_update_8078() {
  $config_factory = \Drupal::configFactory();
  foreach ($config_factory
    ->listAll('yamlform.yamlform.') as $yamlform_config_name) {
    $yamlform_config = $config_factory
      ->getEditable($yamlform_config_name);
    $elements = $yamlform_config
      ->get('elements');
    if (strpos($elements, '#autocomplete_options') !== FALSE) {
      $elements = str_replace('#autocomplete_options', '#autocomplete_items', $elements);
      $yamlform_config
        ->set('elements', $elements);
      $yamlform_config
        ->save(TRUE);
    }
  }
}

/**
 * Issue #2837090: Undefined function call webform_schema.
 */
function yamlform_update_8079() {

  // @see yamlform_update_8080() which fixes this broken hook.
}

/**
 * Issue #2837090: Undefined function call webform_schema.
 */
function yamlform_update_8080() {

  // 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();
    }
  }
}

Functions

Namesort descending Description
yamlform_requirements Implements hook_requirements().
yamlform_uninstall Implements hook_uninstall().
yamlform_update_8075 Issue #2834203: Convert yamlform field target_id to 32 characters.
yamlform_update_8076 Issue #2834572: Refactor and improve token management.
yamlform_update_8077 Issue #2834654: Add close button to messages.
yamlform_update_8078 Issue #2836948: Problem with autocomplete field. Change '#autocomplete_options' to '#autocomplete_items'.
yamlform_update_8079 Issue #2837090: Undefined function call webform_schema.
yamlform_update_8080 Issue #2837090: Undefined function call webform_schema.
_yamlform_update_admin_settings Update admin settings to reflect changes in the default settings.
_yamlform_update_form_settings Update form setting to reflect changes in the default settings.