During core updates or module updates, it is crucial to ensure the stability and integrity of your Drupal website. Luckily, the Update API module and Update/Post Update Hooks are here to help.

The Update API module provides the hooks that are necessary for updating code and modules on your Drupal site. These hooks are nothing but Update and Post-Update Hooks which allow developers to customize updates according to their needs.

In this article, we’ll discuss the Update API, what are update and post-update hooks and when and how they should be used. By understanding both types of hooks, you can successfully update your Drupal site with minimal effort. Let’s get started!

Update and post update hooks

The Update API

While working on an existing site, when you update code in a module, you may need to update stored data so that the stored data is compatible with the new code. You might have noticed errors like ‘The website encountered an unexpected error’ flash in front of you. Scary right!? I know! This is where Drupal’s Update API comes to our rescue.

If the update is between two minor versions of your module within the same major version of Drupal core, you can use the Update API to update the data. Update API allows you to provide code that performs an update to stored data whenever your module makes a change to its data model. The data model change refers to any change that makes the stored data on an existing site incompatible with that site's updated codebase. These Data model changes involve:

Updating the Configuration Schema

  • Adding/removing/renaming a configuration key.
  • Changing the data type of the configuration key.
  • Changing the expected default value of a configuration key, etc.

Updating the Database Schema

  • Adding/changing/removing a database table or field.
  • Moving the stored data to a different field or table.
  • Changing the format of stored data, etc.

Updating the Entities & Fields

  • Adding a new base field to an existing entity type.
  • Updating a field from an obsolete type to a new type, etc.

Updating the Data

  • Manipulate the stored data on an existing site.

Working with Update hooks

Hook hook_update_N() is used to introduce an update between minor versions of a module. These hooks are placed within your module in the *.install file.

The hook_update_N() is written in the form of (module name)_update_(number). Here N comprises of:

  • 1 or 2 digits refer to the  Drupal core compatibility (Drupal 8, 9, 10, etc.)
  • The next 1 digit is for your module's major release version
  • The last 2 digits for sequential counting, starting with 01

Example:

example_update_9201(): The first update for the 9.x-2.x versions.
Where ‘example’ is the name of the module, the first digit refers to Drupal core version ‘9’, the number ‘2’ refers to the module’s major release version and the last two digits ‘01’ indicates the first update function written for module ‘example’.

The numeric part of the hook implementation function (i.e, 9201 in the above example) is stored in the database to keep track of which updates have already been executed. So you should never renumber update functions.
To know the current schema version of a module ‘example stored in database’, use:

drush php-eval "echo drupal_get_installed_schema_version(‘example’);"

schema version

 

To manually set the current schema version of a module ‘example’ back to ‘9201’, use:

drush php-eval "echo drupal_set_installed_schema_version('example', '9201');"

manually configure schema

 

Note: Please try to avoid using  drupal_set_installed_schema_version() function on production sites as it directly updates your database. You can use it on your local or lower test environments during development to reset the schema version.

Add a proper description in the document block comment before the update hook function as it will be printed for the users while running it.

Structure of hook_update_N():
/**
 * A aimple hook_update_N() hook.
 */
function example_update_9201() {
 // Code goes here.
}

These hooks are executed in sorted order, i.e., example_update_9201() hook executes before example_update_9202(), next is 9203, 9204 and so on.

You can also change the sorted order of these hooks, by introducing dependencies between the hooks. Use the hook hook_update_dependencies() to run updates between two update hooks.

React component

 

All the update hooks are executed in batch and they also support batch processing of items. All update hooks have access to a $sandbox parameter which can be used to create batch processes in the update hooks in order to process huge data at once without causing any PHP to timeout.

A simple example of an update hook to add a new configuration key:

Currently, the example_module.settings.yml file contains:

Module setting

 

Update hook

 

To add a new key ‘description’ to the configuration:

  • Add the ‘description’ key to the settings file

Configuration description

 

  • Add the update_hook in example_module.install file:

install module

 

  • Use  drush updb to run the hook.

Implement hook update

 

  • Check the updated configuration, the new key ‘description’ is updated.

Configuration description

Working with Post Update hooks

Hook hook_post_update_NAME(), similar to the update hook, is used to introduce an update. But this hook is mostly intended to update data, like entities. These hooks are executed after all the hook_update_N() hooks are run. At this stage, Drupal is already fully repaired so you can use any API within the site.

These hooks are placed in a *.post_update.php file in your module.

The hook_post_update_NAME()is written in the form of (module name)_post_update_(any name). Here NAME can be any arbitrary machine name. This alphanumeric naming of functions in the file is the only thing that ensures the execution order of this hook.

Similar to update hooks, add a proper description in the docblock comment before the post_update hook. Also, do not reuse the same hook name.

Structure of hook_post_update_NAME():

/**
 * A aimple hook_post_update_NAME() hook. 
 */ 
function example_post_update_test() {
  // Code goes here.
}

Just like with update hooks, use the $sandbox parameter to indicate that the Batch API should be used for your post_update hooks.

A simple example on the usage of post-update hook to update the term data:

  • Currently, all the terms under Tags vocabulary have a disabled ‘Test example’ field.

Edit term

  • Add a post_update hook in example_module.post_update.php file to enable the ‘Test example’ field for all the existing terms.

post update

 

  • Use  drush updb to run the hook.

drush updb

 

  • Verify the updated term data, the checkbox ‘Test example’ must be enabled.

term data

How to Run these hooks!

You can use the Drush command to execute these hooks, drush updb.It builds the batch in the following steps:

  • All the update hooks are discovered.
  • Resolves dependency and sort their order.
  • Hooks are placed for batch processing.
  • Next, all the Post hooks are discovered.
  • If there are post_update hooks, and if update_hook has run previously, then caches are cleared.
  • Then, push each post_update hook into the batch.
  • Execute the batch.

One major advantage the post-update hook has over the update hook is that Drupal is fully functional at the time post-update is run. This allows developers to use any Drupal services while using the post-update hook. With the update hook, one must not assume that Drupal is fully repaired and avoid invoking other hooks, entity APIs, etc.

Final Thoughts

When trying to fix your site by updating config/database schema try to use update hooks. When comes to manipulating stored data, resaving configs, updating content entities, clearing the cache, etc then post-update hooks are more appropriate to use.

To be honest, there is no clear documentation on Drupal.org regarding when to use which hook! There is an open issue requesting to improve documentation on the usage of these two hooks to which you can contribute if you like.

But based on the developers' experience and by looking at the Drupal 9 & 10 core modules as an example, use update hooks to perform CRUD operations on configurations or databases (i.e repair the site) and use post-update hooks for CRUD content entities (then fix the data on the updated site), as post-update hooks are run after update hooks.

Enjoyed reading this article? Show us some love and subscribe to our weekly newsletter today!

Contact us

LET'S DISCUSS YOUR IDEAS. 
WE'D LOVE TO HEAR FROM YOU.

CONTACT US