Drupal 8  8.0.2
Update API

Data Structures

class  UpdatePathTestBase
 

Functions

 hook_update_N (&$sandbox)
 
 hook_update_dependencies ()
 
 hook_update_last_removed ()
 
 hook_updater_info ()
 
 hook_updater_info_alter (&$updaters)
 

Detailed Description

Updating minor versions of modules

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. If this update is between two minor versions of your module within the same major version of Drupal, you can use the Update API to update the data. This API is described in brief here; for more details, see https://www.drupal.org/node/2535316. If you are updating your module for a major version of Drupal (for instance, Drupal 7 to Drupal 8), updates will not run and you will need to use the Migrate API instead.

When to write update code

You need to provide code that performs an update to stored data whenever your module makes a change to its data model. A data model change is any change that makes stored data on an existing site incompatible with that site's updated codebase. Examples:

How to write update code

Update code for a module is put into an implementation of hook_update_N(), which goes into file mymodule.install (if your module's machine name is mymodule). See the documentation of hook_update_N() and https://www.drupal.org/node/2535316 for details and examples.

Testing update code

Update code should be tested both manually and by writing an automated test. Automated tests for update code extend – see that class for details, and find classes that extend it for examples.

See Also
Migration API

Function Documentation

hook_update_dependencies ( )

Return an array of information about module update dependencies.

This can be used to indicate update functions from other modules that your module's update functions depend on, or vice versa. It is used by the update system to determine the appropriate order in which updates should be run, as well as to search for missing dependencies.

Implementations of this hook should be placed in a mymodule.install file in the same directory as mymodule.module.

Returns
A multidimensional array containing information about the module update dependencies. The first two levels of keys represent the module and update number (respectively) for which information is being returned, and the value is an array of information about that update's dependencies. Within this array, each key represents a module, and each value represents the number of an update function within that module. In the event that your update function depends on more than one update from a particular module, you should always list the highest numbered one here (since updates within a given module always run in numerical order).
See Also
update_resolve_dependencies()
hook_update_N()
hook_update_last_removed ( )

Return a number which is no longer available as hook_update_N().

If you remove some update functions from your mymodule.install file, you should notify Drupal of those missing functions. This way, Drupal can ensure that no update is accidentally skipped.

Implementations of this hook should be placed in a mymodule.install file in the same directory as mymodule.module.

Returns
An integer, corresponding to hook_update_N() which has been removed from mymodule.install.
See Also
hook_update_N()
hook_update_N ( $sandbox)

Perform a single update between minor versions.

hook_update_N() can only be used to update between minor versions of a module. To upgrade between major versions of Drupal (for example, between Drupal 7 and 8), use the Migrate API instead.

Naming and documenting your function

For each change in a module that requires one or more actions to be performed when updating a site, add a new implementation of hook_update_N() to your mymodule.install file (assuming mymodule is the machine name of your module). Implementations of hook_update_N() are named (module name)_update_(number). The numbers are normally composed of three parts:

  • 1 or 2 digits for Drupal core compatibility (Drupal 8, 9, 10, etc.). This convention must be followed.
  • 1 digit for your module's major release version; for example, for 8.x-1.* use 1, for 8.x-2.* use 2, for Core 8.0.x use 0, and for Core 8.1.x use 1. This convention is optional but suggested for clarity.
  • 2 digits for sequential counting, starting with 01. Note that the x000 number can never be used: the lowest update number that will be recognized and run for major version x is x001. Examples:
  • node_update_8001(): The first update for the Drupal 8.0.x version of the Drupal Core node module.
  • mymodule_update_8101(): The first update for your custom or contributed module's 8.x-1.x versions.
  • mymodule_update_8201(): The first update for the 8.x-2.x versions.

Never renumber update functions. The numeric part of the hook implementation function is stored in the database to keep track of which updates have run, so it is important to maintain this information consistently.

The documentation block preceding this function is stripped of newlines and used as the description for the update on the pending updates task list, which users will see when they run the update.php script.

Notes about the function body

Writing hook_update_N() functions is tricky. There are several reasons why this is the case:

  • You do not know when updates will be run: someone could be keeping up with every update and run them when the database and code are in the same state as when you wrote your update function, or they could have waited until a few more updates have come out, and run several at the same time.
  • You do not know the state of other modules' updates either.
  • Other modules can use hook_update_dependencies() to run updates between your module's updates, so you also cannot count on your functions running right after one another.
  • You do not know what environment your update will run in (which modules are installed, whether certain hooks are implemented or not, whether services are overridden, etc.).

Because of these reasons, you'll need to use care in writing your update function. Some things to think about:

  • Never assume that the database schema is the same when the update will run as it is when you wrote the update function. So, when updating a database table or field, put the schema information you want to update to directly into your function instead of calling your hook_schema() function to retrieve it (this is one case where the right thing to do is copy and paste the code).
  • Never assume that the configuration schema is the same when the update will run as it is when you wrote the update function. So, when saving configuration, use the $has_trusted_data = TRUE parameter so that schema is ignored, and make sure that the configuration data you are saving matches the configuration schema at the time when you write the update function (later updates may change it again to match new schema changes).
  • Never assume your field or entity type definitions are the same when the update will run as they are when you wrote the update function. Always retrieve the correct version via ::entityDefinitionUpdateManager()::getEntityType() or ::entityDefinitionUpdateManager()::getFieldStorageDefinition(). When adding a new definition always replicate it in the update function body as you would do with a schema definition.
  • Never call ::entityDefinitionUpdateManager()::applyUpdates() in an update function, as it will apply updates for any module not only yours, which will lead to unpredictable results.
  • Be careful about API functions and especially CRUD operations that you use in your update function. If they invoke hooks or use services, they may not behave as expected, and it may actually not be appropriate to use the normal API functions that invoke all the hooks, use the database schema, and/or use services in an update function – you may need to switch to using a more direct method (database query, etc.).
  • In particular, loading, saving, or performing any other CRUD operation on an entity is never safe to do (they always involve hooks and services).
  • Never rebuild the router during an update function.

The following actions are examples of things that are safe to do during updates:

  • Cache invalidation.
  • Using ::configFactory()->getEditable() and ::config(), as long as you make sure that your update data matches the schema, and you use the $has_trusted_data argument in the save operation.
  • Marking a container for rebuild.
  • Using the API provided by ::entityDefinitionUpdateManager() to update the entity schema based on changes in entity type or field definitions provided by your module.

See https://www.drupal.org/node/2535316 for more on writing update functions.

Batch updates

If running your update all at once could possibly cause PHP to time out, use the $sandbox parameter to indicate that the Batch API should be used for your update. In this case, your update function acts as an implementation of callback_batch_operation(), and $sandbox acts as the batch context parameter. In your function, read the state information from the previous run from $sandbox (or initialize), run a chunk of updates, save the state in $sandbox, and set $sandbox['#finished'] to a value between 0 and 1 to indicate the percent completed, or 1 if it is finished (you need to do this explicitly in each pass).

See the Batch operations topic for more information on how to use the Batch API.

Parameters
array$sandboxStores information for batch updates. See above for more information.
Returns
string|null Optionally, update hooks may return a translated string that will be displayed to the user after the update has completed. If no message is returned, no message will be presented to the user.
Exceptions
\Drupal\Core\Utility\UpdateException|PDOExceptionIn case of error, update hooks should throw an instance of Drupal with a meaningful message for the user. If a database query fails for whatever reason, it will throw a PDOException.
See Also
Batch operations
Schema API
hook_update_last_removed()
update_get_update_list()
node_update_8001
system_update_8004
https://www.drupal.org/node/2535316

References t().

Here is the call graph for this function:

hook_updater_info ( )

Provide information on Updaters (classes that can update Drupal).

Drupal is a class that knows how to update various parts of the Drupal file system, for example to update modules that have newer releases, or to install a new theme.

Returns
An associative array of information about the updater(s) being provided. This array is keyed by a unique identifier for each updater, and the values are subarrays that can contain the following keys:
  • class: The name of the PHP class which implements this updater.
  • name: Human-readable name of this updater.
  • weight: Controls what order the Updater classes are consulted to decide which one should handle a given task. When an update task is being run, the system will loop through all the Updater classes defined in this registry in weight order and let each class respond to the task and decide if each Updater wants to handle the task. In general, this doesn't matter, but if you need to override an existing Updater, make sure your Updater has a lighter weight so that it comes first.
See Also
drupal_get_updaters()
hook_updater_info_alter()

References t().

Here is the call graph for this function:

hook_updater_info_alter ( $updaters)

Alter the Updater information array.

An Updater is a class that knows how to update various parts of the Drupal file system, for example to update modules that have newer releases, or to install a new theme.

Parameters
array$updatersAssociative array of updaters as defined through hook_updater_info(). Alter this array directly.
See Also
drupal_get_updaters()
hook_updater_info()