Series Overview & ToC | Previous Article | Next Article

In the previous article, we talked about avoiding entity ID conflicts which is one of the primary known issues when migrating to Drupal 10. In this section, we will discuss other issues that might arise and some limitations of the API. As time passes, issues are fixed and new ones might get discovered. While we strive to keep this series up to date, refer to the official documentation for the latest community aggregated resources.

Contact us to learn how we can help you with your migration.

Migrating Views

The migration of views is not supported by the core Migrate API. Among other reasons, changes to the site architecture and views plugins not being available in Drupal 10 are some of the reasons behind this decision. Outside of what is provided by Drupal core, multiple contributed modules were created to attempt an automated upgrade path. As of this writing, the only supported one is the Views Migration module. It takes a best-effort approach to performing an automated migration.

A few things to consider:

  • There are many modules that integrate with Views to provide additional functionality. Those modules need to be enabled on Drupal 7 and Drupal 10 before attempting the automated upgrade. Otherwise, you will get broken or missing plugin handlers.
  • If a Views plugin used in Drupal 7 is not found in Drupal 10, the automated migration will still attempt to create the view as complete as possible. In this case, when editing the view in Drupal 10 look for broken and missing plugin handlers and manually fix the issue.
  • In some cases, it will not be possible to create the view at all. When this happens, check the migration messages to get a list of views that failed to migrate. A command similar to drush migrate:messages d7_views_migration would show the relevant information.
  • The module only works with Views_ whose configuration is stored in the database_. In Drupal 7, the Features module was a very popular approach to deploying configuration changes. When adding a view to a feature, its configuration is stored in code, not in the database. Such views would not be picked up by the automated upgrade path. To work around this, overwrite the view’s configuration in Drupal 7. Making any change, like adding a space character to the description, will overwrite the view and store its new configuration in the database.

In my experience, the module does a good job. Simple views usually work out of the box in Drupal 10 and complex ones need a bit of tweaking to fix them. In all cases, I review each view and view display to make sure everything is working as expected.

Something to remember: you might not need all of your current views in the new Drupal 10 site. Always evaluate which views need to be replicated and which can be dropped. The site audit template contains a tab to keep track of views migrations.

PHP module

In Drupal 7, the PHP module was part of Drupal core. Many sites used it to embed PHP code to render dynamic content in rich text fields, control block visibility, and implement views plugins like contextual filters and argument validators. The module would store PHP code in the database and execute it on demand.

While a Drupal 10 version of the module is available, there are many reasons not to use it. The primary concerns are introducing security and performance issues and producing fatal errors and broken pages due to malformed code. It is strongly advised not to use the PHP module in Drupal 10.

Replacing the PHP module will depend on how it was used in Drupal 7. Custom tokens could be used to inject dynamic content in rich text fields. Custom condition plugins could replace block visibility rules. Custom views plugins could replace contextual filters and arguments validators. Note that you might not need to create custom code in all cases. Sometimes, the functionality provided by Drupal core or contributed modules suffices to replace instances of PHP module usage.

One aspect of the upgrade process that is not straightforward is finding all places in Drupal 7 where PHP code was used. I have seen code embedded in rich text fields attached nodes, block descriptions, views text area plugins, and more. Unfortunately, there is no single API call or query against the database that would retrieve places where code is embedded.

Consider the following to help determine where PHP is present in the database:

  • Review text formats that have the PHP filter enabled. From there, review which roles have access to those text formats and what content they have permission to author. At the database level, the text format is a separate column in a table which can be used for filtering based on the identified text formats.
  • Create a database dump and search for PHP opening tags in the result file. A tool commonly used for this is grep.
  • Use an IDE capable of connecting to a database and perform a full-text search for PHP opening tags.
  • Talk to the content editors. They are likely to know key pages or sections of the site that rely on PHP code.

Unsupported filter formats

Filters are used as part of input format configuration to clean up and enhance content entered by end-users in rich text fields. For example, you can configure one to restrict which HTML tags are allowed and another one to replace a token for a dynamic value. When migrating input formats Drupal will attempt to migrate all filters attached to them. If an equivalent Drupal 10 filter format is not found, it will be migrated as filter_null. This filter replaces all content for an empty string.

This can cause confusion because any input format using an unsupported filter will return an empty string. This effectively hides the content of any rich text fields that were saved with that input format even though it exists in the database. It is common to bump into this issue when using the PHP filter, but any unsupported filter format will produce the same result.

To work around this issue, you can:

  • Check if a Drupal 10 module provides the missing filter format. If available, enable the module and run the migration for filter formats again.
  • Edit and re-save the affected input formats to remove the references to filter_null. While this will make content appear, any functionality provided by the unsupported Drupal 7 filter will be lost. This could lead to unreplaced tokens and even security issues due to unfiltered markup.
  • Edit the content where the unsupported filter is used and save it again using an input format. This case is similar to the previous one in the sense that we are bypassing the changes that the unsupported filter would produce.
  • Implement the missing filter yourself and consider contributing it back.

Other issues

There are other known issues, but the ones above are the ones that I encounter more frequently. Other issues that you might encounter during your migration include:

  • Conflicting text processing settings in text fields.
  • Duplicate comment fields in content types.
  • Inability to migrate files stored in a non-standard location.
  • Field types, widgets, or formatters that have no Drupal 10 equivalent. The Migrate Skip Fields module will be covered in a future article to help with this issue.

Refer to the official documentation on known issues for more details on the above issues and other ones not listed in this article. Note that some issues are dependent on the version of Drupal you are migrating from. That is, some issues are only relevant when migrating from Drupal 6 while others manifest when the source site is Drupal 7.

Migrating from Drupal 7 to Drupal 10 presents several challenges, particularly with Views, the PHP module, and unsupported filters. To ensure a successful migration, leverage the migration modules available, replace PHP code with safer alternatives, address filter format issues, and consult official documentation for the latest updates. In our next part, we will provide an overview of Drupal entities.

Image by Songchai Premprasopchok from Pixabay