contacts_events-8.x-1.x-dev/contacts_events.install

contacts_events.install
<?php

/**
 * @file
 * Install and update code for the Contacts Events module.
 */

use Drupal\commerce_order\Entity\OrderItemType;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
use Drupal\Core\Entity\Sql\SqlContentEntityStorageException;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\entity\BundleFieldDefinition;
use Drupal\search_api\Item\Field;

/**
 * Implements hook_install().
 */
function contacts_events_install() {
  $fields['creator'] = BundleFieldDefinition::create('entity_reference')
    ->setName('creator')
    ->setLabel(t('Creator'))
    ->setTargetEntityTypeId('commerce_order')
    ->setTargetBundle('contacts_booking')
    ->setDescription(t('The user ID of the order creator.'))
    ->setRevisionable(TRUE)
    ->setSetting('target_type', 'user')
    ->setSetting('handler', 'default')
    ->setTranslatable(FALSE)
    ->setDisplayConfigurable('form', FALSE)
    ->setDisplayConfigurable('view', FALSE);

  $fields['state_log'] = BundleFieldDefinition::create('status_log')
    ->setName('state_log')
    ->setLabel(t('State History'))
    ->setTargetEntityTypeId('commerce_order')
    ->setTargetBundle('contacts_booking')
    ->setDescription(t('A log of when the status was changed and by whom.'))
    ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
    ->setSettings([
      'source_field' => 'state',
    ])
    ->setDisplayConfigurable('view', FALSE)
    ->setDisplayConfigurable('form', FALSE);

  foreach ($fields as $field_name => $field) {
    \Drupal::entityDefinitionUpdateManager()
      ->installFieldStorageDefinition($field_name, 'commerce_order', 'contacts_events', $field);
  }

  /** @var \Drupal\search_api\IndexInterface $index */
  $index = \Drupal::entityTypeManager()->getStorage('search_api_index')->load('contacts_index');

  if ($index) {
    // Create the Booking Manager booking reference field.
    $bm_field = new Field($index, 'bm_order_number');
    $bm_field->setType('text');
    $bm_field->setPropertyPath('ce_bookings_managed:entity:order_number');
    $bm_field->setDatasourceId('entity:user');
    $bm_field->setLabel('Bookings (manager) » Order » Order number');
    $bm_field->setBoost(8);

    // Create the Delegate booking reference field.
    $delegate_field = new Field($index, 'delegate_order_number');
    $delegate_field->setType('text');
    $delegate_field->setPropertyPath('ce_bookings_delegate:entity:order_number');
    $delegate_field->setDatasourceId('entity:user');
    $delegate_field->setLabel('Bookings (delegate) » Order » Order number');
    $delegate_field->setBoost(5);

    // Add to fields to the index.
    $index->addField($bm_field);
    $index->addField($delegate_field);
    $index->save();
  }

}

/**
 * Adds the creator field to Booking orders.
 */
function contacts_events_update_8001() {
  $field = BundleFieldDefinition::create('entity_reference')
    ->setLabel(t('Creator'))
    ->setTargetEntityTypeId('commerce_order')
    ->setTargetBundle('contacts_booking')
    ->setDescription(t('The user ID of the order creator.'))
    ->setRevisionable(TRUE)
    ->setSetting('target_type', 'user')
    ->setSetting('handler', 'default')
    ->setTranslatable(FALSE)
    ->setDisplayConfigurable('form', FALSE)
    ->setDisplayConfigurable('view', FALSE);

  \Drupal::entityDefinitionUpdateManager()
    ->installFieldStorageDefinition('creator', 'commerce_order', 'contacts_events', $field);
}

/**
 * Adds creator field to payments.
 */
function contacts_events_update_8002() {
  $field = BaseFieldDefinition::create('entity_reference')
    ->setName('creator')
    ->setTargetEntityTypeId('commerce_payment')
    ->setLabel(new TranslatableMarkup('Creator'))
    ->setDescription(new TranslatableMarkup('The user ID of the payment creator.'))
    ->setRevisionable(TRUE)
    ->setSetting('target_type', 'user')
    ->setSetting('handler', 'default')
    ->setTranslatable(FALSE)
    ->setDisplayConfigurable('form', FALSE)
    ->setDisplayConfigurable('view', FALSE);

  \Drupal::entityDefinitionUpdateManager()
    ->installFieldStorageDefinition('creator', 'commerce_payment', 'contacts_events', $field);
}

/**
 * Adds the link text overrides field.
 */
