Дата релиза: 3 июня 2020 Прекращение поддержки безопасности: ноябрь 2021
Данный релиз является переходным с Drupal 8 на Drupal 9.
Drupal 8.9.0 API совместим с Drupal 9.0.0. Главное отличие между версиями — Drupal 9.0.0 не содержит код, который помечен @deprecated
в Drupal 8.9.0.
Изменения в данной версии минимальны, по причине того, что он разрабатывается одновременно с Drupal 9 и все силы направлены на чистку устаревшего кода Drupal 8.
¶hook_install, hook_uninstall, hook_modules_installed и hook_modules_uninstalled теперь получают параметр $is_syncing
Теперь в хуки hook_install()
, hook_uninstall()
, hook_modules_installed()
и hook_modules_uninstalled()
передаётся новый параметр $is_syncing
.
Параметр $is_syncing
будет TRUE
когда модуль устанавливается или удаляется как часть процесса обновления конфигураций. Это позволит корректировать поведение модуля с учётом данного значения. Например, если происходит синхронизация конфигураций, вы не должны производить никаких изменений в конфигурационных объектах и сущностях.
Раньше
/**
* Implements hook_install().
*/
function demo_umami_content_install() {
if (!\Drupal::service('config.installer')->isSyncing()) {
\Drupal::classResolver(InstallHelper::class)->importContent();
}
}
Теперь
/**
* Implements hook_install().
*/
function demo_umami_content_install($is_syncing) {
if (!$is_syncing) {
\Drupal::classResolver(InstallHelper::class)->importContent();
}
}
¶Twig фильтр without() теперь может принимать массив
Иногда требуется перенести большое количество полей из {{ content }}
массива и отрендерить их в ручном режиме.
Вы не можете не рендерить {{ content }}
и просто вызывать поля напрямую, так как это может нарушить целостность кеша.
До текущего изменения without()
принимал лишь аргументы в качестве строк чтобы вы могли контролировать поведение, теперь он может принимать массив из строк.
Ранее
<article>
<div class="fancy">
{{ content.field_fancy_1 }}
{{ content.field_fancy_2 }}
{{ content.field_fancy_3 }}
{{ content.field_fancy_4 }}
</div>
<div class="important">
{{ content.field_important_1 }}
{{ content.field_important_2 }}
{{ content.field_important_3 }}
{{ content.field_important_4 }}
</div>
<div class="content">
{{ content|without('field_fancy_1', 'field_fancy_2', 'field_fancy_3', 'field_fancy_4', 'field_important_1', 'field_important_2', 'field_important_3', 'field_important_4', 'field_special') }}
</div>
<div class="special">
{{ content.field_special }}
</div>
</article>
Теперь
{%
set fancy_fields = [
'field_fancy_1',
'field_fancy_2',
'field_fancy_3',
'field_fancy_4',
]
%}
{%
set important_fields = [
'field_important_1',
'field_important_2',
'field_important_3',
'field_important_4',
]
%}
<article>
<div class="important">
{% for field in important_fields %}
{{ content[field] }}
{% endfor %}
</div>
<div class="fancy">
{% for field in fancy_fields %}
{{ content[field] }}
{% endfor %}
</div>
<div class="content">
{{ content|without(fancy_fields, important_fields, 'field_special') }}
</div>
<div class="special">
{{ content.field_special }}
</div>
</article>
¶Теперь к листингам добавляется новый кеш тег [entity_type]_list:[bundle]
Теперь для листингов возвращается дополнительный кеш тег [entity_type]_list:[bundle]
, если у сущности имеется поддержка бандлов.
Ранее, сущность возвращала кеш тег для списков [entity_type]_list
(node_list
), который автоматически устанавливался на выводы со списком конкретной сущности. Например это делает Views, если вы выводите сущности.
Это приводило к ситуациям, когда обновление одной сущности инвалидировало множество других, не имеющих отношения к текущей. Например, у вас есть типы материалов «Новость» и «Отзыв», а для них созданы страницы с листингом /news
и /reviews
, соответственно. На оба листинга ранее устанавливался кеш тег node_list
, и когда вы правили новость, он инвалидировался и очищал соответствующие кеш данные, но это также задевало листинг отзывов, что совершенно ненужно. Теперь, изменяя новость, будут инвалидированы только новости, а другие типы содержимого останутся в кеше.
Данное изменение позволит снизить частоту обращения и инвалидации кеша без необходимости.
¶Добавлена поддержка поиска библиотек в папке сайта и установочных профилях
Некоторые модули используют модуль Libraries, для того чтобы хранить сторонние библиотеки в отличных от /libraries
директориях. Данное поведение и возможность перенесена в ядро.
Все библиотеки, путь которых начинается с /libraries
теперь ищутся в нескольких директориях в соответствующем порядке:
-
/PATH/TO/SITE/libraries
(например/sites/default/libraries
) -
/libraries
-
/PATH/TO/INSTALL_PROFILE
(например/core/profiles/demo_umami/libraries
)
Первый файл что будет обнаружен и будет использован для библиотеки.
Дополнительно в ядро добавлен новый сервис library.libraries_directory_file_finder
, метод find()
которого полная альтернатива для libraries_get_path()
.
¶Разработчики теперь могут создавать собственные Session Bag
Теперь разработчики могут создавать свои собственные «сессионные мешки» для хранения информации конкретного модуля внутри сессии.
Сессионный мешок должен реализовывать \Symfony\Component\HttpFoundation\Session\SessionBagInterface
и быть объявлен как сервис с меткой. Получить сессионный мешок можно через сессию из запроса.
Пример объявления сервиса:
example.session_bag:
class: Drupal\example\Session\ExampleSessionBag
tags:
- { name: session_bag }
Пример получения сессионного мешка:
$bag = $request->getSession()->getBag(ExampleSessionBag::BAG_NAME);
$bag->setFlag();
¶Темы могут объявлять зависимости на модули
Темы оформления теперь могут указывать зависимости на модули, которые необходимы для работы. Принцип указания зависимостей такойже как и у модулей — при помощи свойства dependencies
.
name: test theme depending on nonexisting module
type: theme
core: 8.x
dependencies:
- test_module_non_existing
¶Оформление и темизация
-
#3040758 В теме оформления Classy на поля с меткой «в строку» теперь добавляется класс
clearfix
. Если вызовет проблемы в вашей теме, вы можете переопределить данное поведение перезаписав шаблонfield.html.twig
в своей теме. - #3115005 Из тем оформления удалён фикс для fieldset в Firefox, так как ошибку в браузере исправили.
-
#2550717 js-cookie (
core/js-cookie
) добавлен в ядро на заменуcore/jquery.cookie
, которая теперь помечена устаревшей.
¶Ban
-
#3126784 Класс
\Drupal\ban\Plugin\migrate\destination\BlockedIP
приведён в соответствии с его названием файлаBlockedIp
.
¶Book
-
#3010378
BookManager::buildItems
теперь не загружает сущности для генерации ссылки, а генерирует роут на основе ID. Это значительно повышает производительность на материалах с большим количество «подшивок». -
#3047806 Справка из
hook_help()
конвертирована в Help Topic.
¶Composer
-
#3127013
wikimedia/composer-merge-plugin
удалён из зависимостей ядра. -
#3121885
drupal/coder
обновлён до 8.3.8. - #3122112 Обновлены зависимости ядра.
- #3144204 Зависимости ядра обновлены перед предстоящим релизом.
¶Claro
- #3078524 Стили фокусировки WYSIWYG элементов приведены к общему стилю.
- #3101040 Исправлена проблема, когда стиль фокусировки обрезался.
¶Database API
-
#3113403 (временно откачено) Все драйверы баз данных теперь должны переопределять
Drupal\Core\Database\Query\Condition
. -
#3118832 Сторонние драйвера баз данные теперь могут иметь те же самые имена что и в ядре. Также, в тестах, терминале и установщике будет использоваться драйвер указанный в
settings.php
в приоритете над стандартным. -
#3120096 Драйвера баз данных теперь могут располагаться в
src/Driver/Database/[DriverName]
под соответствующим неймспейсомDrupal\[module_name]\Driver\[DriverName]
. Drupal теперь будет автоматически находить данные драйвера без необходимости их копировать в/core/lib
или/drivers/lib
. -
#3126940 Теперь в URI до БД нет необходимости указывать опциональный параметр
module
. -
#2956556
StatementPrefetch
теперь передает также$class_name
вfetchOptions
. -
#3125391 В возвращаемые типы данных методом
Connection::query()
добавлено строковое значение, а также описание, когда оно может таким стать. -
#3131379
CONCAT_WS()
больше не используется, когда в фильтре всего 1 аргумент.
¶Entity API
- #3109795 Исправлена неполадка, из-за которой мог отсутствовать контекс для множественного лейбла сущности.
¶Extension API
-
#3066801 Добавлен новый хук
hook_removed_post_updates()
который позволяет указать какиеhook_post_update_N()
реализации были удалены и в какой версии. -
#3039296 Примеры для
hook_install()
иhook_uninstall()
обновлены и упрощены.
¶File
-
#3016814 Теперь хук
hook_file_download()
не будет вызываться при отсутствии аргументов для файла.
¶Field UI
-
#3126617 Исправлена опечатка в теге для Help Topics.
<me>
заменён на<em>
.
¶HAL
- #2907402 Нормализованные данные файловых полей теперь предоставляют информацию о файле.
¶Views
-
#3092185 Добавлен
rel="nofollow"
для заголовков сортировки таблиц.
¶Composer
- #3090416 Представлен Composer плагин Core Project Message.
- #3103090 drupal/core-composer-scaffold теперь не заменяет файлы которые не изменились, а также не выводит сообщение о файлах которые не были изменены. Это сократит выводимое сообщение данным пакетом в композере.
- #3126566 Плагины, предоставляемые Drupal, теперь совместимы с Composer 2.
-
#3134731
drupal/coder
обновлён до версии 8.3.9. - #3134606 Исправлена неполадка приводящая к фатальной ошибке при обновлении с 8.9.x до 9.0.x.
-
#3101210 Удалён
"overwrite": true
в extra разделе по умолчанию. - #3101214 В документации для Drupal Scaffold плагина слегка измёнен пример.
¶Color
-
#3082742 Тип данных возвращаемый функцией
color_valid_hexadecimal_string()
был изменён. До изменения возвращаемый тип был числом (0 или 1), теперь возвращается логическое значение (TRUE
,FALSE
).
¶Config Translation
- #3131388 Добавлен тест на страницу с листингом конфигураций. Исправлен DI приводящий к WSOD.
¶Contextual
- #2891603 Улучшена работа с одинаковыми контекстуальными параметрами.
¶Claro
- #3097651 Улучшено оформление вспомогательных вкладок.
¶Database
- #3135629 Минимальная версия MySQL теперь также будет проверяться в процессе обновлений и на странице о статусе сайта.
-
#3133798 Точка с запятой из запросов будет удаляться из запроса, если они не разрешен в
allow_delimiter_in_query
. -
#2983452 SQLite теперь может использоваться в памяти при помощи URL:
sqlite://localhost/:memory:
.
¶Entity
-
#2766135 Исправлена неполадка в
EntityQuery
, при которой условие на поле ревизии приводило к некорректным результатам.
¶Field
-
#2988309 При сравнении полей при помощи метода
::equals()
теперь не учитываютсяNULL
значения.
¶Form
-
#1831560 Удалён вызов
Html::resetSeenIds()
в процессе обработки формы.
¶JavaScript
- #3136604 jQuery обновлён до 3.5.1.
- #3118741 Обновлены Yarn зависимости (включая обновления безопасности).
¶JSON:API
-
#3115772 Вызовы
User::load
заменены на Dependency Injection.
¶Language
-
#3130438 Сервис
page_cache_kill_switch
вLanguageNegotiationBrowser
теперь добавляется через Dependency Injection.
¶Layout Builder
-
#3101891
@Layout
плагины теперь могут предоставлять ширину колонок по умолчанию при помощиdefault_width
.
¶Locale
- #3119278 Теперь сообщения при обновлении и проверки локазаций будут более информативными. Дополнительно будут выводиться и языковые коды, для которых производится проверка.
¶Migrate
-
#2746541 Добавлена новая миграция
d*_node_complete.yml
, которая именуется как "complete node migration". Данная миграция переносить все ноды, их ревизии, переводы и переводы ревизий. -
#2966856 Модуль
migrate_drupal_multilingual
удалён из зависимостей миграций и скрыт из интерфейса. Мультиязычные миграции теперь стабильны и данный модуль больше не требуется и будет удалён в Drupal 10. -
#3128069 Название модуля «Book» теперь пишется с заглавной буквы в
OverviewForm
. -
#3106304 Для миграции фильтров из Drupal 7 добавлен маппинг фильтров
editor_align
иeditor_caption
. - #3133305 В качестве версии назначения миграции теперь пишется актуальная версия системы сайта вместо мажорной версии.
- #3110669 Добавлены миграции для миграции язковых настроек меню из Drupal 7.
- #3076447 Добавлены миграции переводов для ревизий из Drupal 7.
- #2969231 Улучшены сообщения об ошибках в конфигурациях миграций.
- #3123095 Исправлены ошибки при откате успешных миграций нод.
¶Media
-
#3071682 oEmbed ресурсы должны возвращать либо число больше нуля, либо
NULL
для высоты и ширины.
¶Media Library
- #3127838 Кнопка "Сохранить и вставить" теперь не имеет дополнительного вложения в массиве.
¶Node
- #2946073 Node Grants проверки прав доступа теперь указывают кеш-зависимость для результата доступа.
¶Plugin API
-
#3115987 Свойство
$instanceIDs
переименовано в$instanceIds
.
¶PHP
- #3135250 (Только для Drupal 8.9) Рекомендуемая версия PHP увеличена до 7.3. На момент выхода Drupal 8.9 PHP 7.2 уже будет неподдерживаемой версией.
¶Seven
-
#2980304 Внесены исправления в
<details>
и<summary>
чтобы фокусировка работала во всех браузерах.
¶System
-
#3133604
ThemeExtensionList
теперь всегда содержит информацию о версии темы оформления. Если версия у темы не указана, будет использовано значениеNULL
.
¶Help Topics
-
#3041926 Инструкции
hook_help()
для модулейautomated_cron
,dblog
,syslog
,system
,update
иuser
конвертированы в Help Topics. -
#3087562 Инструкции
hook_help()
для модулейdatetime
,datetime_range
,field
,field_ui
,link
,options
,telehpone
,text
конвертированы в Help Topics.
¶Update
- #3098475 Теперь страница обновления БД будет показывать ожидающие обновления, зависимости и требования которых до сих пор не удовлетворены и они не могут быть применены.
¶Views
-
#3113556 Views UI теперь использует библиотеку
core/drupal.dialog.ajax
вместоcore/jquery.ui.dialog
. -
#3123653 Исправлена опечатка в документации
BulkForm::clickSortable
. -
#2997748 Джоины теперь могут использовать
left_formula
вместоleft_field
для того чтобы применять SQL выражения для левой части джоина. - #3103010 В интерфейсе представлений улучшены пояснения для машинного имени.
-
#3119279 В шаблоне
views-view-table.html.twig
сводка в<details>
теперь подготавливается в препроцессе при помощи рендер массива. Это также подключит полифил для браузеров, в которых нет нативной поддержки данного элемента. - #2974640 Кнопка «Отправка» больше не имеет вес 10.
- #2710407 Исправлена ошибка в формировании запроса по названию термина из URL.
¶Тестирование
-
#3105980 Метод
\Drupal\migrate_drupal\Tests\StubTestTrait::createStub
был переименован вcreateEntityStub
. -
#3118477 Реестр темы теперь создаётся через мок, для того чтобы избежать конфликта когда он создавался в двух разных местах
RegistryTest
иRegistryLegacyTest
. -
#3078671 Зависимость
behat/mink
обновлена до 1.8.0, аbehat/mink-selenium2-driver
до 1.4.0. -
#3121827 Исправлена докуменация в тестах
update_test_last_removed
. -
#3126694 В тесте
ThemeTest
заменено использованиеtpl.twig
наhtml.twig.
-
#3119922
DeleteTruncateTest
больше не опирается на стандартную сортировку, которая может быть разной у каждой БД. Теперь сортировка явно указана. -
#3124769
UiHelperTrait::drupalLogout
теперь получает путь для редиректа напрямую из маршрутаuser.page
вместо захардкоженого/user
. -
#3119924
SelectPagerDefaultTest
больше не опирается на стандартную сортировку, которая может быть разной у каждой БД. Теперь сортировка явно указана. -
#3128575 Использование
is_null()
в сравнениях заменено на нативные методы::assertNotNull()
,::assertNull()
. -
#3130396 Использование
is_file()
в сравнениях заменено на нативные методы::assertFileExists()
,::assertFileNotExists()
. -
#3131090 Использование
is_dir()
в сравнениях заменено на нативные методы::assertDirectoryExists()
,::assertDirectoryNotExists()
. -
#3130811 Удалена передача аргумента
$message
для методов::assertInstanceOf()
и::assertNotInstanceOf()
. -
#3131088 Использование
file_exists()
в сравнениях заменено на нативные методы::assertFileExists()
,::assertFileNotExists()
. -
#3128814 Использование
:assert*
методов для сравнения количества заменено на штатный::assertCount
. -
#3131223 Использование
array_key_exists()
в сравнениях заменено на нативные методы::assertArrayHasKey()
,::assertArrayNotHasKey()
. - #3129074 Произведен рефактор сравнений, результаты которых используются в условиях.
-
#3131258 Удалена передача аргумента
$message
для методов::assertFileExists()
,::assertFileNotExists()
,::assertDirectoryExists()
,::assertDirectoryNotExists()
. -
#3131821 Использование
is_callable()
в сравнениях заменено на нативные методы::assertIsCallable()
,::assertIsNotCallable()
. -
#3131821 Использование
is_numeric()
в сравнениях заменено на нативные методы::assertIsNumeric()
,::assertIsNotNumeric()
. -
#3131816 Использование
is_array()
в сравнениях заменено на нативные методы::assertIsArray()
,::assertIsNotArray()
. -
#3131818 Использование
is_object()
в сравнениях заменено на нативные методы::assertIsObject()
,::assertIsObject()
. -
#3131819 Использование
is_resource()
в сравнениях заменено на нативный метод::assertIsResource()
. -
#3108006 Использование
::assertInternalType
заменено на соответствующие методы:::assertIsArray
,::assertIsBool
и т.д. -
#3128746 Сравнения строк теперь используют более точные методы сравнения вместо
strpos()
и прочих решений. -
#3133103 (Только для Drupal 8.9) Исправлены ошибки сравнения в
InstallerCustomConfigDirectoryCreateTest
. -
#3131343 Использование
in_array()
в сравнениях заменено на нативные методы::assertContains()
,::assertNotContains()
. -
#3137455 Изменены ссылки на ишьюсы в
@trigger_error
AssertLegacyTrait
. -
#3113077 Использование
::assertContains
заменено на новые методы:::assertStringContainsString
и::assertStringContainsStringIgnoringCase
. -
#3126965 Использование
count()
в сравнении заменено на нативный метод::assertCount()
. -
#3132964 Удалена передача параметра
$message
в::assertResponse()
, так как он его не поддерживает. -
#3128880
ConnectionUnitTest
теперь также запускается для PostgreSQL. -
#3139218 Использование
::assertResponse()
заменено на$this->assertSession()->statusCodeEquals()
.
¶Производительность
-
#3092180 Добавлен новый кеш контекст
protocol_version
, который позволяет иметь различные результаты для разных протоколов (HTTP/1.0, HTTP/1.1 или HTTP/2).
¶Прочие изменения
-
#3083486 Конфигурация
action.settings.recursion_limit
и её схема была удалена. Drupal ядро не использовало данную конфигурацию. -
#3111613 Удалены два
protected
метода уDrupal\Core\Entity\Sql\SqlContentEntityStorageSchema
. Они не использовались ядром, а так как являются защищёнными, не относятся к публичному API. -
#3113062 Функция
system_user_timezone()
помечена как@internal
и будет удалена в Drupal 9. -
#3054049 Добавлена новая проверка доступа маршрута
_entity_bundles
, при помощи которой можно создать маршрут принимающий только конкретные бандлы сущности из аргумента. Например:_entity_bundles: 'node:article|page'
. -
#3114909 Документация для
EntityTypeInterface::hasHandlerClass
и::getHandlerClass
приведены к одному виду. -
#2999549 Добавлен новый служебный роут
<button>
для генерации ссылки в виде кнопкиroute:<button>
. -
#3120954 Сообщение об устаревшей функции приведено в соответствии с требования для
Registry
класса. -
#3121229 Удалён эксперементальный модуль
config_environment
, который находился в альфа версии. - #3104015 Zend Framework стал Laminas, поэтому все зависимости и код был заменён на новые.
-
#3107243 Исправлены метки для
link.schema.yml
файла. Теперь они утверждения, вместо вопросов. - #3126003 Исправлена ошибка приводящая к увеличенному потреблению памяти в момент установки Drupal.
- #3126923 Исправлена неполадка, вызванная изменением #3120096, приводящая к ошибкам на PHP 7.0.
-
#3127960 Удалено некорректное нижнее подчёркивание в миграции Drupal 7
Shortcut
. -
#2455465 Удалена поддержка PHP 5 для
.htaccess
и добавлена поддержка PHP 7. -
#3084078
AdminNegotiator::determineActiveTheme()
теперь соответствует интерфейсу и явно возвращаетNULL
. - #3118726 js.cookie обновлён до 3.0.
-
#3107472
DbDumpCommand
теперь используетDrupal::VERSION
вместо захардкоженного значения. -
#3134318 Для PHPCS включено правило
Drupal.Classes.ClassFileName
. -
#3114122
ExceptionLoggingSubscriber
теперь также записывает в логи причину HTTP 403. -
#3123211 В
MenuForm
использование\Drupal::menuTree()
заменено на использование свойства$menuTree
. -
#3134676 В файле
CHANGELOG.txt
упоминание Drupal теперь производится без мажорной версии. - #3120731 Исправлена неполадка, из-за которой выводилось сообщение «Drupal уже установлен» при некорректных настройках подключения БД.
- #2055851 Сообщения об ошибках в исключениях теперь не переводимы.
- #2830326 Ссылка «Перевести сайт в режим обслуживания» на странице update.php теперь генерируется относительно адреса сайта.
-
#3135310 Удалён параметр
$install_state['database_ready']
так как нигде не используется и всегдаFALSE
. - #3044059 Справки модулей big_pipe, dynamic_page_cache и page_cache конвертированы в Help Topic.
- #3055055 Справки модулей breakpoint, color, layout_builder и layout_discovery перенесены в Help Topic.
- #3138772 Исправлены опечатки в слове «Disable».
- #3138783 Исправлены опечатки в слове «Partially».
- #3138778 Исправлены опечатки в слове «Nourriture».
- #3138789 Исправлены опечатки в слове «blockquote».
- #3138718 Британские слова заменены на их американские аналоги, так как Drupal использует American English в качестве стандарта для написания кода и комментариев.
-
#2937552 Включена проверка
Drupal.Commenting.DocComment.TagsNotGrouped
для ядра. -
#3123068 Включена проверка
Drupal.Semantics.FunctionT.ConcatString
для ядра и исправлены ошибки. -
#2901745 Включена проверка
PSR2.Namespaces.UseDeclaration.UseAfterNamespace
для ядра. -
#3143085 Добавлено свойство
$aliases
дляOptimizedPhpArrayDumper
. - #3138774 Исправлены опечатки в слове «DoesNot».
-
#3123065 Включена проверка
Drupal.NamingConventions.ValidClassName
для ядра и исправлены ошибки. -
#2824935 Исправлены ошибки по стандарту
Squiz.ControlStructures.SwitchDeclaration
.
¶Смотрите также
¶Ссылки
- Drupal 8.9.0 (англ.), drupal.org, 3 июня 2020