 This session is about update hooks, post update hooks specially and hook update and available in core. So my name is Gibran Ijaz and I am a core developer. I have more than 300 commit squared in ruble 8. And I'm maintaining contact and shortcuts modules in core. And I also maintain some handful of contrib modules. So I work with previous next and previous at previous next we built large ruble websites. And some kind of similar flow we've kind of followed some kind of similar flow as my colleague discussed earlier in the presentation. And I'm going to talk in depth about update hooks and post update hooks and the new functionality we have added, why we need the post update hook in ruble 8 and why update hooks are there for us. First of all, let's discuss what is an update system? Why we need an update system? We need an update system because we want to make changes to our configuration on the website. We want to change site name in this particular example. We are removing the system filter settings from configuration factory. Then we want to make changes to the database tables. In this particular example, we are changing, adding, or dropping the index on a particular table. Or maybe we want to update the content so we can do that in post update hook. In this particular example, we are copying the values from one table to another. And these are the changes. Update system, update hooks and update system is there to provide us API to make these changes. Let's discuss some conventions about update hooks. So first of all, we all know this hook has been there forever, like hook update. Then we put it in install file. Install file is the file which is loaded on install or during the update process. And that piece of code is only executed on demand whenever needed during either installation or update process. So let's talk about the nomenclature of the update hook. In this particular update hook, we have n at the end, which has a significant importance. In this example, because the first digit of n represents the core version, the major version. If it's 7, it will be 7. And in Drupal 8, it will be 8. And in Drupal 10, we will see how we will tackle this situation. But for all major versions, for Drupal 8, it's 8. And the second digit, if you are writing an update hook for core, then the second digit is the minor version of the release. If you are using it in Contrib, then it's a major version of your Contrib module. There's a mismatch in that. The community is still working on figuring out the ways and steps how we can improve this. So let's hope we'll have some solution soon about this. Then last two digits are just the sequence numbers to make that possible that this sequence can be used for once. So last but not the least, the functional documentation of the block on top of update hook is used to identify the hook name or the things hook is doing, going to do. So we are using that in Drush and Update Hook UI. So if we look at meta tag.install in Contrib, this is the install file. As you can see, we have installed hook here. And the first hook update n is 8.101 because it's 1.x version of meta tag. It's compatible with Drupal 8. And this is the first hook. And they are changing some field storage settings. Let's take a deep dive in the theory of Update Hooks. So the numeric part of the Update Hook, as we discussed in detail in previous example, that it is a schema version. And it is stored in database. And that's why you are not allowed to rename your Update Hooks once the schema version is changed. It's changed forever. You cannot go back to previous schema until unless you write some script to revert those changes. But we can only go forward. And maybe in the next Update Hook, you can revert previous Update Hook changes. So because it's a sequence number, they are executed in sorted order. And the Update Hooks all are executed in batch processes and can use batch processing as well. Last thing, which is very important, that the order of Update Hooks can be changed. The execution of Update Hooks order can be changed. And for that, we use Hooked Update Dependencies. So for this particular case, as you can see on the left, we want to execute Update Hooks in particular order that Test Module 2 wants to execute 801. And then we want to execute Test Module 3, 801, and then 802, and so on and so forth. So what we are doing here, essentially, in the Hooked Update Dependencies, as you can see on the right side, for Test Module 3, we are adding a dependency on Test Module 2, 801 Hook. And similarly, in Test Module 2, we are adding 802 dependency on 801. So when the Update System will sort the order of execution of hooks, this is going to be calculated using these hook dependencies, and then we can go and make our changes and making sure that our sorting order is correct. Similarly, this is very important for Contrib modules, because sometimes right after some core updates, we want to execute our update. And if there is no way to do that, then there will be no way to make changes in right order and correct format. So this is a very important API thing. So let's talk about some do's and don'ts of Update Hooks, some things we shouldn't do in Update Hooks, something like invalidating the cache we should do in Update Hooks. We shouldn't clear the cache, because cache tables can be changed. We can change the structure of caching. We may be adding a new cache table or removing some cache table. So always invalidate the cache, because if you invalidate the cache at the end of the execution of all the Update Hooks, we will clear the cache, and that would be it. Similarly, if you want to change the configuration on the website, just use the config factory editable command as listed here, because we don't want to make changes directly to schema. We want to make sure that we make changes on config objects, and we are not making changes directly without any validation of the factory method. Similarly, if you want to read and just want to process those values, you can just use config function directly. Another thing which is very important, during the Update Hooks, we still use container, the dependency section container. So it is a minimal container, but it is still very helpful and useful. So do not rebuild your container during any Post Update Hook. Always mark it for the rebuilding so that once the execution is finished, the container should be rebuilt properly. And similarly, Entity Schema depends heavily on configuration in core and container services, so you cannot update the Entity Schema as well without making sure that these things are there, and you can update Entity Schema as well. So some don'ts. As discussed earlier, that cache table can be worked on. The structure can be changed in Update Hooks. So never assume any DB table schema. Always add check and balances around that and make sure that specific column and with the specific property there is proper API in core to use all this function. So use that. Similarly, configuration schema is another thing. You can update the existing structure. You can remove the config schema keys from the config structure. So never assume the schema structure there as well. And similarly, it's true for Entity Updates, Entity Tables as well, because they are using database table and field configuration. So you cannot do with Entity Tables as well. The most important thing here is that if you want to process entities, you cannot do that in Update Hooks. You can't create, or load, or update, or delete any entity. Whether it's Content Entity or Config Entity, for Config Entity, you have to use Config Factory methods. But for Content, if you have to make the changes, directly make do that table. But if you still have to use Entity API, then use PostUpdateHook. And we'll discuss that in later slides. And Update Hooks, our update system is still using the routing system. So you cannot rebuild the routes as well during Update Hooks. So you have to rebuild those. The mark for the rebuild, there's a flag in the routing system. You can make that true, and they can be rebuilt afterwards. Let's discuss the new system, the PostUpdateHook, and why did we need that. So PostUpdateHook underscore name is the convention here. We remove the N and replace it with the name, because N doesn't hold any significance in PostUpdateHooks. N can be anything. It can be any machine name. Maybe a description of the function what you are doing will be a better name for the PostUpdateHook. Then in the execution order, we execute Update Hooks first, and then we execute PostUpdateHooks. And the main focus of PostUpdateHook is that we are allowed to use any APIs. We are allowed to use any entity APIs, config APIs, or any other APIs available from core. So that's why we wanted to have a different set of update hooks for this process only. And to distinguish between a HookUpdateN and PostUpdateHooks, we store them in a separate file just to keep them separately from the code base. And then, nevertheless, it's also loaded on demand as install file is loaded on demand. And as you know, UpdateHooks are executed in batch and can process batch. And similarly, PostUpdateHook can do the same thing. And as I described earlier, HookUpdateN executed in sorted order. But these are executed in top-down order. So Hook appears in the file, will be executed first, and then the later one, and then after that. But as we know that HookUpdateN are only executed once in their lifetime, and then once the schema is changed, we cannot use that UpdateHook. Similarly, is the case with PostUpdateHook. And if you make a change, so this question comes to me all the time. Like, what if I make a change in PostUpdateHook and paste my new PostUpdateHook above a previous hook? That still will be executed, because the UpdateHook system has no record of that PostUpdateHook before this execution. So even if it is on top of a previous hook, it will still be executed. But they will still be executed in top-down order. So if I'm creating nodes and editing nodes, and I'm changing the node URLs in this order, there are three UpdateHooks. Then you have to make sure that they will, so the first will be the created hook, and the second will be the added content, and third will be the node URL. So here is the basis. Let's discuss some basic differentiation between UpdateHooks. So this is an UpdateHook from core. This is actually in block.install file. In this hook, there's some code hidden in this example as well. As you can see, we are changing some block visibilities, and then we are saving the configuration. You can do that in UpdateHooks, because we are directly operating on the config, and we are changing the config values. So it is recommended to directly read from the factory and make those changes. Similarly, if you are updating the schema of the table, in this case, we are changing the column type in a database table from int to tiny int. So you can do that in UpdateHook, and it's a node UpdateHook. So now what is the use of post UpdateHook? As you can see, in this particular example, we are using factory storage, and we are loading a view from factory, and we are saving it to the config. So the idea here is that you can create an entity, and similarly, you can create content and move it to active storage of the website and from the file storage of the website. Similarly, you can update content as well. This is a contrib example. There is a file browser module, and in that, we import some config during installation, and add some images as well. But there is no UUID for the image, so in this case, in specific scenario, we are loading the file from the file URI and updating the field UUID in the config. Another example here is that of post UpdateHook, where we are changing the configuration, but we are using the configuration API for that, which is, in this specific case, we are loading all the field storage configuration, and we are relying on entity API to save and make the appropriate changes and remove all the redundant keys there may be or their values. And this is a strength of post UpdateHook that you don't have to make any other change and just re-save all the values, and the entity API will take care of that. If you are doing any communication between two UpdateHooks, you leave a message. If you are core developer and you are writing a core UpdateHook and you want to leave a message that I have changed such and such blocks, and if Contrib want to act on those, they can do that by reading the specific key you updated in your UpdateHook. In this case, we are using the Drupal State Key Value factory to store some values that we have executed this hook and you can now execute your stuff and make changes or whatever changes you want to make right now. This is a key value pair store. So most probably you will never be touching it or core will never be touching it again. So it is safe to store strings there. It's safe to retrieve data from there. Even UpdateSystem heavily rely on state key value pair to store information there. If you are making any entity-related changes, if you are updating their definitions, if you are updating, maybe you are adding a new base field or you are making changes to a node title and making the title label different. So these are the base field changes you can do and you can always rely on entity UpdateManager, a definition UpdateManager, which is built for that specific purpose only. Core heavily relies on that. There is proper testing around that so that each and every case is properly tested and it will fulfill all the requirements for developers so that they can make changes easily without any problem. Another thing which is very important is that always test your upgrade path. In core, we have so many upgrade path tests and we recently converted them to functional test base. And this is a really simple example in core and I think all the upgrade path tests look the same, like this example. As you can see, we are loading a file from core from the name suggested, like it's a bare standard installation of Drupal. There are a couple of other files as well with content, with configurations, so you can load this file and then all you have to do is, in your test method, use the test run update method and you can run your update hook through the UI with all the steps you follow from update.php and after running those, if they pass, all the steps are clear, there is no execution error, there is no runtime error, there is no schema problem, then you can check and verify the things you have changed in the update hooks are still there. So this particular example is for post update hook. This test is actually testing the post update hook execution, but we can also test update hooks as well in the same testing system. So this is the actual test in which we are making the changes and we are testing there. As you can see, that we are loading all the views and we are changing the display cacheability settings and we are unsetting the cacheability method data and making sure that after saving every value, using entity API will be changed the way we want it to. And if you look at this, we have assert faults where we are making sure that cacheable keys are not there anymore in the display cacheability method data and there are new context and max age keys are available for you. We have several bugs around update system and we need a lot of help. If you want to learn about update hooks and update system, you want to improve your knowledge base, go jump in the queue and help out. You can also go to the sprints and ask for help. You can jump in IRC. So please feel free and if you have any question, please go ahead. Any questions? Thank you.