Aller au contenu principal

Mise en jour du schema des entités Drupal 9

Les entités permettent de gérer les données dans une ou plusieurs tables, au cours du développement des sites web ou applications nous sommes généralement amener à créer des entités.

Ces derniers évoluent en function des besoins. Lorsque cela se produit tout au debut du développement ( sans information importante en BD), nous pouvons vider nos tables et  utiliser le module Devel Entity Updates pour mettre à jour les schémas des table.

Mais si le besoin de mise à jour du schema des tables se fait ressentir plus tard, Drupal ne dispose pas pour le moment des API permettant de mettre cela à jour. Pour régler cela, nous devons écrire nos propres function de mise à jour.

Notre logique de mise à jour doit être implementer dans le hook hook_update_N. La logique de base est la suivante : Nous devons récupérer les données dans la table, vider cette dernière (généralement juste la colonne), appliquer la mise jour et réinjecter les données.

Cas pratique 1 : mise de la longueur (max_length) d'une colonne de type varchar.

nous disponsons d'un champs avec la configuration suivante :

...
$fields['name'] = BaseFieldDefinition::create('string')->setLabel(t('Name'))->setDescription(t('The name of the Site type datas entity.'))->setSettings([
      'max_length' => 50,
      'text_processing' => 0
    ])->setDefaultValue('')->setDisplayOptions('view', [
      'label' => 'above',
      'type' => 'string',
      'weight' => -4
    ])->setDisplayOptions('form', [
      'type' => 'string_textfield',
      'weight' => -4
    ])->setDisplayConfigurable('form', TRUE)->setDisplayConfigurable('view', TRUE)->setRequired(TRUE)->setTranslatable(true);
...

Nous souhaitons faire passer le max_length à 250.

function __blockscontent_update_name_max_length($entity_type_id) {
  /**
   *
   * @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $entityStorage
   */
  $entityStorage = \Drupal::entityTypeManager()->getStorage($entity_type_id);
  
  // Retrieve existing field data.
  $database = \Drupal::database();
  $table = $entity_type_id . '_field_data';
  $names = $database->select($table, 'et')->fields('et', [
    'id',
    'langcode',
    'name'
  ])->execute()->fetchAll(\PDO::FETCH_ASSOC);
  // Remove data from the column.
  $database->update($table)->fields([
    'name' => NULL
  ])->execute();
  //
  // si les revisions sont activées.
  if ($entityStorage->getRevisionTable()) {
    $table_revision = $entity_type_id . "_field_revision";
    $names_revision = $database->select($table_revision, 'et')->fields('et', [
      'id',
      'langcode',
      'name'
    ])->execute()->fetchAll(\PDO::FETCH_ASSOC);
    $database->update($table_revision)->fields([
      'name' => NULL
    ])->execute();
  }
  
  // Remove old definition field.
  $updateManager = \Drupal::entityDefinitionUpdateManager();
  $storagedef = $updateManager->getFieldStorageDefinition('name', $entity_type_id);
  $updateManager->uninstallFieldStorageDefinition($storagedef);
  // Load new definition field in code.
  /**
   *
   * @var \Drupal\Core\Entity\EntityFieldManager $fieldManager
   */
  $fieldManager = \Drupal::service('entity_field.manager');
  $fields = $fieldManager->getFieldStorageDefinitions($entity_type_id);
  $updateManager->installFieldStorageDefinition('name', $entity_type_id, "gestion_tache", $fields['name']);
  // Restore entity data in the new schema.
  foreach ($names as $name) {
    $database->update($table)->fields([
      'name' => $name['name']
    ])->condition('id', $name['id'])->condition('langcode', $name['langcode'])->execute();
  }
  // restore revision
  if ($entityStorage->getRevisionTable())
    foreach ($names_revision as $name) {
      $database->update($table_revision)->fields([
        'name' => $name['name']
      ])->condition('id', $name['id'])->condition('langcode', $name['langcode'])->execute();
    }
}

/**
 * Update value max_length from 50 to 250.
 *
 * implement hook_update_8001
 *
 * @see https://www.drupal.org/node/2554097
 */
function blockscontent_update_8001() {
  __blockscontent_update_name_max_length('blocks_contents');
}
Stephane K
Il y'a 1 year
Modifié
Il y'a 1 year
Loading ...