function contacts_events_update_8003() {
  $field = BaseFieldDefinition::create('contacts_events_text_overrides')
    ->setLabel('Link text overrides')
    ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
    ->setDisplayConfigurable('view', FALSE)
    ->setDisplayConfigurable('form', TRUE)
    ->setDisplayOptions('view', [
      'region' => 'hidden',
    ]);

  \Drupal::entityDefinitionUpdateManager()
    ->installFieldStorageDefinition('link_overrides', 'contacts_event', 'contacts_events', $field);
}

/**
 * Adds the settings field.
 */
function contacts_events_update_8004() {
  $field = BundleFieldDefinition::create('contacts_events_settings')
    ->setLabel('Settings')
    ->setDisplayConfigurable('view', FALSE)
    ->setDisplayOptions('view', ['region' => 'hidden'])
    ->setDisplayConfigurable('form', FALSE)
    ->setDisplayOptions('form', ['region' => 'hidden']);

  \Drupal::entityDefinitionUpdateManager()
    ->installFieldStorageDefinition('settings', 'contacts_event', 'contacts_events', $field);
}

/**
 * Adds the state log field to Booking orders.
 */
function contacts_events_update_8005() {
  $field = BundleFieldDefinition::create('status_log')
    ->setName('state_log')
    ->setLabel(t('Status History'))
    ->setTargetEntityTypeId('commerce_order')
    ->setTargetBundle('contacts_booking')
    ->setDescription(t('A log of when the status was changed and by whom.'))
    ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
    ->setSettings([
      'source_field' => 'state',
    ])
    ->setDisplayConfigurable('view', FALSE)
    ->setDisplayConfigurable('form', FALSE);

  \Drupal::entityDefinitionUpdateManager()
    ->installFieldStorageDefinition('state_log', 'commerce_order', 'contacts_events', $field);
}

/**
 * Install Booking Transfer payment gateway.
 */
function contacts_events_update_8006() {
  $config_name = 'commerce_payment.commerce_payment_gateway.booking_transfer';
  if (!\Drupal::service('config.storage')->exists($config_name)) {
    $config = \Drupal::configFactory()->getEditable($config_name);
    $values = [
      'uuid' => \Drupal::service('uuid')->generate(),
      'langcode' => 'en',
      'status' => FALSE,
      'dependencies' => [],
      'id' => 'booking_transfer',
      'label' => 'Booking Transfer',
      'weight' => 10,
      'plugin' => 'manual',
      'configuration' => [
        'instructions' => [
          'value' => '',
          'format' => 'plain_text',
        ],
        'display_label' => 'Booking Transfer',
        'mode' => 'n/a',
        'payment_method_types' => [
          'credit_card',
        ],
      ],
      'conditions' => [],
      'conditionOperator' => 'AND',
    ];

    foreach ($values as $id => $value) {
      $config->set($id, $value);
    }
    $config->save();
  }
}

/**
 * Add the cut_off_confirmed column to booking window field tables.
 */
