Score:0

Run an update hook after specific configuration has been imported?

in flag

I am introducing new configuration to an entity in Drupal that adds a few new boolean fields. The problem is, even though I set the default value as TRUE in the UI, this is only for new entities. Existing entities will have no value, or false, when evaluated in code.

I would like to script a change in that will default all existing entities to TRUE when the configuration is introduced for backwards compatibility, and only run it that one time.

Typical deployment scripts advise running updb first before cim with Drush. This creates a conflict when trying to attempt this.

Pantheon deployment script example:

if (isset($_ENV['PANTHEON_ENVIRONMENT'])) {
  $status = 0;
  $config_directory = dirname(__FILE__) . '/config/default';

  passthru("drush updb --yes", $status);
  passthru("drush cim --yes", $status);
  passthru("drush cim --yes", $status);
  passthru("drush cim --yes", $status);
  passthru("drush updb --yes", $status);
  passthru("drush cr", $status);

  if ($status == 0) {
    echo('Configuration imported and database updated.' . "\n");
  } else {
    echo('Configuration not imported / database not updated. Drush command returned an error.' . "\n");
  }
}

Is there a better way to do changes like this that only run once without causing script like the one above to fail?

cn flag
The only option I've come across in these cases is to add the fields programatically in the update hook, before you set the data. The config import for those fields will then essentially become a no-op, but it means you don't need to change your deployment
cn flag
Incidentally, Pantheon seem to run `updb` and `cim` an...interesting number of times. Typically you would only do both once like [drush does](https://www.drush.org/latest/deploycommand/)
Kevin avatar
in flag
That is patterned off what folks advised for deployments in the past - CIM is exhausted, updb is run first before cim, then at the end ' in case' other updates are required. I never found any additional update around that process either, but its been pretty bulletproof on Pantheon and Acquia to date.
cn flag
Not sure that really makes sense - either all the updates run first time, or the build should fail. The only way to introduce new updates following `updb` is a code change, at which point it's a new deployment and you're back on the first `updb` again. But that's not really what you're asking about so I'll shush now
Kevin avatar
in flag
Is it a case for this, maybe? https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension%21module.api.php/function/hook_post_update_NAME/9.2.x
cn flag
That hook still runs as part of `updb`, just at the end. You either need to change the deployment and run the cim first, or keep the deployment the same and create the fields yourself first. I don’t think there would be another logical option, although this happens to me often enough that I’d be delighted to hear of an easier solution
sonfd avatar
in flag
re @clive's first comment, I've used something like this in the past to import the config in an update hook to do just this sort of thing: https://www.metaltoad.com/blog/programmatically-importing-drupal-8-field-configurations
Score:3
ph flag

You can use drush deploy, which performs updates in this order:

  1. Update hooks from module.install
  2. cim
  3. cr
  4. Deploy hooks from module.deploy.php

So converting your update hook to a deploy hook means it will run after the config import.

cn flag
This has the same problem as the OP’s original deploy code - the new config won’t be imported before the update hook tries to use it
Lambic avatar
ph flag
Moving the update hook to a deploy hook means it runs after import
cn flag
Ah yes, I didn't get that first time round. May be worth mentioning the need to add (e.g.) `passthru('drush deploy:hook', $status);` if OP wants to run their own script instead of `drush deploy` directly
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.