Updating to Drupal 10
Begin by upgrading Drupal 9 to the latest version. Currently that is 9.5.10
Review existing modules and themes
Using the Upgrade Status (https://www.drupal.org/project/upgrade_status) module, review the state of existing installed and uninstalled modules and themes. This includes removing deprecated modules in Drupal 10 such as Color, HAL, RDF and themes Bartik and Stable. Note, for Drupal 10, the theme Stable is now Stable9.
Note - while these deprecated modules are no longer part of Drupal core.... access to some of them are available
Module | Version | URL | Drupal version |
---|---|---|---|
Color | 1.0.3 | https://www.drupal.org/project/color | ^9.4 |
HAL | 2.0 | https://www.drupal.org/project/hal | ^10 |
RDF | ^2.1 | https://www.drupal.org/project/rdf | ^9.4 || ^10.0 |
Obviously, as you work through the upgrade process, and your current Drupal version is 9.5, upgrading a module with a Drupal base version of ^10 cannot be installed until the upgrade process has been completed.
Upgrade steps
Preparation to upgrade
Now that you have prepared your site, your first step in the upgrade process is to temporarily add write access to protected files and directories:
chmod -R 777 {path}/web/sites/default
chmod 666 {path}/web/sites/default/*settings.php
chmod 666 {path}/web/sites/default/*services.yml
Prepare core-recommend and dev-dependencies changed in the composer.json file. The file will be updated similar to
"require": {
/.../
"drupal/core-composer-scaffold": "^9.5",
"drupal/core-project-message": "^9.5",
"drupal/core-recommended": "^9.5",
Run the following
composer require 'drupal/core-recommended:^10' 'drupal/core-composer-scaffold:^10' 'drupal/core-project-message:^10' --update-with-dependencies --no-update
Change
"require": {
/.../
"drupal/core-composer-scaffold": "^10",
"drupal/core-project-message": "^10",
"drupal/core-recommended": "^10",
Also updating
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1",
"drupal/core-dev": "^9.5",
/.../
Check if you have Core dev script? If so, then run
composer require 'drupal/core-dev:^10' --dev --update-with-dependencies --no-update
Response
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1",
"drupal/core-dev": "^10",
/.../
Drush version
Check the current version of Drush being used, as Drupal 10 is best to run off Drush 12
drush --version
Response
Drush Commandline Tool 11.6.0
Prepare the update to version by
composer require 'drush/drush:^12' --no-update
Time to perform the update
With the preparation completed, let's run the update
composer update
Update the database
Perform this action by running
drush updatedb
Permissions
If completed, then change the permissions that were altered at the start
chmod -R 755 {path}/web/sites/default
chmod 644 {path}/web/sites/default/*settings.php
chmod 644 {path}/web/sites/default/*services.yml
Review the Status Report
If you have any issues, read through the Errors / issues below. You might be experiencing similar issues to us.
Otherwise, if all going well, then let's cross check status report (Admin > Reports > Status Report).
Status Report - Errors
The first batch of errors:
Area | Notes or details |
---|---|
Search API | The following search servers are not available: General, Related |
Solr Server General | Solr not reachable Solr server General is not reachable. |
Solr Server Related | Solr not reachable Solr server Related is not reachable. |
The Solr errors I'll leave as there related to the server.
Status Report - warnings
Area | Notes or details | Solution |
---|---|---|
Color Field library: jQuery Simple Color |
Missing If you want to use the Simple Color widget, you must download the jQuery Simple Color library and copy it to /app/web/libraries/jquery-simple-color/ |
Download library from https://github.com/recurser/jquery-simple-color |
Color Field library: Spectrum |
Missing If you want to use the Spectrum widget, you must download the Spectrum Library and copy it to /app/web/libraries/spectrum/ |
Download the library from https://github.com/bgrins/spectrum |
Configuration files |
Protection disabled
|
The permissions noted above are correct. If you see this error, then check if hardening has been activated. If so, you'll need to add to your settings.php file the following line
|
Deprecated modules enabled | Deprecated modules found: Activity Tracker. | Uninstall listed modules |
Media | It is potentially insecure to display oEmbed content in a frame that is served from the same domain as your main Drupal site, as this may allow execution of third-party code. You can specify a different domain for serving oEmbed content here. | |
SameSite cookie attribute |
Not set This attribute should be explicitly set to Lax, Strict or None. If set to None then the request must be made via HTTPS. See PHP documentation |
|
Transaction isolation level |
REPEATABLE-READ The recommended level for Drupal is "READ COMMITTED". See the setting MySQL transaction isolation level page for more information. |
Errors / issues
Theme issue
When working on updating a custom theme from Drupal 9 to Drupal 10, the theme used Stable as a base theme. However, this needs to be changed to Stable9 to work in Drupal 10. However, I came across a curious issue I had the following error.
Drupal\Core\Theme\MissingThemeDependencyException: Base theme stable9 has not been installed. in Drupal\Core\Theme\ThemeInitialization->getActiveThemeByName() (line 122 of core/lib/Drupal/Core/Theme/ThemeInitialization.php)
To resolve this error, I manually installed Stable9 using Drush
drush theme:enable stable9
Response
[success] Successfully installed theme: stable9
Attempting to run drush updb again.
I had the following warning:
[warning] (Currently using Protected forms Total of 0 submissions containing spam patterns [1] have been rejected.
[1] http://default/admin/config/content/protected_forms
)
[error] (Currently using Removed core theme You must add the following contributed theme and reload this page.
* Stable [1]
This theme is installed on your site but is no longer provided by Core.
For more information read the documentation on deprecated themes. [2]
[1] https://www.drupal.org/project/stable
[2] https://www.drupal.org/node/3223395#s-recommendations-for-deprecated-themes
)
Requirements check reports errors. Do you wish to continue? (yes/no) [yes]:
Given I was confident with my preparation, I responded yes so the database would be updated.
Requirements check reports errors. Do you wish to continue? (yes/no) [yes]:
>
------------------ ----------- --------------- --------------------------------
Module Update ID Type Description
------------------ ----------- --------------- --------------------------------
system 10100 hook_update_n 10100 - Remove the year 2038
date limitation.
block_content 10100 hook_update_n 10100 - Update entity
definition to handle revision
routes.
block_content 10200 hook_update_n 10200 - Remove the unique
values constraint from block
content info fields.
comment 10100 hook_update_n 10100 - Remove the year 2038
date limitation.
dblog 10100 hook_update_n 10100 - Remove the year 2038
date limitation.
dblog 10101 hook_update_n 10101 - Converts the 'wid' of
the 'watchdog' table to a big
integer.
history 10100 hook_update_n 10100 - Remove the year 2038
date limitation.
openai 10001 hook_update_n 10001 - Disable the openai_api
module.
statistics 10100 hook_update_n 10100 - Remove the year 2038
date limitation.
tracker 10100 hook_update_n 10100 - Remove the year 2038
date limitation.
user 10000 hook_update_n 10000 - Remove non-existent
permissions created by
migrations.
block_content block_li post-update Update block_content 'block
brary_vi library' view permission.
ew_permi
ssion
block_content move_cus post-update Moves the custom block library
tom_bloc to Content.
k_librar
y
block_content sort_per post-update Update permissions for users
missions with "administer blocks"
permission.
ckeditor5 code_blo post-update Updates Text Editors using
ck CKEditor 5 Code Block.
ckeditor5 plugins_ post-update Updates Text Editors using
settings CKEditor 5 to sort plugin
_export_ settings by plugin key.
order
editor image_la post-update Enable filter_image_lazy_load
zy_load if editor_file_reference is
enabled.
file add_perm post-update Grant all non-anonymous roles
issions_ the 'delete own files'
to_roles permission.
media oembed_l post-update Add the oEmbed loading
oading_a attribute setting to field
ttribute formatter instances.
metatag v2_01_ch post-update Convert all fields to use JSON
ange_fie storage.
lds_to_j
son
metatag v2_02_re post-update Remove meta tags entity values
move_ent that were removed in v2.
ity_valu
es
metatag v2_03_re post-update Remove meta tags from default
move_con configurations that were
fig_valu removed in v2.
es
metatag v2_04_un post-update Uninstall submodule(s)
install_ deprecated in v2: GooglePlus.
modules
metatag v2_05_tw post-update Replace deprecatedremoved
itter_ty Twitter Card "type" values.
pe_chang
es
responsive_image image_lo post-update Add the image loading settings
ading_at to responsive image field
tribute formatter instances.
responsive_image order_mu post-update Re-order mappings by
ltiplier breakpoint ID and descending
_numeric numeric multiplier order.
ally
system enable_p post-update Enable the password
assword_ compatibility module.
compatib
ility
system linkset_ post-update Add new menu linkset endpoint
settings setting.
system timestam post-update Update timestamp formatter
p_format settings for entity view
ter displays.
text allowed_ post-update Add allowed_formats setting to
formats existing text fields.
views boolean_ post-update Update Views config schema to
custom_t make boolean custom titles
itles translatable.
views fix_revi post-update Fix '-revision_id' replacement
sion_id_ token syntax.
part
views oembed_e post-update Add eager load option to all
ager_loa oembed type field
d configurations.
views responsi post-update Add lazy load options to all
ve_image responsive image type field
_lazy_lo configurations.
ad
views timestam post-update Update timestamp formatter
p_format settings for views.
ter
webform ckeditor post-update Move from custom CKEditor to
hidden 'webform_default' text
format.
webform ckeditor post-update Issue #3351348:
01 '#multiple__no_items_message'
added to every field.
webform confirma post-update #3335924: Allow the
tion_pag confirmation page to include
e_noinde robots noindex meta tag.
x
webform deprecat post-update #3254570: Move jQuery UI
e_jquery datepicker support into
_ui_date dedicated deprecated module.
picker
webform deprecat post-update Issue #3247475: Location field
e_locati Algolia Places sunsetting May
on_place 31, 2022.
s
webform multiple post-update Issue #3339769: Improve
_categor Webform categorization to
ies support assigning multiple
categories and default
categories.
------------------ ----------- --------------- --------------------------------
Do you wish to run the specified pending updates? (yes/no) [yes]:
>
> [notice] Update started: block_content_update_10100
> [notice] Added revision routes to Content block entity type.
> [notice] Update completed: block_content_update_10100
> [notice] Update started: dblog_update_10100
> [notice] Update completed: dblog_update_10100
> [notice] Update started: system_update_10100
> [notice] Update completed: system_update_10100
> [notice] Update started: block_content_update_10200
> [notice] Update completed: block_content_update_10200
> [notice] Update started: comment_update_10100
> [notice] Update completed: comment_update_10100
> [notice] Update started: dblog_update_10101
> [notice] Update completed: dblog_update_10101
> [notice] Update started: history_update_10100
> [notice] Update completed: history_update_10100
> [notice] Update started: openai_update_10001
> [notice] Update completed: openai_update_10001
> [notice] Batch process has consumed in excess of 60% of available memory. Starting new thread
> [notice] Update started: statistics_update_10100
> [notice] Update completed: statistics_update_10100
> [notice] Update started: tracker_update_10100
> [notice] Update completed: tracker_update_10100
> [notice] Update started: user_update_10000
> [notice] Update completed: user_update_10000
> [notice] The file assets://css was not deleted because it does not exist.
> [notice] Batch process has consumed in excess of 60% of available memory. Starting new thread
> [notice] Update started: block_content_post_update_block_library_view_permission
> [notice] Update completed: block_content_post_update_block_library_view_permission
> [notice] Update started: block_content_post_update_move_custom_block_library
> [notice] Update completed: block_content_post_update_move_custom_block_library
> [notice] Update started: block_content_post_update_sort_permissions
> [notice] Update completed: block_content_post_update_sort_permissions
> [notice] Update started: ckeditor5_post_update_code_block
> [notice] Update completed: ckeditor5_post_update_code_block
> [notice] Update started: ckeditor5_post_update_plugins_settings_export_order
> [notice] Update completed: ckeditor5_post_update_plugins_settings_export_order
> [notice] Update started: editor_post_update_image_lazy_load
> [notice] Update completed: editor_post_update_image_lazy_load
> [notice] Update started: file_post_update_add_permissions_to_roles
> [notice] Update completed: file_post_update_add_permissions_to_roles
> [notice] Update started: media_post_update_oembed_loading_attribute
> [notice] Update completed: media_post_update_oembed_loading_attribute
> [notice] Update started: metatag_post_update_v2_01_change_fields_to_json
> [notice] There were no overridden Metatag records that needed to be updated to store the data using JSON.
> [notice] Update completed: metatag_post_update_v2_01_change_fields_to_json
> [notice] Update started: metatag_post_update_v2_02_remove_entity_values
> [notice] There were no Metatag records to update.
> [notice] Update completed: metatag_post_update_v2_02_remove_entity_values
> [notice] Update started: metatag_post_update_v2_03_remove_config_values
> [notice] Removed meta tags from the node Metatag configuration.
> [notice] Update completed: metatag_post_update_v2_03_remove_config_values
> [notice] Update started: metatag_post_update_v2_04_uninstall_modules
> [notice] Metatag: Google Plus has been uninstalled.
> [notice] Update completed: metatag_post_update_v2_04_uninstall_modules
> [notice] Batch process has consumed in excess of 60% of available memory. Starting new thread
> [notice] Update started: metatag_post_update_v2_05_twitter_type_changes
> [notice] Update completed: metatag_post_update_v2_05_twitter_type_changes
> [notice] Update started: responsive_image_post_update_image_loading_attribute
> [notice] Update completed: responsive_image_post_update_image_loading_attribute
> [notice] Update started: responsive_image_post_update_order_multiplier_numerically
> [notice] Update completed: responsive_image_post_update_order_multiplier_numerically
> [notice] Update started: system_post_update_enable_password_compatibility
> [notice] Update completed: system_post_update_enable_password_compatibility
> [notice] Batch process has consumed in excess of 60% of available memory. Starting new thread
> [notice] Update started: system_post_update_linkset_settings
> [notice] Update completed: system_post_update_linkset_settings
> [notice] Update started: system_post_update_timestamp_formatter
> [notice] Update completed: system_post_update_timestamp_formatter
> [notice] Update started: text_post_update_allowed_formats
> [notice] Update completed: text_post_update_allowed_formats
> [notice] Update started: views_post_update_boolean_custom_titles
> [notice] Update completed: views_post_update_boolean_custom_titles
> [notice] Update started: views_post_update_fix_revision_id_part
> [notice] Update completed: views_post_update_fix_revision_id_part
> [notice] Update started: views_post_update_oembed_eager_load
> [notice] Update completed: views_post_update_oembed_eager_load
> [notice] Update started: views_post_update_responsive_image_lazy_load
> [notice] Update completed: views_post_update_responsive_image_lazy_load
> [notice] Update started: views_post_update_timestamp_formatter
> [notice] Update completed: views_post_update_timestamp_formatter
> [notice] Update started: webform_post_update_ckeditor
> [notice] Update completed: webform_post_update_ckeditor
> [notice] Update started: webform_post_update_ckeditor01
> [notice] Update completed: webform_post_update_ckeditor01
> [notice] Update started: webform_post_update_confirmation_page_noindex
> [notice] Update completed: webform_post_update_confirmation_page_noindex
> [notice] Update started: webform_post_update_deprecate_jquery_ui_datepicker
> [notice] Update completed: webform_post_update_deprecate_jquery_ui_datepicker
> [notice] Update started: webform_post_update_deprecate_location_places
> [notice] Update completed: webform_post_update_deprecate_location_places
> [notice] Update started: webform_post_update_multiple_categories
> [notice] Update completed: webform_post_update_multiple_categories
[success] Finished performing updates.
[notice] The file assets://css was not deleted because it does not exist.
[notice] The file assets://js was not deleted because it does not exist.
Time to clear the database cache.
drush cr
Response
[notice] The file assets://css was not deleted because it does not exist.
[notice] The file assets://js was not deleted because it does not exist.
[success] Cache rebuild complete.
Looking ok. However, I need to investigate the file assets notice.
Working through errors
Using Drush, you can query the error log with watchdog
-------- -------------- ------ ---------- ----------------------------------------------------------------
ID Date Type Severity Message
-------- -------------- ------ ---------- ----------------------------------------------------------------
302761 18/Jul 23:20 php Error Error: Call to undefined function render() in
bales_preprocess_page() (line 207 of
/var/www/vhosts/{domain}/themes/custom/{theme}/{theme}.th
eme).
Render() issue
Error: Call to undefined function render() in hook_preprocess_page() (line 193 of themes/custom/{theme}/{theme}.theme).
Existing code
$variables['menu_global_navigation'] = render($render_header);
or
$variables['menu_global_navigation'] = drupal_render($render_header);
Change to
$variables['menu_global_navigation'] = \Drupal::service('renderer')->render($render_header);
Entity query
Drupal\Core\Entity\Query\QueryException: Entity queries must explicitly set whether the query should be access checked or not. See Drupal\Core\Entity\Query\QueryInterface::accessCheck(). in Drupal\Core\Entity\Query\Sql\Query->prepare() (line 141 of core/lib/Drupal/Core/Entity/Query/Sql/Query.php).
Not a fan of this error response. Letting the developer very little detail of where the error has occurred.
How to resolve, check where you have added queries and adding ->accessCheck(FALSE) to your queries, so the warnings no longer appear.
Therefore, the ugliness of adding accessCheck(FALSE) to most of the entity queries and making developers spend time adding it to existing code. As noted, not a fan having where developers are wasting hours of time chasing non-informative bugs because they forgot that queries were assuming accessCheck(TRUE) by default.
Example in my code
$bids = \Drupal::entityTypeManager()
->getStorage('block_content')
->getQuery()
->condition('type', $type)
->execute();
Change to
$bids = \Drupal::entityTypeManager()
->getStorage('block_content')
->getQuery()
->accessCheck(FALSE)
->condition('type', $type)
->execute();
file_create_url()
Error: Call to undefined function file_create_url()
To solve this Drupal 10 error change the following, from
$image_path = file_create_url($uri);
Change to
$image_path = \Drupal::service('file_url_generator')->generateAbsoluteString($uri);