In multi-environment deployments of Drupal, update hooks can be useful for populating initial data for new content types/containers. There are obviously better ways of deploying content between environments. However, some setups might require populating data even in the lowest-tier environments that may even be configured for blue-green deployment. Below is a simple example of an update hook that reads data from a JSON file and loads it into custom entities.
Data Source: JSON File
The data we provide to the update hook can come from anywhere -- internal systems, external APIs, etc. For this demo, we are using a simple JSON file like the one below:
[
{
"name": "Peace Prize",
"description": "The Nobel Peace Prize is awarded by a <a href=\"https://www.nobelprize.org/about/the-norwegian-nobel-committee/\">committee</a> elected by the Norwegian Parliament (Stortinget)."
},
{
"name": "Physics Prize",
"description": "The Nobel Prize in Physics is awarded by <a href=\"https://www.nobelprize.org/about/the-royal-swedish-academy-of-sciences-3/\">The Royal Swedish Academy of Sciences</a>, Stockholm, Sweden."
}
]
We can put this JSON file inside the custom module (i.e., mymodule/data/data.json). We then iterate over the data in a custom function and save each object as a custom entity.
<?php
use Drupal\mymodule\Entity\MyModuleNobelLeaureate;
/**
* Populate data from file into custom entity.
*/
function _mymodule_populate_data() {
// Read data from file.
$data = file_get_contents(dirname(__FILE__) . '/data/prizes.json');
$prizes = json_decode($data);
// Save each item as an entity.
if (!empty($prizes)) {
$storage = \Drupal::entityTypeManager()->getStorage('nobel_prize');
foreach ($prizes as $prize) {
// Check if an entity already exists.
$q = $storage->loadByProperties(['name' => $prize->name]);
if (empty($q)) {
$new_entry = MyModuleNobelLeaureate::create([
'name' => $prize->name,
'description' => [
'value' => $prize->description,
'format' => 'full_html',
],
]);
$new_entry->save();
}
}
}
}
Update Hook
Now that we have a custom function to read the data. We need to call it when the module is enabled or, if it is already enabled, as an update hook so it executes when drush updb
is called. The update hook is a power concept. It allows us to make all kinds of changes with full confidence. We can test deployments at lower environments by simply running it against production baseline.
Here are our hook_install()
and update_hook_N()
functions inside mymodule.install
:
<?php
/**
* Implements hook_install().
*/
function mymodule_install() {
// Import data from JSON file.
_mymodule_populate_data();
}
/**
* Import data.
*/
function mymodule_update_8101() {
_mymodule_populate_data();
}