Дата релиза: 15 июня 2022
Активная поддержка до: не позднее декабря 2022
Поддержка безопасности до: не позднее июня 2023
¶Хук THEME_ENGINE_init() объявлен устаревшим
Хук THEME_ENGINE_init()
объявлен устаревшим и будет удалён в Drupal 10. Замена данному хуку не предоставляется.
¶Для сущностей с поддержкой ревизий, модуль Views теперь предоставляет связи между основной и ревизионной таблицами
Ранее, модуль Views не предоставлял для ревизионных сущностей связи между основной таблицой и таблицой ревизий. Для модулей block_content
и node
были «костыли» для решения данной проблемы, но остальным сущностям приходилось решать это вопрос самостоятельно.
Начиная с текущего релиза, Views предоставляет соответствующие связи между основной и ревизионной таблицами для всех типов сущностей что поддерживают ревизии.
¶В .htaccess файлы добавлена поддержка настроек PHP 8
В .htaccess
файлы добавлен новый раздел для настроек параметров PHP 8. Это изменение касается как основного файла .htaccess
, так и всех прочих что генерируются Drupal для различных ситуаций, например, для sites/default/files
.
В эти файлы добавлена настройка для PHP 8:
# Имеющийся раздел для PHP 7.
<IfModule mod_php7.c>
php_value assert.active 0
</IfModule>
# Новые настройки для PHP 8.
<IfModule mod_php.c>
php_value assert.active 0
</IfModule>
Если вы переопределяете данные файлы или изменяете параметры PHP, для PHP 8 вам необходимо скопировать данные настройки и поправить под себя. Если вы используете стандартные настройки, файлы обновятся автоматически.
¶Для оптимизации определения сериализаторов и нормализаторов, NormalizerBase теперь реализует CacheableSupportsMethodInterface
Drupal\serialization\Normalizer\NormalizerBase
теперь реализует CacheableSupportsMethodInterface
и возвращает FALSE
по умолчанию. Это означает, что классы, расширяющие абстрактные классы из ядра продолжат работать как и раньше. Все конкретные реализации теперь имеют метод ::hasCacheableSupportsMethod()
, который возвращает TRUE
.
Данный интерфейс был представлен в Symfony 4.1:
Приложения могут определять множество нормализаторов и денормализаторов, Symfony вызывает
::supportsNormalization()
для каждого из них, каждый раз производя нормализацию или денормализацию объекта. В теории, результат вызова::supportsNormalization()
зависит от моженства факторов. На практике большинство из них зависит лишь от типа и формата, а данная информация легко кешируется.
Утверждение выше также подходит и для Drupal. Мы можем кешировать результат основываясь на переданном типе и формате, что позволяет сократить количество вызовов. Подобное изменение позволяет добиться увеличения производительности от 5 до 60 процентов!
¶Драйвера баз данных, предоставляемые ядром Drupal, перенесены в соответствующие одноимённые модули
Ранее была добавлена поддержка драйверов баз данных, как в пространстве имён модуля, так и в «src» директории ядра. Теперь эта возможность задействована для переноса драйверов баз данных предоставляемых ядром в соответствующие модули. Для каждого драйвера базы данных добавлен новый одноимённый модуль: mysql
, pgsql
и sqlite
.
Для драйверов баз данных в пространстве имён модуля требуется добавлять query-параметр в URL-строку подключения. Например: pgsql://test_user:test_pass@test_host:5432/test_database?module=pgsql
. Если вы используете один из модулей ядра, добавлять данный query-параметр не обязательно, все ранее сформированные URL-адреса подключений продолжат работать.
Использование use
с пространством имён содержащим Drupal\Core\Database\Driver
объявлено устаревшим и будет удалено до релиза Drupal 11. Рекомендуется заменить их использование на новые пространства имён:
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Install\Tasks
→Drupal\Core\Database\Install\Tasks
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Connection
→Drupal\Core\Database\Connection
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Delete
→Drupal\Core\Database\Query\Delete
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\ExceptionHandler
→Drupal\Core\Database\ExceptionHandler
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Insert
→Drupal\Core\Database\Query\Insert
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Schema
→Drupal\Core\Database\Schema
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Select
→Drupal\Core\Database\Query\Select
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Truncate
→Drupal\Core\Database\Query\Truncate
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Update
→Drupal\Core\Database\Query\Update
-
use Drupal\Core\Database\Driver\{mysql|pgsql|sqlite}\Upsert
→Drupal\Core\Database\Query\Upsert
¶JSON:API теперь корректно обрабатывает запросы в режиме обслуживания
В JSON:API внесены множественные улучшения для корректной обработки и поведения запросов в режиме обслуживания.
¶JSON:API теперь отвечает с заголовком Retry-After в режиме обслуживания
Начиная с данного релиза, если сайт находится в режиме обслуживания, JSON:API будет отвечать с заголовком Retry-After
.
Пример ответа в режиме обслуживания:
{
"jsonapi":{
"version":"1.0",
"meta":{
"links":{
"self":{
"href":"http://jsonapi.org/format/1.0/"
}
}
}
},
"errors":[
{
"title":"Service Unavailable",
"status":"503",
"detail":"core workspace is currently under maintenance. We should be back shortly. Thank you for your patience.",
"links":{
"via":{
"href":"http://example.com/jsonapi/base_field_override/base_field_override"
},
"info":{
"href":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4"
}
}
}
]
}
Данный ответ также содержит заголовок Retry-After
с информацией о том, сколько следует подождать до следующей попытки. По умолчанию рекомендуется время от 5 до 10 секунд. Значение из данного диапазона выбирается случайным образом на каждый запрос для предотвращения эффекта громового стада.
В связи с данным изменением было добавлено две новые настройки:
-
jsonapi.settings.maintenance_header_retry_seconds.min
: Минимальное значение в секундах для заголовкаRetry-After
. -
jsonapi.settings.maintenance_header_retry_seconds.max
: Максимальное значение в секундах для ззаголовкаRetry-After
.
Это позволит владельцу приложения иметь контроль над тем, как долго клиенты должны ждать перед повторным обращением. Данные настройки рассчитаны на продвинутых пользователей, в связи с этим, они не доступны в административном интерфейсе.
¶Добавлено новое событие Drupal\Core\Site\MaintenanceModeEvents::MAINTENANCE_MODE_REQUEST
В ядро было добавлено новое событие Drupal\Core\Site\MaintenanceModeEvents::MAINTENANCE_MODE_REQUEST
которое позволяет изменить как запрос, так и ответ, который производится в режиме обслуживания.
¶Добавлен новый метод MaintenanceModeInterface::getSiteMaintenanceMessage()
В интерфейс MaintenanceModeInterface
добавлен новый метод ::getSiteMaintenanceMessage()
который позволяет получить сообщение, которое должно выводиться в режиме обслуживания сайта.
¶Функция drupal_js_defaults() объявлена устаревшей
В Drupal 7 был добавлен хук hook_js_alter()
, для того чтобы для него всегда были данные, была введена функция drupal_js_defaults()
. В Drupal 8 произошёл переход на систему библиотек, что сделало hook_js_alter()
очень специфичным хуком для исключительных ситуаций. В связи с этим, функция drupal_js_defaults()
стала бесполезной и объявлена устаревшей, будет удалена в Drupal 10 без предоставления замены.
¶Метод LanguageManagerInterface::getLanguageSwitchLinks() теперь возвращает объект или NULL
В предыдущих версиях Drupal, Drupal\Core\Language\LanguageManagerInterface::getLanguageSwitchLinks()
имел документацию, что он возвращает массив ссылок, но Drupal\language\ConfigurableLanguageManager::getLanguageSwitchLinks()
возвращал объект, содержащий массив ссылок, или же FALSE
, если ссылок нет.
Документация для Drupal\Core\Language\LanguageManagerInterface::getLanguageSwitchLinks()
была изменена на то, что метод теперь возвращает либо объект с массивом ссылок, либо NULL
, если ссылок нет.
Если вы используете или реализуете данный метод, вам необходимо обновить свой код.
¶На замену опции запроса return добавлен новый метод Connection::lastInsertId()
Опция запроса return
и константы Database::RETURN_*
объявлены устаревшими. В Drupal 11 они будут удалены и Connection::query()
будет всегда возвращать объект StatementInterface
.
Для манипуляций данными в БД (INSERT
, DELETE
, UPDATE
, UPSET
, MERGE
, TRUNCATE
) не принято использовать Connection::query()
, для этого Drupal предоставляет построители динамических запросов.
В исключительных ситуациях Connection::query()
использовался для операции вставки (INSERT
) с целью получения ID последнего добавленного значения в БД. Для подобных случаев, начиная с данной версии, добавлен новый метод Connection::lastInsertId()
, который возвращает ID последнего добавленного значения.
Для операций обновления и прочих, больше не рекомендуется использовать Database::RETURN_AFFECTED
, вместо этого рекомендуется включить подсчёт значений путём передачи соответствующего аргумента в конструктор.
Пример, как данное изменения повлияло на Connection::nextId()
для MySQL драйвера:
Было:
$new_id = $this->query('INSERT INTO {sequences} () VALUES ()', [], ['return' => Database::RETURN_INSERT_ID]);
Стало:
$this->query('INSERT INTO {sequences} () VALUES ()');
$new_id = $this->lastInsertId();
¶Метод \Drupal\Core\Validation\DrupalTranslator:transChoice() объявлен устаревшим
Symfony 4.2 объявил \Symfony\Component\Translation\TranslatorInterface::transChoice()
устаревшим методом. Drupal реализует данный интерфейс в \Drupal\Core\Validation\DrupalTranslator:transChoice()
. Таким образом \Drupal\Core\Validation\DrupalTranslator:transChoice()
также объявлен устаревшим.
¶Функция module_load_include() объявлена устаревшей
Функция module_load_include()
объявлена устаревшей, вместо неё используйте метод ::loadInclude()
сервиса module_handler
.
Ранее:
module_load_include($type, $module, $name = NULL);
Сейчас:
\Drupal::moduleHandler()->loadInclude($module, $type, $name = NULL);
¶Функция module_load_install() объявлена устаревшей
Функция module_load_install()
объявлена устаревшей, вместо неё используйте метод ::loadInclude()
сервиса module_handler
.
Ранее:
module_load_include($module);
Сейчас:
\Drupal::moduleHandler()->loadInclude($module, 'install');
¶Сервисы использующие Laminas\Feed объявлены устаревшими
Сервисы, использующие Laminas\Feed\Reader
(feed.reader.*
) и Laminas\Feed\Writer
(feed.writer.*
) расширения, объявлены устаревшими. Также объявлен устаревшим сервис feed.bridge.writer
, который ранее использовался как замена для сервисов feed.writer.*
.
Сервис feed.bridge.reader
объявлен устаревшим в core.services.yml
, но добавлена замена с одноимённым названием aggregator.servies.yml
. Таким образом, сервис feed.bridge.reader
теперь перенесён в модуль Aggregator.
Замены для Laminas\Feed\Reader
:
-
feed.reader.dublincoreentry
→\Drupal::service('feed.bridge.reader')->get('DublinCore\Entry')
-
feed.reader.dublincorefeed
→\Drupal::service('feed.bridge.reader')->get('DublinCore\Feed')
-
feed.reader.contententry
→\Drupal::service('feed.bridge.reader')->get('Content\Entry')
-
feed.reader.atomentry
→\Drupal::service('feed.bridge.reader')->get('Atom\Entry')
-
feed.reader.atomfeed
→\Drupal::service('feed.bridge.reader')->get('Atom\Feed')
-
feed.reader.slashentry
→\Drupal::service('feed.bridge.reader')->get('Slash\Entry')
-
feed.reader.wellformedwebentry
→\Drupal::service('feed.bridge.reader')->get('WellFormedWeb\Entry')
-
feed.reader.threadentry
→\Drupal::service('feed.bridge.reader')->get('Thread\Entry')
-
feed.reader.podcastentry
→\Drupal::service('feed.bridge.reader')->get('Podcast\Entry')
-
feed.reader.podcastfeed
→\Drupal::service('feed.bridge.reader')->get('Podcast\Feed')
Замены для Laminas\Feed\Writer
и feed.bridge.writer
:
Для замены вам потребуется объявить собственный сервис со следующим содержанием:
feed.bridge.writer:
class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer
calls:
- [setContainer, ['@service_container']]
- [setStandalone, ['\Laminas\Feed\Writer\StandaloneExtensionManager']]
arguments: ['feed.writer.']
Вы также можете использовать класс \Laminas\Feed\Writer\StandaloneExtensionManager
напрямую.
¶В листинге модулей добавлено визуальное обозначение для устаревших модулей, а попытка включения устаревших модулей или тем будет показывать предупреждение
Теперь, на странице со списком модулей, будет визуальная индикация для устаревших модулей. Это позволит предупреждать пользователей заранее, что включение модуля может иметь последствия.
Также, при попытке включения таких модулей и тем, будет показываться системное сообщение, предупреждающее о том, что модули или тема объявлены устаревшими и их использование на свой страх и риск.
¶Темы оформления теперь могут предоставлять starterkit варианты
Темы оформления теперь в *.info.yml
файле могут добавить новую опцию starterkit
. Если данная опция равна true
, то данная тема может быть использована как стартовая.
Темы оформления, для которых задана опция starterkit: true
могут быть взяты за основу при генерации новой темы.
Пример использования:
$ php core/scripts/drupal generate-theme --starterkit [starterkit_themename] [new_themename]
В результате выполнения, содержимое темы оформления [starterkit_themename]
будет скопировано в themes/[new_themename]
. Название файлов стартовой темы останутся неизменными.
¶Drupal теперь предупреждает об отсутствии поддержки JSON текущей базой данных
Drupal теперь выводит предупреждение, если база данных не имеет поддержки JSON.
Если у вас имеются свои драйвера баз данных, убедитесь что ::hasJson()
работает корректно с вашим типом БД, в случае необходимости, переопределите его.
¶Расширения для построения SELECT запросов теперь управляются при помощи переопределяемых сервисов
- #3217699 (отменено)
Расширения для построения SELECT запросов теперь управляются при помощи переопределяемых сервисов.
\Drupal\Core\Database\Query\Select
используется Database API для построения SELECT запросов к БД. Данный класс имеет поддержку расширений, которые должны наследоваться от Drupal\Core\Database\Query
. Эти расширения могут влиять на построение запроса, добавлять новые и редактировать уже имеющиеся условия.
Ранее, данные расширения подключались при помощи вызова Select::extend()
, где в качестве аргумента передавалось полное название класса с расширением, которое необходимо добавить к запросу.
Теперь метод ожидает ключ (название) расширения. По этому ключу должен должен существовать одноимённый переопределяемый сервис, который является фабрикой. Данная фабрика должна подготовить экземпляр расширения и вернуть его.
Давайте рассмотрим на примере, как поменялось подключение расширений предоставляемых ядром:
-
Connection->select('some_table')->extend(PagerSelectExtender::class)
теперьonnection->select('some_table')->extend('pager')
-
Connection->select('some_table')->extend(TableSortExtender::class)
теперьonnection->select('some_table')->extend('table_sort')
-
Connection->select('some_table')->extend(SearchQuery::class)
теперьonnection->select('some_table')->extend('search_query')
-
Connection->select('some_table')->extend(ViewsSearchQuery::class)
теперьonnection->select('some_table')->extend('views_search_query')
Для того чтобы создать фабрику для своего расширения ExampleExtender
, вам необходимо объявить сервис который удовлетворяет именованию select_exntender_factory.[extender_name]
и имеющий тег backend_overridable
.
Например, example.services.yml
:
select_extender_factory.example_extender:
# Название класса не имеет значения.
class: Drupal\example\ExampleExtenderFactory
tags:
- { name: backend_overridable }
<?php
namespace Drupal\example;
/**
* Select extender example factory.
*/
class ExampleExtenderFactory {
/**
* Returns a query extender for example.
*
* @param \Drupal\Core\Database\Query\SelectInterface $query
* Select query object.
* @param \Drupal\Core\Database\Connection $connection
* Database connection object.
*
* @return \Drupal\example\ExampleExtender
* A query extender example.
*/
public function get(SelectInterface $query, Connection $connection): ExampleExtender {
return new ExampleExtender($query, $connection);
}
}
После чего вы можете использовать объявленную фабрику как расширение: Connection->select('some_table')->extend('example_extender')
.
¶Плагин-обработчик для миграций SubProcess (sub_process) теперь может выбросить исключение MigrateException
Плагин SubProcess
требует чтобы входные данные были многоуровневым массивом (массив из массивов), где каждый вложенный массив — значение источника на обработку.
Если значение на входе не будет являться массивом, теперь выбрасывается исключение MigrateException
.
¶Рекомендуемая версия PHP увеличена до 8.1
Рекомендуемая версия PHP увеличена до 8.1. Минимальная версия по-прежнему остаётся PHP 7.3.0.
¶Функция drupal_required_modules() объявлена устаревшей
Функция drupal_required_modules()
объявлена устаревшей и будет удалена в Drupal 10. Явной замены не предоставляется.
Данная функция использовалась для получения массива с модулями, необходимыми для работы Drupal ядра (required: true
).
Если вам требуется аналогичный список, вы можете использовать ExtensionDiscovery
и сервис info_parser
.
$parser = \Drupal::service('info_parser');
$required = [];
$listing = new ExtensionDiscovery(\Drupal::root());
$files = $listing->scan('module');
foreach ($files as $name => $file) {
$parsed = $parser->parse($file->getPathname());
if (!empty($parsed) && !empty($parsed['required']) && $parsed['required']) {
$required[] = $name;
}
}
¶Добавлена новая константа Drupal\Core\Utility\Error::DEFAULT_ERROR_MESSAGE
В ядро была добавлена новая константа Drupal\Core\Utility\Error::DEFAULT_ERROR_MESSAGE
. Данная константа содержит сообщение по умолчанию, которое можно использовать для вывода сообщений об ошибках: %type: @message in %function (line %line of %file).
¶Добавлено новое свойство для сущностей — enable_page_title_template
Если у сущности с поддержкой полей есть поле с меткой, то Drupal не добавляет метку в процессе рендера самой сущности, а вместо этого использует данное значение для построения заголовка страницы (см. EntityViewController::buildTitle()
). Это позволяет предотвратить дубли заголовка и сохраняет всю дополнительную информацию, добавляемую сторонними модулями при помощи хуков.
К сожалению, недостатком данного подхода является то, что может получиться неверная разметка из-за того что используется форматирование поля.
В Drupal ядре данная проблема проявляется с сущностями Media. По умолчанию, сущность node
не подвержена данной ошибке, потому что там есть специфичное решение для этой проблемы, но проблема появляется сразу же, как только это поле становится настраиваемым.
Ранее:
- Заголовок страницы мог быть сформирован с использованием таких HTML-тегов как
<h2>
,<div>
внутри<h1>
. - Если заголовок страницы был отключен для настройки отображения, тогда терялись метаданные, добавляемые модулями через хуки.
Сейчас:
Разработчикам доступно новое свойство для типов сущностей — enable_page_title_template
, при помощи которого можно активировать использование нового шаблона entity-page-title.html.twig
для вывода заголовка страницы, который полностью независим от форматирования поля.
Например, чтобы включить поддержку данного шаблона для нод, необходимо сделать следующее:
function mymodule_entity_type_build(array &$entity_types) {
$entity_types['node']->set('enable_page_title_template', TRUE);
}
Если вы хотите добавить дополнительные аттрибуты или данные в этот шаблон, то необходимо использовать hook_preprocess_entity_page_title()
, например:
/**
* Implements hook_preprocess_entity_page_title().
*/
function quickedit_preprocess_entity_page_title(&$variables) {
$variables['#cache']['contexts'][] = 'user.permissions';
$entity = $variables['entity'];
if (!\Drupal::currentUser()->hasPermission('access in-place editing')) {
return;
}
if ($entity instanceof RevisionableInterface) && !$entity->isLatestRevision()) {
return;
}
$label_field = $entity->getEntityType()->getKey('label');
$variables['attributes']['data-quickedit-field-id'] = $entity->getEntityTypeId() . '/' . $entity->id() . '/' . $label_field . '/' . $entity->get('langcode')->value . '/' . $variables['view_mode'];
}
¶Устаревшие темы оформления больше не отображаются в списке тем оформлений
На странице управления темами оформления (/admin/appearance
) теперь не отображаются темы со свойством lifecycle: obsolete
.
¶Модуль HAL объявлен устаревшим
Модуль HAL, предоставляемый Drupal, объявлен устаревшим и будет удалён в Drupal 10. Проект был перенесён в сторонний проект Heypermedia Application Language (HAL).
Если ваш сайт использует данный модуль, вам необходимо добавить сторонний модуль как зависимость в проект:
$ composer require drupal/hal-hal
¶Попытка установки Drupal на не поддерживаемой версии PHP теперь показывает предупреждение вместо ошибки
Drupal имеет две константы для указания минимальной версии PHP:
-
\Drupal::MINIMUM_PHP
: На PHP менее данной версии Drupal не может быть запущен. -
\Drupal::MINIMUM_SUPPORTED_PHP
: На PHP менее данной версии Drupal может быть запущен и использовать, обновляться, но будет отображаться предупреждение о необходимости обновить PHP.
Подобное разделение позволяет сайтам продолжать работать, и получать обновления безопасности даже на версиях PHP которые больше не поддерживаются.
Ранее, версия PHP менее \Drupal::MINIMUM_SUPPORTED_PHP
вызывало ошибку установки, что не позволяло установить Drupal на старой версии PHP. Тем не менее распространены процессы деплоя, где сайт устанавливается из конфигураций (например для тестирования). Для того чтобы подобные процессы продолжали работать, Drupal теперь не будет блокировать установку, а лишь выводить предупреждение, если версия PHP находится в пределах \Drupal::MINIMUM_PHP
- \Drupal::MINIMUM_SUPPORTED_PHP
.
\Drupal::MINIMUM_PHP
и \Drupal::MINIMUM_SUPPORTED_PHP
имеют одинаковое значение 7.3.0 во всех версиях Drupal 9 до 9.4.0, что не скажется на ваших процессах.
¶Добавлена возможность использования PHP callable в качестве функций обратного вызова для препроцесса тем хуков
Функции обратного вызова в Drupal для препроцесса тем хуков обычно объявляются при помощи hook_preprocess_HOOK()
в модулях и темах. Данные функции хранятся в регистре тем и применяются на необходимые элементы в момент рендера.
Менеджер тем позволяет использовать только функции, тогда как прочий API Drupal, например Form API, позволяет использовать PHP callables в качестве функций обратного вызова. Это изменение делает возможным использование PHP callables в качестве препроцессоров для тем хуков.
Сторонние модули и темы, желающие использовать данную возможность, должны реализовать hook_theme_registry_alter()
и объявить необходимые PHP callables.
function mymodule_theme_registry_alter(&$theme_registry) {
if (!empty($theme_registry['node'])) {
// Объект реализующий магический метод __invoke().
$theme_registry['node']['preprocess functions'][] = new Invokable();
// Массив с экземпляром класса и его методом.
$preprocess = new ThemePreprocess();
$theme_registry['node']['preprocess functions'][] = [$preprocess, 'objectMethodName'];
}
}
¶Сервис module_handler теперь ответственен за вызов всех хуков
Сервис module_handler
теперь ответственен за вызов всех хуков. Разработчики модулей больше не должны собирать функции для хуков самостоятельно. Это позволит в дальнейшем улучшать систему хуков так как вся работа с ними будет централизована.
\Drupal\Core\Extension\ModuleHandlerInterface::getImplementations()
объявлен устаревшим. Если вам необходим его функционал, используйте новые методы Drupal\Core\Extension\ModuleHandlerInterface::invoke*With()
.
Интерфейс для сервиса module_handler
был изменён. Добавлено два новых метода:
-
public function invokeAllWith(string $hook, callable $callback): void
-
public function hasImplementations(string $hook, $modules = NULL): bool
Вызов хука больше не имеет информации о реализации хука, например, об имени функции, но по-прежнему знает название модуля в котором он объявлен. Таким образом, вызов хука не должен полагаться на то, что хотя бы имеется одна реализация хука.
Ответственность за итерацию по реализациям была перенесена в сервис module_handler
. Теперь каждый вызов хука может сопровождаться замыканием, которое будет вызываться на каждую реализацию хука. В каждое замыкание передаётся названием модуля, в котором реализован хук и функция обратного вызова текущей реализации. Если замыкание не вызовет функцию обратного вызова, реализация не будет обработана (вызвана).
Прежнее поведение можно повторить с использованием методов Drupal\Core\Extension\ModuleHandlerInterface::invoke*With()
с небольшими изменениями в логике.
Ранее:
$hook = 'myhook';
foreach ($this->moduleHandler->getImplementations($hook) as $module) {
$this->moduleHandler->invoke($module, $hook);
// Или..
$function = $module . '_' . $hook;
$function(...$args);
}
Сейчас:
$hook = 'myhook';
// Простой пример:
$this->moduleHandler->invokeAllWith($hook, function (callable $hook, string $module) {
$hook();
});
// Продвинутый пример, на случай если вы хотите добавить данные или жонглировать состоянием:
$results = [];
$this->moduleHandler->invokeAllWith($hook, function (callable $hook, string $module) use (&$results) {
$results[$module] = $hook();
});
// Получение списка модулей, реализующих хук, также просто, как использовать переменную $module.
$implementors = [];
$this->moduleHandler->invokeAllWith($hook, function (callable $hook, string $module) use (&$implementors) {
// Небольшой оверхед так как хук не будет вызван.
$implementors[] = $module;
});
¶Модуль Aggregator объявлен устаревшим
Модуль Aggregator объявлен устаревшим и будет удалён в Drupal 10.
Если вы хотите продолжить использовать функционал предоставляемый модулем Aggregator, прочтите рекомендации по его замене.
¶Блоки и плагины лейаутов получили возможность определять, находятся ли они в режиме предпросмотра или нет
В ядро добавлен новый интерфейс PreviewAwarePluginInterface
, который реализуют BlockBase
и LayoutDefault
классы. Данная возможность позволяет определить, в каком состоянии сейчас происходит рендер содержимого, в режиме представления или в обычном при помощи нового свойства $this->inPreview
.
На данный момент этот функционал используется только модулем Layout Builder.
Пример блока:
/**
* An example block that uses preview mode detection.
*
* @Block(
* id = "preview_aware_block",
* admin_label = "Preview-aware block",
* )
*/
class PreviewAwareBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$markup = $this->t('This block is being rendered normally.');
if ($this->inPreview) {
$markup = $this->t('This block is being rendered in preview mode.');
}
return [
'#markup' => $markup,
];
}
}
Пример Layout плагина:
/**
* An example layout that uses preview mode detection.
*
* @Layout(
* id = "preview_aware_layout",
* label = @Translation("Preview-aware layout"),
* regions = {
* "main" = {
* "label" = @Translation("Main Region")
* }
* },
* )
*/
class PreviewAwareLayout extends LayoutDefault {
/**
* {@inheritdoc}
*/
public function build(array $regions) {
$build = parent::build($regions);
if ($this->inPreview) {
$build['main']['#attributes']['class'][] = 'layout-preview';
}
return $build;
}
}
¶Библиотека Backbone.js объявлена устаревшей и для внутреннего применения
Библиотека Backbone.js объявлена устаревшей и для внутреннего применения. Библиотека будет удалена в Drupal 10.0.0.
¶Добавлена поддержка post update хуков для тем оформления
Темы оформления теперь поддерживают post update хуки для того чтобы у разработчиков появилась возможность устанавливать зависимости, а также исправлять настройки темы, если это необходимо.
Это значит, что темы оформления теперь поддерживают файл THEME.post_update.php
, который может содержать реализации HOOK_post_update_NAME()
и HOOK_removed_post_updates()
:
/**
* Install a dependent module.
*/
function test_theme_depending_on_modules_post_update_module_install(&$sandbox = NULL) {
\Drupal::service('module_installer')->install(['test_another_module_required_by_theme']);
}
Данные обновления будут запускаться как и их аналоги для модулей: на странице /update.php
, либо при помоищ Drush команды drush updb
.
¶Библиотека Underscore JS объявлена устаревшей
Библиотека Underscore JS объявлена устаревшей и только для внутреннего пользования. Библиотека будет удалена в Drupal 10.0.0.
Замена данной библиотеке не предоставляется, вместо этого используйте современные возможности JavaScript. Для более удобного перехода вам может пригодиться репозиторий You-Dont-Need-Lodash-Underscore.
¶Добавлен интерфейс для настройки loading значения для изображений обработанных Drupal
Добавлен интерфейс для настройки loading
значения для изображений обработанных Drupal. Это значит, что вы сможете настроить какое значение для изображений будет установлено по умолчанию. На данный момент значение равно loading="lazy"
.
¶Библиотека core/drupal.date и метод Drupal\Core\Render\Element\Date::processDate() объявлены устаревшими
Библиотека core/drupal.date
использовалась для поддержки браузеров, которые больше не будут поддерживаться в Drupal 10, в связи с чем она объявлена устаревшей. В дополнении к библиотеке, метод Drupal\Core\Render\Element\Date::processDate()
, который добавлял аттрибут data-drupal-date-format
, также объявлен устаревшим. Данный аттрибут больше не будет присутствовать в HTML разметке, так как использовался устаревшей библиотекой.
¶Тема оформления Claro помечена стабильной и является административной темой по умолчанию
Тема оформления Claro с этого релиза является стабильной и пригодна для использования на живых проектах.
Начиная с данного релиза, Claro будет использована в качестве административной темы по умолчанию при установке сайта с использованием стандартного профиля и демонстрационного профиля Umami.
¶Тема оформления Olivero теперь является темой по умолчанию
Тема оформления Olivero теперь является темой по умолчанию при установке стандартного профиля.
¶Стартовые темы теперь могут участвовать в процессе генерации новой темы
Для тем, которые являются стартовыми (шаблонными) и используются для генерации новых тем, добавлена возможность также выполнять свои действия в процессе генерации новой темы.
Для этого в теме необходимо создать класс StarterKit
в директории THEME/src
. Данный класс должен реализовывать интерфейс StarterKitInterface
.
Пример:
<?php
namespace Drupal\starterkit_theme;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Theme\StarterKitInterface;
final class StarterKit implements StarterKitInterface {
/**
* {@inheritdoc}
*/
public static function postProcess(string $working_dir, string $machine_name, string $theme_name): void {
$info_file = "$working_dir/$machine_name.info.yml";
$info = Yaml::decode(file_get_contents($info_file));
unset($info['hidden']);
file_put_contents($info_file, Yaml::encode($info));
}
}
¶Добавлена новая вкладка «Управление разрешениями» после вкладки «Управление отображением»
При редактировании типа материала, словаря таксономии или иных типов сущностей, администраторы сайтов уже имеют вкладки: Редактирование, Управление полями, Управление отображением и т.д.
Начиная с текущего релиза добавлена новая вкладка «Управление разрешениями». Она будет появляться, если соответствующие сущности предоставляют необходимые данные для вкладки. На данной странице будут представлены все настройки прав доступа связанные с данной сущностью и её типами.
¶Для разработчиков модулей
Данный функционал поддерживается сущностями с подтипами (бандлами). В будущем это ограничение может быть ослаблено.
Если вы хотите добавить вкладку управления правами для своего типа сущности, вам необходимо объявить следующие ключи в аннотации сущности: handlers.route_provider.permissions
и links.entity-permissions-form
.
Например из MediaType.php
:
* @ConfigEntityType(
* ...
* handlers = {
* ...
* "route_provider" = {
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
* "permissions" = "Drupal\user\Entity\EntityPermissionsRouteProvider",
* }
* },
* ...
* bundle_of = "media",
* ...
* links = {
* ...
* "entity-permissions-form" = "/admin/structure/media/manage/{media_type}/permissions",
* ...
* },
* )
Провайдер маршрутов должен быть либо Drupal\user\Entity\EntityPermissionsRouteProvider
, либо Drupal\user\Entity\EntityPermissionsRouteProviderWithCheck
.
Для того чтобы у пользователей был доступ к данной форме, у них должно быть разрешение administer permissions
. Если вы будете использовать EntityPermissionsRouteProviderWithCheck
, тогда проверка доступа к странице будет провалена если нет ни одного разрешения имеющего зависимость на текущую сущность. При этом, ссылки на данную форму будут также скрыты.
Проверка прав доступа может быть медленной и если вы столкнулись с данной проблемой, рекомендуется использовать EntityPermissionsRouteProvider
вместо EntityPermissionsRouteProviderWithCheck
.
Если ваша сущность является сущностью подтипом для сторонней сущности, а та сущность имеет в аннотации field_ui_base_route
, тогда вкладка появится автоматически.
В качестве альтернативы, вы можете объявить маршрут для соответствующей формы самостоятельно, например:
entity.filter_format.permissions_form:
path: '/admin/config/content/formats/manage/{bundle}/permissions'
defaults:
_title: 'Manage permissions'
_form: 'Drupal\user\Form\EntityPermissionsForm'
bundle_entity_type: filter_format
requirements:
_permission: 'administer permissions'
options:
parameters:
bundle:
type: 'entity:filter_format'
with_config_overrides: true
Это будет крайне полезно в тех случаях, когда у сущности нет UI для управления типами.
¶Команды yarn build:js и yarn watch:js объявлены устаревшими
Внутренние команды yarn build:js
и yarn watch:js
объявлены устаревшими и будут удалены в Drupal 10, так как все браузеры, которые поддерживает Drupal, поддерживают ES6.
¶Добавлено новое разрешение view update notifications
В Update модуль было добавлено новое разрешение «Просмотр уведомлений об обновлениях». Это разрешение позволяет настраивать то, кто будет видеть уведомление о новых обновлениях для Drupal на административных страницах.
Для уже существующих сайтов данное разрешение будет установлено всем ролям которые имеют разрешение administer site configuration
.
¶Модуль Color объявлен устаревшим
Модуль Color объявлен устаревшим и будет удалён в Drupal 10.0.0.
Функционал модуля вынесен в сторонний модуль drupal/color.
¶Добавлен новый метод Token::replacePlain()
Некорректное использование системы токенов может привести в двойному экранированию или поломке разметки. Для предотвращения данного рода проблем, в Token API были внесены улучшения в документацию, а также новый метод, который позволяет производить замену в тексте без обработки.
Примеры правильного применения:
-
::replace()
: На ввод и вывод передаётся разметка. Возвращаемое значение должно расцениваться как небезопасное, даже если на входе вы передали «безопасную» разметку. Это необходимо в связи с тем, что позволяет производить атаку когда результатом токена может оказаться небезопасная разметка. -
::replacePlain()
: На ввод и вывод передаётся обычный текст.
Ранее:
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Component\Utility\Html
PlainTextOutput::renderFromHtml($token_service->replace(Html::escape($plain)));
Сейчас:
$token_service->replacePlain($plain);
¶Константа \Drupal::MINIMUM_SUPPORTED_PHP объявлена устаревшей в пользу динамического метода
Для того чтобы предоставить сайтам максимально полную информацию о текущих поддерживаемых и рекомендуемых версиях PHP, константа \Drupal::MINIMUM_SUPPORTED_PHP
объявлена устаревшей и заменена новым методом \Drupal\Core\PhpRequirements::minimumSupportedPhp()
.
Данный метод возвращает версию PHP на основе известных и ожидаемых релиз циклах для PHP и Drupal.
¶drupal/core-recommended теперь позволяет устанавливать обновления патч-версий
Метапакет drupal/core-recommended
теперь позволяет устанавливать обновления патч-версий. Это означает что владельцы сайтов, использующие drupal/core-recommended
, теперь могут обновления зависимостей ядра при помощи Composer самостоятельно, не дожидаясь официального релиза Drupal с обновлёнными версиями.
¶Action
-
#3067299 Миграции модуля перенесены в модуль
system
.
¶Aggregator
- #2610520 Улучшена справка о блоке предоставляемом модулем.
-
#3267052 Справка по модулю была перенесена непосредственно в модуль из
help_topics
модуля. -
#3265424 Тесты для миграций связанные с модулем
aggregate
перенесены в сам модуль. -
#3267508 В тестах модуля теперь используется фикстура предоставляемая самим модулем вместо
migrate_drupal
. -
#3267274 Тест
MigraetBlockTest
теперь использует собственную фикстуру вместо предоставляемой модулемmigrate_drupal
. -
#3264122 Тесты связанные с модулем
aggregate
перенесены в сам модуль.
¶Big Pipe
-
#3270835 Регрессионный тест для CKEditor 4 перенесён в соответствующий модуль
ckeditor
. -
#3276839 Удалены остатки кода от свойства
$dumpHeaders
.
¶Block
- #3273072 Исправлена опечатка в туре по модулю.
- #3271507 Тесты модуля теперь используют тему оформления Stark вместо Classy.
-
#2430133 Внесены улучшения в
BlockLanguageTest
.
¶CKEditor 4
- #3271046 Тесты CKEditor 4 для проверки Inline Form Errors перенесены непосредственно в модуль редактора.
-
#3281438
CKEditorTest
больше не использует темы Bartik и Seven.
¶CKEditor 5
- #3258250 CKEditor обновлён до версии 31.1.0.
- #3258030 Поля с CKEditor 5 редактором теперь имеет красную рамку если в поле ошибка.
- #3271050 Тесты для REST и JSON:API связанные с редактором теперь используют CKEditor 5 вместо CKEditor 4.
-
#3275114 В
MAINTAINERS.txt
добавлены мейнтейнеры CKEditor 5. -
#3231334 Добавлена поддержка глобальных аттрибутов
<* lang>
и<* dir="ltr rtl">
. -
#3283599 Исправлена опечатка в
hook_help()
.
¶Claro
- #3214170 Кнопка «Отмена» теперь отцентрована в off-canvas модальном окне.
-
#3247994 Исправлена неполадка, из-за которой мог некорректно работать элемент формы
password
. - #3184667 Улучшено отображение формы материала на широкоформатных экранах.
- #3168326 Улучшено отображение dropbutton элемента в таблицах.
-
#3264220 Удалено переопределение шаблона
views-ui-views-listing-table.html.twig
. -
#3214124 Добавлены кавычки для
<blockquote>
элемента. -
#3171728 Улучшено отображение
<select>
элемента формы в режиме Windows High Contrast. -
#3067697 Исправлена неполадка, из-за которой элемент
dropbutton
работал некорректно если текст имел перенос на следующую строку. -
#3269417 Улучшено отображение разделителя хлебных крошек в режиме
forced-colors
. - #3210435 Исправлена неполадка, из-за которой дополнительные вкладки могли отображаться некорректно.
-
#3271305 Улучшено отображение радио кнопок и чекбоксов в режиме
forced-colors
. - #3020418 Улучшена контрастность для заполнителей элементов форм.
-
#3081489 Удалён дублирующийся код в
vertical-tabs.es6.js
. -
#3266216 Улучшена контрастность для
.section-title
элемента Views. - #3251709 Добавлены новые градации синего.
¶Color
- #3270897 Обновлены тесты проверяющие корректную миграцию при удалении модуля Color.
- #3270905 Help Topics для модуля Color перенесены непосредственно в него.
- #3270842 Объявлены переменные с градацией красного цвета.
¶Comment
-
#3090187 Добавлена возможность отключить preprocess для полей
created
,uid
,pid
иsubject
с последующей настройкой отображения при помощи «Параметры отображения». См.enable_base_field_custom_preprocess_skipping
. - #3267653 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Composer
- #3246595 Зависимости ядра обновлены на 01.11.21.
-
#3255623 Удалены замены для пакетов
paragonie/random_compat
иsymfony/polyfill-php70
. -
#3258276 В Composer скрипте
drupal-phpunit-upgrade
убрана опция--no-suggest
при установкеphpspec/prophecy-phpunit
. -
#3225706 Произведён рефакторинг
ComposerProjectTemplatesTest::testMinimumStabilityStrictness()
так, чтобы при ошибке писалось, с каким пакетом возникли проблемы. - #3278162 Зависимости ядра обновлены на 06.05.2022.
-
#3262874 Зависимость
drupal/coder
обновлена до 8.3.15. -
#322596
guzzlehttp/guzzle
теперь может быть как 6 так и 7 версии. -
#3282050 Исправлен некорректный хеш в
composer.lock
, который приводил к провалу теста. -
#3282342 Минимальные версии
guzzlehttp/guzzle
обновлены до 6.5.6 и 7.4.3. - #3281578 Обновлены минимальные патч версии для всех зависимостей ядра.
- #3283093 Зависимости ядра обновлены на 30.05.2022.
-
#3277025 В фикстуру
composer.json.tmpl
добавлена конфигурацияallow-plugins
. - #3285572 Зависимости ядра обновлены на 15.06.2022.
-
#3285696
symfony/http-foundation
откачен до версии 4.4.41, так как 4.4.42 конфликтует со старым способом генерации случайных идентификаторов сессии.
¶Configuration System
-
#2343517 Удалён код и упоминания с
@todo
на задачи, которые решены. - #2540794 Административный интерфейс синхронизации конфигураций теперь корректно отличает пустые временные конфигурации и что они соответствуют текущей активной конфигурации.
-
#3232494 Оптимизирована работа
StorageCopyTrait
. - #3268443 Тесты модуля теперь используют тему оформления Stark вместо Classy.
-
#3284270
ConfigImporter
теперь сбрасывает массив с ошибками при повторной валидации.
¶Contact
- #3268708 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Content Translation
- #2873648 Улучшена производительность при выводе множества альтернативных ссылок для разных языков.
-
#3278032 Из
ContentTranslationController
удалён неиспользуемый код. - #3272558 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Contextual Links
- #3269266 Тесты модуля теперь используют тему оформления Stark вместо Classy.
-
#2168711 Исправлена неполадка, при которой, использование
Modernizr.touchevents
могло приводить к поломке контекстуальных ссылок. - #3277311 Contextual JS API теперь является внутренним и помечено устаревшим.
-
#3276565
larowlan
добавлен в качестве мейнтейнера модуля.
¶CSS
- #3215517 Исправлена неполадка, из-за которой множественный список выбора некорректно отображался в Chrome.
¶Database Logging
-
#3246471 Из класса
DbLogController
удалены свойства, которые объявлены у родительского. - #3269267 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Database System
-
#3213644 Внесены улучшения в тест
StatementWrapperLegacyTest::testClientStatementMethod()
. -
#3259532 Добавлено тестирование
::hasJson()
. -
#2236983 Улучшена документация для метода
Database::addConnectionInfo()
. - #3284502 Исправлена неполадка, из-за которой могли некорректно загружаться драйверы баз данных.
¶Datetime
-
#3251100 Исправлена неполадка, из-за которой
DateTimeWidgetBase
дважды устанавливал одну и ту же временную зону. - #3269517 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Editor
-
#3263873 Библиотеке
editor/drupal.editor.admin
добавлена зависимостьcore/underscore
.
¶Entity System
-
#3260520
\Drupal\Core\Entity\EntityTypeEvent
и\Drupal\Core\Field\FieldStorageDefinitionEvent
теперь наследуются отEvent
вместоGenericEvent
. -
#3269215 Тайпхинт для
EntityTypeInterface::getKey()
теперь содержитFALSE
вместоbool
, так как он никогда не возвращаетTRUE
.
¶Extension System
-
#3245622 Ссылкам на справку и права доступа конкретного модуля, в списке модулей, добавлено указание, для какого модуля они а также
title
аттрибуты. - #3250585 Добавлено отображение информации об устаревших модулях и темах на страницу отчётности.
-
#3259850 Исправлена неполадка, из-за которой мог проваливаться тест
InstallUninstallTest
, если у модуля, объявленного устаревшим, была зависимость на стабильный. -
#3259888 Исправлена неполадка, из-за которой мог проваливаться тест
InstallUninstallTest
, если выключать одновременно модули объявленные устаревшими и экспериментальными. -
#3215044 Добавлена пометка об устаревших темах на странице
/admin/appearance
. -
#3258782 Устаревшие модули больше не отображаются на странице
/admin/modules
. -
#3266308 Значение для
%extensions
заполнителя на странице статуса теперь имеет корректное значение. -
#3266397 Добавлена пометка о нестабильных модуля на странице
/admin/modules/uninstall
.
¶Field System
-
#3213023
FieldConfig
теперь выводит более полезные и понятные сообщения об ошибках. - #3269502 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Field UI
- #3254866 Обновлены сообщения об устаревшем коде, который указывал что код, связанный со страницами управления разрешений, объявлен устаревшим в Drupal 9.3.0, вместо Drupal 9.4.0.
-
#1948572 Добавлена документация для свойства
#region_callback
в элементеfield_ui_table
.
¶Filter
- #3227821 Исправлена неполадка в фильтре «Заменять переводы строк соответствующими HTML-тегами», которая могла приводить к поломке SVG элементов.
-
#3272516 Метод
FilterInterface::getHTMLRestrictions()
объявлен устаревшим. Это также значит что и функционалforbidden_tags
объявлен устаревшим. - #3272354 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Image
- #3223233 Улучшены заголовки страниц для форм добавления и редактирования стилей изображений.
-
#3060875
ImageStyleStorageInterface
теперь расширяетConfigStorageInterface
. - #3272581 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Install System
- #3280398 Post update хуки теперь корректно указывают тип расширения на странице обновлений.
- #2392815 Теперь, при удалении модулей, запускаются проверки конфигураций, что модуль может быть удалён, прежде чем действительно его удалять.
¶JavaScript
-
#3238860 Использование
jQuery.map()
заменено на нативнуюmap()
функцию. -
#3239500 Добавлен полифил для
Array.includes()
. -
#3239134 Использование
jQuery.val()
заменено на нативные.value
. -
#3239123 Использование
jQuery.text()
заменено на нативный.textContent
. - #3246211 Stylelint обновлён до 14 версии.
-
#3264520 Удалена зависимость
acorn
. -
#3258114 Зависимость
chromedriver
обновлена до 98 версии. -
#3265618 Зависимость
eslint
обновлена до 8 версии. -
#3265619 Зависимость
Shepherd.js
обновлена до 9 версии. - #3261734 Минимальная версия Node.js увеличена до 16.
- #3239838 Из ESlint конфигурации удалены неиспользуемые правила для React и JSX.
- #3233491 Добавлена операция проверки изменений в сторонних JavaScript зависимостях (без предварительной минификации).
-
#3265664 Зависимость
jsdom
обновлена до 19 мажорного релиза. - #3278786 Зависимости ядра обновлены на 12.05.22.
-
#3101922 Функционал
touchevent
из Modernizr заменён нативной реализацией. -
#3280359 Библиотека
jquery.form
теперь является внутренней и будет удалена в Drupal 10.
¶JSON:API
-
#3199696
ResourceObject
теперь учитывает текущий язык и корректно кеширует результаты для мультиязычных ресурсов. - #3031271 JSON:API теперь поддерживает версионирование для всех версионных типов сущностей.
¶HAL
- #3263654 Тесты, связанные с модулем HAL, были перенесены непосредственно в модуль, в целях последующего удаления месте с модулем.
¶Help Topics
- #3272537 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶History
- #3272543 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Language
- #3275530 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Layout Builder
-
#3253666
LayoutTempstoreRouteEnhancer
теперь используетDrupal\Core\Routing\RouteObjectInterface
вместоSymfony\Cmf\Component\Routing\RouteObjectInterface
. -
#3190541 Исправлена неполадка, из-за которой кеш-контекст
layout_builder_is_active
мог предоставлять некорректные значения.
¶Link
- #3274096 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Locale
- #3274265 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Mail System
-
#3265429 Улучшены ключи в
MailManagerTest
.
¶Media
-
#3254198 Удалена временная проверка на наличие модуля
media_entity
.
¶Media Library
-
#3173770
MediaLibraryFieldWidgetOpener
теперь позволяет использовать другие референс поля, расширяющее поле из ядра и использующиеEntityReferenceFieldItemList
. -
#3248454 Внесены улучшения в
MediaLibraryStateTest
для совместимости с Symfony 5.4.
¶Menu Link Content
- #3245553 Улучшена миграция мультиязычных ссылок из Drupal 6.
¶Migration System
-
#3246053 Обновлено значение
filesize
файлаds9.txt
вfile_managed
. -
#3163663 Исправлена неполадка из-за которой плагин-обработчик
download
мог приводить к предупреждению «failed to open stream: Too many open file». -
#3087332 Плагин-обработчик
d6_url_alias_language
объявлен устаревшим. - #3042533 Внесены улучшения в миграцию словарей таксономии из Drupal 6.
-
#3240109 Возвращаемый тип данных для
MigrateProcessInterface::transform()
изменён сstring|array
наmixed
. -
#3258009 Удалены два неиспользуемых и сломанных плагина
fieldleft
иfieldright
. -
#3240873 Добавлено тестирование для
hash
свойства. -
#3226401 В
Migration
добавлена информация, что миграции можно создавать вMODULENAME/migrations
. - #3254347 Исключения для плагинов-обработчиков теперь содержат название плагина, в котором выброшено исключение.
- #3265483 Улучшены миграции для блоков тех модулей, которые стали сторонними после Drupal 6 или Drupal 7.
¶Node
- #3274066 Тесты модуля теперь используют тему оформления Stark вместо Classy.
-
#3275464 Удалён устаревший метод
FrontPageTest::testAdminFrontPage()
. -
#3259671 Улучшена
производительность для запроса генерируемого плагином аргумента Views
node_vid
.
¶Olivero
- #3186992 Исправлена неполадка, из-за которой навигационные пункты меню могли выходить за рамки контейнера.
-
#3256433 Класс
wide-image
больше не добавляется на картинку профиля пользователя. -
#3187908 Исправлен некорректный шрифт для
placeholder
значения в строке поиска. - #3256003 Исправлена неполадка, из-за которой кнопка закрытия модального окна могла быть некорректных размеров.
- #3270574 В шаблон комментария добавлен индикатор «нового» комментария.
- #3269716 Исправлена неполадка, из-за которой строка поиска была недоступна на Safari.
- #3209903 Исправлена неполадка, из-за которой изображение могло перекрывать кнопки «Add block» и «Add section» в Layout Builder.
-
#3276615 Удалена реализация
olivero_form_comment_form_alter()
. -
#3271666 Улучшено отображение иконок пагинации в режиме
forced-colors
. -
#3276618 Классы активного пункта меню для
book-tree.html.twig
теперь соответствуют классам из меню. -
#3226016 Классы в шаблоне
form--search-block-form.html.twig
теперь задаются в массиве, а не сразу присваиваются обёртке. - #3278215 Опциональные конфигурации блоков перенесены в тему из стандартного профиля.
-
#3278696 Конфигурации
block.block.book_navigation.yml
иblock.block.primary_admin_actions.yml
были переименованы вblock.block.olivero_book_navigation.yml
иblock.block.olivero_primary_admin_actions.yml
соответственно. - #3277557 Улучшено отображение процентной метки в прогресс баре.
-
#3274080 Улучшено отображение мобильного меню в режиме
forced-colors
. -
#3279693 Исправлено отображение ссылок с классом
button
иbutton--primary
внутри контейнераtext-content
. - #3246755 Меню с большим кол-вом элементов теперь конвертируются в мобильную навигацию.
- #3223264 Исправлена неполадка, из-за которой отображение системных сообщений при помощи JS могло быть пропущено если на странице уже есть системные сообщения добавленные бэкендом.
¶RDF
- #3267513 Тесты миграций связанные с RDF теперь учитывают что модуль будет удалён.
¶Render System
-
#2958358
drupal/core-utility
больше не зависит отdrupal/core-render
, аdrupal/core-gettext
теперь зависит отdrupal/core-render
вместоdrupal/core-utility
.
¶Responsive Image
- #3267870 (отменено) Стили для точек остановы теперь сортируются в порядке возрастания множителя, а затем по ID стиля.
¶REST
-
#3277148
ResourceResponse
теперь содержит информацию в документации о том что маршрут для такого ответа должен содержать_format
.
¶Standard Profile
-
#3171149 Стандартный профиль теперь использует стиль изображения
wide
для публикаций вместоlarge
. - #3278568 В профиль добавлены опциональные конфигурации блоков для Bartik и Seven.
- #3278565 Из профиля удалены конфигурации блоков для Claro.
¶Statistics
- #3272734 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶System
-
#3279640 При использовании темы оформления Claro в качестве административной, она также будет использована для страницы
update.php
. - #3279850 Исправлена неполадка, из-за которой обновления не распознавались если тема используется в установщике.
-
#3276652
AssertMenuActiveTrailTrait
теперь опирается на конкретный класс независящий от темы оформления.
¶Taxonomy
-
#3272722 Исправлена ошибка в рекомендации для функции
taxonomy_term_load_multiple_by_name()
. - #3248295 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Toolbar
- #3257504 Тулбар больше не показывает кнопку переключение между горизонтальной и вертикальной ориентацией если в тулбаре нет никаких пунктов.
¶Tracker
- #3263793 Help Topics для модуля Tracker были перенесены в его модуль.
¶Quick Edit
- #3264945 Вся документация Quick Edit была перенесена непосредственно в модуль.
-
#3279840 Исправлен тест
SettingsTrayIntegrationTest::createBlockContent()
. -
#3265140
QuickEditImageController
перемещён из модуля image в quickedit. - #3265492 Исправлены неточности в документации модуля для Help Topics.
¶Update
-
#3253639 Добавлен новый класс
UpdateUploaderTestBase
с универсальной реализацией::setUp()
для уменьшения дублирования кода в тестах модуля. -
#3238311 Маршрут
system.batch_page.html
добавлен в список маршрутов, на которых не показываются предупреждения об обновлениях безопасности. - #2807949 Исправлена неполадка, из-за которой не происходила очистка кеша модуля в момент установки или удаления сторонних модулей, что приводило к ненужным загрузкам переводов и прочим ошибкам. Эта проблема наблюдалась при включении или отключении модуля без участия интерфейса расширений Drupal (например через Drush).
-
#3275216 Обновлён Dependency Injection в
UpdateSettingsForm
. -
#3272956 В
ProjectSecurityData
добавлены даты EOL для Drupal 9.4 и Drupal 9.5.
¶Umami
- #3278732 Удалены конфигурации для блоков Claro.
¶User
-
#3198010 Улучшено отображение ошибки о неудачных попытках авторизации, чтобы снизить нагрузку на систему.
UserLoginForm
теперь принимает сервисbare_html_page_renderer
в качестве аргумента. - #1777270 Добавлены тесты для блока авторизации, которые покрывают ситуации, что можно авторизоваться с паролем длинной до 128 символов.
- #3247694 Тесты модуля теперь используют тему оформления Stark вместо Classy.
- #3258321 Кнопка удаления аккаунта в форме редактирования пользователя заменена на ссылку.
-
#3268105 Добавлен новый тест
UserRegistrationRestTest
.
¶Views
-
#2569381 Из
Drupal\views\Plugin\views\area\Result
удалён лишний вызовXSS::adminFilter()
. - #1810148 Исправлена неполадка, из-за которой сгруппированные раскрытые фильтры по терминам таксономии могли не работать.
-
#2845571 Исправлена неполадка, из-за которой плагин
ViewsJoin
не учитывал выбранный оператор.
¶Views UI
- #2807241 Исправлена неполадка, из-за которой список с добавлением новых страниц представлений не работал на отличных от английского языках.
¶Workspaces
- #3272737 Тесты модуля теперь используют тему оформления Stark вместо Classy.
¶Symfony 6
-
#3232074 Для классов расширяющих
Normalizer
добавлен тайпхинтarray|string|int|float|bool|\ArrayObject|null
методу::normalize()
. -
#3232095 Произведён рефакторинг сервиса
update.root
для того чтобы он возвращал объект вместо строки. -
#3232131 В
DebugClassLoader
добавлены тайпхинты. - #3250299 Внесены улучшения в констрейнты для совместимости с Symfony 6.
-
#3250442 Код с использованием Prophecy на методы с тайпхинтом на возвращаемое значение
static
заменены на моки для исправления проблем, пока поддержка не появится в Prophecy.
¶Тестирование
-
#3258995
run-tests.sh
теперь использует\Drupal::service('app.root')
вместо\Drupal::root()
. -
#2867871 В
OptimizedPhpArrayDumperTest
улучшено использование Symfony Expression. -
#3212346 Добавлен абстрактный тест
ConfigEntityResourceTestBase
. Тесты для конфигурационных сущностей и их ресурсов теперь расширяют данный тест. Это уменьшает количество установок Drupal в процессе тестирования. -
#3257407
BlockCreationTrait::placeBlock()
теперь помещает блоки вcontent
регион вместоsidebar_first
. -
#3253715 Обновлены тесты, в которых использовался
isset()
с результатамиxPath
. -
#3265546 Модули и темы оформления со свойством
lifecycle: deprecated
теперь исключаются из установки вDefaultConfigTest
. -
#3260710
UpdateUploaderTestBase
теперь является абстрактным классом. -
#3268932 В
WebAssert
добавлены методы для сравнения статусных сообщений. -
#3272727 Внесены улучшения в команду
drupalModuleInstall()
для Nightwatch. - #3275093 Обновлены дампы БД для Drupal 9.3.0 тестов.
-
#3266739 Из
FunctionalTestSetupTrait::prepareEnvironment()
удалён комментарий о том что метод является приватным. -
#3276620 Тест
NoJavaScriptAnonymousTest
теперь используетstark
тему оформления. -
#3279788
RequirementsPageTrait::assertRequirementSummaries()
теперь учитывает что темой оформления дляupdate.php
может быть и Claro. -
#3280882 Исправлена неполадка в
KernelTestBase
из-за которой свойствам теста с тайпхинтами нужно было добавлять?
к типу.
¶Прочие изменения
-
#3038596 В
drupalci.yml
добавлено напоминание о том, что данный файл требуется в ручном изменении при создании ново ветки ядра. -
#3245820 Из кода удалены упоминания удалённого
\Drupal\Core\Action\Plugin\Action\PublishAction
. -
#3250263 Удалён неиспользуемый файл
core/scripts/test/test.script
. - #3251891 Исправлены неполадки, приводящие к проблемам на ветке Drupal 10.
-
#3251988 Обновлена документация о возвращаемых типах данных для
JSWebAssert::waitForText()
. -
#3256451 Исправлен некорректный хэш в
composer.lock
. - #3210129 Внесены исправления опечаток для слов, начинающихся с «a» до «d» включительно.
-
#3175428 В документацию настройки
trusted_host_patterns
добавлена ссылка на более детальную документацию. -
#3031130 Улучшено поведение для
\Drupal\Core\KeyValueStore\MemoryStorage::rename()
. Если старое название и новое идентичны, данные не будут удалены, как это было ранее. -
#3258014 Оформление информации об устаревшем коде улучшено для
Drupal\migrate_drupal\Plugin\migrate\field\NodeReference
иDrupal\taxonomy\Plugin\views\argument_validator\Term
. -
#3256539
ContentEntityDeleteForm
больше не помечен как внутренний класс (@internal
), это означает, что вы теперь можете использовать и наследоваться от этой формы. -
#3259996 Использование
t()
для списков с ссылками вsystem_requirements()
заменено наMarkup
. -
#3181275 При использовании PHP 8+, Drupal больше не будет выдавать ошибку при использовании
phar://
URI. Так как на PHP 7 он имеет уязвимости, его использование будет по-прежнему запрещено. -
#3252406 Класс
PharExtensionInterceptor
помечен для внутреннего пользования@internal
. -
#3229714 Исправлена область видимости для метода
ContextAwarePluginTrait::getPluginDefinition()
сprotected
наpublic
. -
#3164210 Везде где
array_merge()
используется внутри цикла, внесены улучшения в код для увеличения производительности. -
#3248879 Внесены улучшения в тест
UpdatePathTestTrait
. - #3259953 Ссылка на отчёт о состоянии системы теперь располагается вверху.
-
#3224178 Из
theme.api.php
удалены упоминанияtheme()
функции. -
#3264435 Внесены улучшения в тесты модулей
help_topics
иrest
, в которых не фильтровались устаревшие модули. - #3260568 В процессах установки профилей Demo Umami и Стандартный исправлено то, как добавляются роли для административного пользователя.
- #3259928 Тесты, проверяющие функционал на «всех темах» теперь также проверяют Olivero.
-
#3262320 Удалён устаревшее исправление в
ContextualLinksTest
. -
#3261517 Из
InstallTest
удалено упоминание ныне несуществующей функцииdrupal_get_schema()
. -
#3267721 В
commit-code-check.sh
добавлена проверка, что CKEditor 5 плагины успешно собраны. -
#3270323 Исправлена неполадка в тесте
ModuleConfigureRouteTest::testModuleConfigureRoutes()
. - #3264911 Из стилей тем оформления удалено упоминание подозрительного сайта.
- #3261611 Ссылки на системные требования обновлены на универсальные.
- #2917655 Прекращена поддержка PHP 7.3.
-
#3270886 Удалена устаревшая заметка в
drupalci.yml
. -
#3013802 Улучшено сообщение об ошибке для
Url
объектов с несуществующим маршрутом. -
#3270395 Библиотеки
editor/drupal.editor.admin
иfilter/drupal.filter.filter_html.admin
больше не зависят от UnderscoreJS. - #3270941 Модуль Color удалён из стандартного установочного профиля
- #3206226 Тема созданная при помощи команды генерации темы теперь имеет комментарий о том, из какой версии темы исходника она была сгенерирована.
-
#3253286 Из
starterkit_theme
удален ненужны переопределения. -
#3112283 Использование
REQUEST_TIME
заменено на более подходящие функции и методы. - #3279703 Заголовок главной страницы теперь просто «Добро пожаловать».
-
#3282395 Исправлена неполадка, из-за которой PHPStan и
mglaman/phpstan-drupal
не могли обнаружитьPhpUnitCompatibilityTrait
. -
#3284970 Упрощён метод
Settings::initialize()
. -
#3281451
AjaxTest
больше не использует темы Bartik и Seven. -
#3281443
ThemeTest
больше не использует темы Bartik и Seven. -
#3283619 Исправлена опечатка в
core/includes/common.inc
. - #3248078 (отменено) Ссылки ведущие на документацию для Drupal 8 заменены на универсальные.