在开发Drupal9核心代码的过程中,我们如何和为什么要弃用一些API

本文介绍Drupal9开发过程中,官方弃用的哪些API、函数、方法等,以及为什么弃用,我们也想了解Drupal9与Drupal8的关系,以便我们在开发Drupal8的过程中,更好考虑将来将Drupal8网站或者系统升级到Drupal9。

我们从一开始就没有在自己的git分支中使用Drupal9,而是在Drupal 8中构建了大部分drupal9。这有各种好处:
1、在Drupal9发布之前,所有新的(Drupal9就绪的)代码都部署在Drupal8站点上。
2、我们可以在Drupal 8的新代码中解决问题。
3、反馈是基于这个新代码提供的,因此可以在Drupal8中进行改进。
4、这使得我们不像以前的Drupal版本那样进行重构,因此我们不会最终得到一个完全重新设计的API。
5、用户最大的好处是Drupal 8到9的路径不是一个突然的跳跃。相反,这是几个更容易采取的小步骤。

在drupal9中,我们为什么弃用(一些API)?

在Drupal中总是有一些需要改进的地方。以Drupal8中的file.inc函数为例。这些功能已经存在很长时间了,但并不适合Drupal 8。大多数在Drupal8.7.0中被弃用,它们将在Drupal9中被删除。这是前/后一对寻找其中一个的方法:

// Before 8.7.0 only this was possible.
file_unmanaged_copy($source, $destination);

// After 8.7.0 this is the new way. The prior code still works but is deprecated.
\Drupal::service('file_system')->copy($source, $destination);

由于各种原因,新的解决方案更好,包括:

文件系统服务继承了FileSystemInterface,因此很容易找到所有相关的方法,无需按照命名约定在全局函数名中搜索。

这个service可以被换成其他的不同的文件系统,例如记录文件操作。

该服务可以在测试中模拟,从而在测试逻辑的同时避免文件系统操作。

代码与Drupal 8其他地方的代码风格相匹配。

代码不需要一直加载,需要时可以自动加载。

旧的解决方案仍然保留在Drupal 8中,以实现向后兼容。这意味着,即使已经有替换解决方案可用,使用file_unmanaged_copy()函数的模块、站点和自定义代码仍将继续工作。旧的解决方案被标记为已弃用,这意味着它最终将完全从Drupal中删除。

在drupal9中,我们怎么弃用呢?

以上面的例子为例,我们在函数实现上使用@deprecated注释。当我们弃用该函数时,当它将被删除时,以及使用什么来代替它时,这些文档将被记录下来。我们还添加了一个@see注释,解释在何处阅读更多内容。在函数的实现中,会添加一个trigger_error()调用,以触发查找弃用错误的失败测试。然后,添加了旧解决方案的向后兼容实现,该实现基于新的API。这就是向后兼容的函数实现的外观:

 

/**
 * Copies a file to a new location without database changes or hook invocation.
 *
 * [...]
 *
 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
 *   Use \Drupal\Core\File\FileSystemInterface::copy().
 *
 * @see file_copy()
 * @see https://www.drupal.org/node/3006851
 */
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
  @trigger_error('file_unmanaged_copy() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \\Drupal\\Core\\File\\FileSystemInterface::copy(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);

  // ... backwards compatible implementation ...
}

最后,虽然在这个代码示例中不明显,但是应该添加一个测试来确认该弃用是否正常工作。

虽然大多数的弃用都很简单,但有些情况并不那么简单。有些将无法trigger_error() (例如 global  或类常量),有些将无法拥有@deprecated注释(例如条件中的else{}子句)。还有一些在采用当前弃用策略之前实现的弃用,并且可能缺少@deprecated annotation或trigger_error()。

重要的一点是,我们有一种方法来识别“未来的变化”,同时维护向后兼容的实现。这意味着Drupal8模块、自定义代码等将在更新版本中继续工作,但很明显,为了使用Drupal9,需要更改什么。

可以在Drupal核心弃用策略中找到更详细的解释。
https://www.drupal.org/core/deprecation

Drupal9中,哪些不推荐使用的api将被删除?

我们的目标是删除所有在Drupal9.0.0发布之前标记为要删除的不推荐使用的API。查看api.drupal.org上所有标记为不推荐的内容的列表,包括依赖项(如Twig和Symfony)中的不推荐内容。虽然此列表无法具体筛选要在9.0.0中删除的项,但到目前为止,所有内容都是针对该版本的。

 

什么时候才能知道Drupal9的全部废弃内容?

完整的弃用列表在Drupal 8.8.0中最终确定,该版本于2019年12月4日发布,尽管在绝对必要的情况下可能会有很少的例外。