function contacts_events_update_8007() {
  $schema = \Drupal::database()->schema();
  $entity_type_manager = \Drupal::entityTypeManager();
  /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
  $entity_field_manager = \Drupal::service('entity_field.manager');
  $entity_field_map = $entity_field_manager->getFieldMapByFieldType('booking_windows');
  $entity_storage_schema_sql = \Drupal::keyValue('entity.storage_schema.sql');
  $entity_definitions_installed = \Drupal::keyValue('entity.definitions.installed');

  foreach ($entity_field_map as $entity_type_id => $field_map) {
    $entity_storage = $entity_type_manager->getStorage($entity_type_id);
    // Only SQL storage based entities are supported / throw known exception.
    if (!($entity_storage instanceof SqlContentEntityStorage)) {
      continue;
    }

    $entity_type = $entity_type_manager->getDefinition($entity_type_id);
    $field_storage_definitions = $entity_field_manager->getFieldStorageDefinitions($entity_type_id);
    /** @var Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
    $table_mapping = $entity_storage->getTableMapping($field_storage_definitions);
    // Only need field storage definitions of booking windows fields.
    /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition */
    foreach (array_intersect_key($field_storage_definitions, $field_map) as $field_storage_definition) {
      $field_name = $field_storage_definition->getName();
      try {
        $table = $table_mapping->getFieldTableName($field_name);
        $cut_off_col_name = $table_mapping->getFieldColumnName($field_storage_definition, 'cut_off');
      }
      catch (SqlContentEntityStorageException $e) {
        // Custom storage? Broken site? No matter what, if there is no table
        // or column, there's little we can do.
        continue;
      }
      // See if the field has a revision table.
      $revision_table = NULL;
      if ($entity_type->isRevisionable() && $field_storage_definition->isRevisionable()) {
        if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) {
          $revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage_definition);
        }
        elseif ($table_mapping->allowsSharedTableStorage($field_storage_definition)) {
          $revision_table = $entity_type->getRevisionDataTable() ?: $entity_type->getRevisionTable();
        }
      }
      // Load the installed field schema so that it can be updated.
      $schema_key = "$entity_type_id.field_schema_data.$field_name";
      $field_schema_data = $entity_storage_schema_sql->get($schema_key);

      // Get the existing spec.
      $cut_off_spec = [
        'description' => 'The paid in full by date.',
        'type' => 'varchar',
        'length' => 20,
      ];

      // Update the new column.
      $schema->changeField($table, $cut_off_col_name, $cut_off_col_name, $cut_off_spec);
      if ($revision_table) {
        $schema->changeField($revision_table, $cut_off_col_name, $cut_off_col_name, $cut_off_spec);
      }

      // Update the existing column in the installed field schema.
      if ($field_schema_data) {
        $field_schema_data[$table]['fields'][$cut_off_col_name] = $cut_off_spec;
        $field_schema_data[$table]['fields'][$cut_off_col_name]['not null'] = FALSE;
        if ($revision_table) {
          $field_schema_data[$revision_table]['fields'][$cut_off_col_name] = $cut_off_spec;
        }
        $entity_storage_schema_sql->set($schema_key, $field_schema_data);
      }

      // Get the new column name and spec.
      $cut_off_confirmed_col_name = $table_mapping->getFieldColumnName($field_storage_definition, 'cut_off_confirmed');
      $cut_off_confirmed_spec = [
        'description' => 'The confirmed by date.',
        'type' => 'varchar',
        'length' => 20,
      ];

      // Add the new column.
      $install_spec = $cut_off_confirmed_spec + ['initial_from_field' => $cut_off_col_name];
      $schema->addField($table, $cut_off_confirmed_col_name, $install_spec);
      if ($revision_table) {
        $schema->addField($revision_table, $cut_off_confirmed_col_name, $install_spec);
      }

      // Add the new column to the installed field schema.
      if ($field_schema_data) {
        $field_schema_data[$table]['fields'][$cut_off_confirmed_col_name] = $cut_off_confirmed_spec;
        $field_schema_data[$table]['fields'][$cut_off_confirmed_col_name]['not null'] = FALSE;
        if ($revision_table) {
          $field_schema_data[$revision_table]['fields'][$cut_off_confirmed_col_name] = $cut_off_confirmed_spec;
        }
        $entity_storage_schema_sql->set($schema_key, $field_schema_data);
      }

      // Update the installed field storage definition.
      if ($table_mapping->allowsSharedTableStorage($field_storage_definition)) {
        $key = "$entity_type_id.field_storage_definitions";
        if ($definitions = $entity_definitions_installed->get($key)) {
          $definitions[$field_name] = $field_storage_definition;
          $entity_definitions_installed->set($key, $definitions);
        }
      }
    }
  }
}

/**
 * Add missing fields to order item bundles.
 */
function contacts_events_update_8008() {
  /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
  $entity_field_manager = \Drupal::service('entity_field.manager');
  /** @var \Drupal\Core\Field\FieldDefinitionListener $field_definition_listener*/
  $field_definition_listener = \Drupal::service('field_definition.listener');

  /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_manager */
  $bundle_manager = \Drupal::service('entity_type.bundle.info');
  $bundle_info = $bundle_manager->getBundleInfo('commerce_order_item');
  $order_item_types = OrderItemType::loadMultiple(array_keys($bundle_info));

  $state = [];

  foreach ($order_item_types as $order_item_type) {
    if ($order_item_type->getOrderTypeId() == 'contacts_booking') {
      // Check each bundle for commerce_order_item. If it's for the booking
      // order type, add the state and confirmed fields if they don't have it
      // already.
      $field_definitions = $entity_field_manager->getFieldDefinitions('commerce_order_item', $order_item_type->id());
      if (!isset($field_definitions['state'])) {
        $state_field = BundleFieldDefinition::create('state')
          ->setName('state')
          ->setTargetEntityTypeId('commerce_order_item')
          ->setTargetBundle($order_item_type->id())
          ->setLabel(new TranslatableMarkup('State'))
          ->setDescription(new TranslatableMarkup('The order item state.'))
          ->setRequired(TRUE)
          ->setSetting('max_length', 255)
          ->setSetting('workflow', 'contacts_events_order_item_process')
          ->setDisplayOptions('view', [
            'label' => 'hidden',
            'type' => 'state_transition_form',
            'weight' => 10,
          ])
          ->setDisplayConfigurable('form', TRUE)
          ->setDisplayConfigurable('view', TRUE);

        $field_definition_listener->onFieldDefinitionCreate($state_field);
        $state[$order_item_type->id()][] = 'state';
      }
      if (!isset($field_definitions['confirmed'])) {
        $confirmed_field = BundleFieldDefinition::create('timestamp')
          ->setName('confirmed')
          ->setTargetEntityTypeId('commerce_order_item')
          ->setTargetBundle($order_item_type->id())
          ->setLabel(new TranslatableMarkup('Confirmed'))
          ->setDescription(new TranslatableMarkup('The time when the order item was confirmed.'))
          ->setReadOnly(TRUE)
          ->setDisplayConfigurable('form', FALSE)
          ->setDisplayConfigurable('view', TRUE);

        $field_definition_listener->onFieldDefinitionCreate($confirmed_field);
        $state[$order_item_type->id()][] = 'confirmed';
      }
    }
  }

  if (!empty($state)) {
    // Cache which fields were created so they can be populated using the
    // populate-order-item-missing-fields.php script.
    \Drupal::state()->set('contacts_events_install_order_item_fields', $state);
  }
}

