You are here

function date_recur_update_8203 in Recurring Dates Field 8.2

Same name and namespace in other branches
  1. 3.x date_recur.install \date_recur_update_8203()
  2. 3.0.x date_recur.install \date_recur_update_8203()
  3. 3.1.x date_recur.install \date_recur_update_8203()

Checks for invalid time zones in storage.

File

./date_recur.install, line 159

Code

function date_recur_update_8203(&$sandbox) : void {
  $timeZoneList = timezone_identifiers_list();
  $database = \Drupal::database();
  $entityTypeManager = \Drupal::entityTypeManager();
  $entityFieldManager = \Drupal::service('entity_field.manager');
  $entityFieldMap = $entityFieldManager
    ->getFieldMapByFieldType('date_recur');

  // Iterate over all date_recur fields for all entity types.
  foreach ($entityFieldMap as $entityTypeId => $fields) {
    $entityStorage = $entityTypeManager
      ->getStorage($entityTypeId);
    if (!$entityStorage instanceof SqlEntityStorageInterface) {
      continue;
    }

    // Loads definitions for all fields (even non date_recur).
    $entityFieldStorageDefinitions = $entityFieldManager
      ->getFieldStorageDefinitions($entityTypeId);

    /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $tableMapping */
    $tableMapping = $entityStorage
      ->getTableMapping($entityFieldStorageDefinitions);

    // Intersect date_recur fields with storage definitions for all fields.

    /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] $fieldDefinitions */
    $fieldDefinitions = array_intersect_key($entityFieldStorageDefinitions, $fields);

    // Iterate over all date_recur field definitions for this entity type.
    foreach ($fieldDefinitions as $fieldDefinition) {
      $fieldName = $fieldDefinition
        ->getName();
      $table = $tableMapping
        ->getFieldTableName($fieldName);

      // Field type column names map to real table column names.
      $columns = $tableMapping
        ->getColumnNames($fieldName);
      $timeZoneColumnName = $columns['timezone'];
      $select = $database
        ->select($table, 'field_table');
      $select
        ->addField('field_table', $timeZoneColumnName);
      $select
        ->distinct();
      $result = $select
        ->execute();
      if (!$result) {
        throw new \Exception('Problem executing query.');
      }
      $allTimeZones = $result
        ->fetchCol($timeZoneColumnName);
      $diff = array_diff($allTimeZones, $timeZoneList);
      if (count($diff)) {

        // This exception prevents further updates from happening until it is
        // resolved.
        throw new UpdateException(sprintf('Invalid time zones found for field `%s` in table `%s`: `%s`. Please resolve these invalid values manually before continuing.', $fieldName, $table, implode(', ', $diff)));
      }
    }
  }
}