/**
 * Migrate rules expression to new date range config.
 */
function contacts_events_update_8009() {
  // Load all event classes.
  $storage = \Drupal::entityTypeManager()->getStorage('contacts_events_class');
  /** @var \Drupal\contacts_events\Entity\EventClass[] $classes */
  $classes = $storage->loadMultiple();
  $to_save = [];

  foreach ($classes as $class) {
    $expr = $class->get('expression');
    $min_age = NULL;
    $max_age = NULL;

    if (!empty($expr)) {
      if ($expr['id'] !== 'rules_and') {
        throw new \Exception("Can't automatically migrate class {$class->label()}");
      }

      foreach ($expr['conditions'] as $condition) {
        if (isset($condition['context_values']['operation']) && $condition['context_values']['operation'] == '<') {
          if ($condition['context_mapping']['data'] != 'order_item.purchased_entity.entity.date_of_birth.date') {
            throw new \Exception("Can't automatically migrate class {$class->label()} - not acting upon DOB.");
          }

          if (isset($min_age)) {
            throw new \Exception("Can't automatically migrate class {$class->label()} - found multiple minimum ages");
          }

          if (empty($condition['context_processors']['value'])) {
            // No minimum.
            continue;
          }

          $interval = $condition['context_processors']['value']['rules_dynamic_date']['interval'] ?? NULL;

          if ($interval == NULL) {
            throw new \Exception("Can't automatically migrate class {$class->label()} - can't find date interval.");
          }

          if (substr($interval, 0, 1) !== 'P' || substr($interval, -1) !== 'Y') {
            throw new \Exception("Can't automatically migrate class {$class->label()} - interval in wrong format");
          }

          $age = substr($interval, 1, strlen($interval) - 2);

          if (!is_numeric($age)) {
            throw new \Exception("Couldn't migrate class {$class->label()} - can't extract min age");
          }

          $min_age = (int) $age;
        }
        elseif (isset($condition['context_values']['operation']) && $condition['context_values']['operation'] == '>') {
          if ($condition['context_mapping']['data'] != 'order_item.purchased_entity.entity.date_of_birth.date') {
            throw new \Exception("Can't automatically migrate class {$class->label()} - not acting upon DOB.");
          }

          if (isset($max_age)) {
            throw new \Exception("Can't automatically migrate class {$class->label()} - found multiple max ages");
          }

          if (empty($condition['context_processors']['value'])) {
            // No maximum.
            continue;
          }

          $interval = $condition['context_processors']['value']['rules_dynamic_date']['interval'] ?? NULL;

          if ($interval == NULL) {
            throw new \Exception("Can't automatically migrate class {$class->label()} - can't find date interval.");
          }

          if (substr($interval, 0, 1) !== 'P' || substr($interval, -1) !== 'Y') {
            throw new \Exception("Can't automatically migrate class {$class->label()} - interval in wrong format");
          }

          $age = substr($interval, 1, strlen($interval) - 2);

          if (!is_numeric($age)) {
            throw new \Exception("Couldn't migrate class {$class->label()} - can't extract min age");
          }

          $age = (int) $age;
          // Old format max age is exclusive, so decrement by 1.
          $age--;

          $max_age = $age;
        }
      }
    }

    if ($min_age !== NULL) {
      $class->set('min_age', $min_age);
    }
    if ($max_age !== NULL) {
      $class->set('max_age', $max_age);
    }

    $to_save[] = $class;
  }

  foreach ($to_save as $entity) {
    $entity->save();
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc