From eaa0c629f067ce9fefa8ec0c947539519484a3cc Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Wed, 16 Apr 2025 09:40:58 +0200 Subject: [PATCH 01/23] feat: apply patch #27 with some small updates --- .../comment/src/Plugin/views/row/Rss.php | 10 ++-- .../tests/src/Unit/ConfigNamesMapperTest.php | 5 -- .../modules/node/src/Plugin/views/row/Rss.php | 12 ++--- .../system/config/install/system.rss.yml | 2 - .../system/config/schema/system.schema.yml | 12 ----- core/modules/system/migrations/system_rss.yml | 16 ------- core/modules/system/src/Form/RssFeedsForm.php | 48 ------------------- .../system/system.config_translation.yml | 6 --- core/modules/system/system.links.menu.yml | 5 -- core/modules/system/system.links.task.yml | 5 -- core/modules/system/system.post_update.php | 7 +++ core/modules/system/system.routing.yml | 8 ---- .../Functional/Update/SystemRssDeleteTest.php | 37 ++++++++++++++ .../d6/MigrateSystemConfigurationTest.php | 6 --- .../d7/MigrateSystemConfigurationTest.php | 6 --- .../src/Plugin/views/row/RssPluginBase.php | 15 +++++- 16 files changed, 64 insertions(+), 136 deletions(-) delete mode 100644 core/modules/system/config/install/system.rss.yml delete mode 100644 core/modules/system/migrations/system_rss.yml delete mode 100644 core/modules/system/src/Form/RssFeedsForm.php create mode 100644 core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php diff --git a/core/modules/comment/src/Plugin/views/row/Rss.php b/core/modules/comment/src/Plugin/views/row/Rss.php index f15b031e8c38..78a8d098edc3 100644 --- a/core/modules/comment/src/Plugin/views/row/Rss.php +++ b/core/modules/comment/src/Plugin/views/row/Rss.php @@ -66,8 +66,7 @@ public function preRender($result) { */ public function buildOptionsForm_summary_options() { $options = parent::buildOptionsForm_summary_options(); - $options['title'] = $this->t('Title only'); - $options['default'] = $this->t('Use site default RSS settings'); + $options[$this::TITLE_VIEW_MODE] = $this->t('Title only'); return $options; } @@ -83,9 +82,6 @@ public function render($row) { } $view_mode = $this->options['view_mode']; - if ($view_mode == 'default') { - $view_mode = \Drupal::config('system.rss')->get('items.view_mode'); - } // Load the specified comment and its associated node: /** @var \Drupal\comment\CommentInterface $comment */ @@ -113,7 +109,7 @@ public function render($row) { // The comment gets built and modules add to or modify // $comment->rss_elements and $comment->rss_namespaces. - $build = $this->entityTypeManager->getViewBuilder('comment')->view($comment, 'rss'); + $build = $this->entityTypeManager->getViewBuilder('comment')->view($comment, $view_mode); unset($build['#theme']); if (!empty($comment->rss_namespaces)) { @@ -121,7 +117,7 @@ public function render($row) { } $item = new \stdClass(); - if ($view_mode != 'title') { + if ($view_mode != $this::TITLE_VIEW_MODE) { // We render comment contents. $item->description = $build; } diff --git a/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php b/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php index 5bbe2b9a3098..cc17c6304e60 100644 --- a/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php +++ b/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php @@ -470,11 +470,6 @@ public function testGetConfigData(): void { 'enabled' => FALSE, 'message' => '@site is currently under maintenance.', ], - 'system.rss' => [ - 'items' => [ - 'view_mode' => 'rss', - ], - ], ]; $this->configNamesMapper->setConfigNames(array_keys($configs)); diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php index 56549f01d124..6e33e522743d 100644 --- a/core/modules/node/src/Plugin/views/row/Rss.php +++ b/core/modules/node/src/Plugin/views/row/Rss.php @@ -51,8 +51,7 @@ class Rss extends RssPluginBase { */ public function buildOptionsForm_summary_options() { $options = parent::buildOptionsForm_summary_options(); - $options['title'] = $this->t('Title only'); - $options['default'] = $this->t('Use site default RSS settings'); + $options[$this::TITLE_VIEW_MODE] = $this->t('Title only'); return $options; } @@ -89,9 +88,6 @@ public function render($row) { } $display_mode = $this->options['view_mode']; - if ($display_mode == 'default') { - $display_mode = \Drupal::config('system.rss')->get('items.view_mode'); - } // Load the specified node: /** @var \Drupal\node\NodeInterface $node */ @@ -120,11 +116,9 @@ public function render($row) { // The node gets built and modules add to or modify $node->rss_elements // and $node->rss_namespaces. - $build_mode = $display_mode; - $build = \Drupal::entityTypeManager() ->getViewBuilder('node') - ->view($node, $build_mode); + ->view($node, $display_mode); // Add rss key to cache to differentiate this from other caches. $build['#cache']['keys'][] = 'view_rss'; @@ -135,7 +129,7 @@ public function render($row) { } $item = new \stdClass(); - if ($display_mode != 'title') { + if ($display_mode != $this::TITLE_VIEW_MODE) { // We render node contents. $item->description = $build; } diff --git a/core/modules/system/config/install/system.rss.yml b/core/modules/system/config/install/system.rss.yml deleted file mode 100644 index bb7c0c040a97..000000000000 --- a/core/modules/system/config/install/system.rss.yml +++ /dev/null @@ -1,2 +0,0 @@ -items: - view_mode: rss diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml index 88f34652b986..96cfabee126b 100644 --- a/core/modules/system/config/schema/system.schema.yml +++ b/core/modules/system/config/schema/system.schema.yml @@ -238,18 +238,6 @@ system.performance: type: boolean label: 'Compress JavaScript files.' -system.rss: - type: config_object - label: 'Feed settings' - mapping: - items: - type: mapping - label: 'Feed items' - mapping: - view_mode: - type: string - label: 'Feed content' - system.theme: type: config_object label: 'Theme settings' diff --git a/core/modules/system/migrations/system_rss.yml b/core/modules/system/migrations/system_rss.yml deleted file mode 100644 index 8a74ac6c84cf..000000000000 --- a/core/modules/system/migrations/system_rss.yml +++ /dev/null @@ -1,16 +0,0 @@ -id: system_rss -label: RSS configuration -migration_tags: - - Drupal 6 - - Drupal 7 - - Configuration -source: - plugin: variable - variables: - - feed_item_length - source_module: system -process: - 'items/view_mode': feed_item_length -destination: - plugin: config - config_name: system.rss diff --git a/core/modules/system/src/Form/RssFeedsForm.php b/core/modules/system/src/Form/RssFeedsForm.php deleted file mode 100644 index 72617220f2c0..000000000000 --- a/core/modules/system/src/Form/RssFeedsForm.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -namespace Drupal\system\Form; - -use Drupal\Core\Form\ConfigFormBase; -use Drupal\Core\Form\FormStateInterface; - -/** - * Configure RSS settings for this site. - * - * @internal - */ -class RssFeedsForm extends ConfigFormBase { - - /** - * {@inheritdoc} - */ - public function getFormId() { - return 'system_rss_feeds_settings'; - } - - /** - * {@inheritdoc} - */ - protected function getEditableConfigNames() { - return ['system.rss']; - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, FormStateInterface $form_state) { - $form['feed_view_mode'] = [ - '#type' => 'select', - '#title' => $this->t('Feed content'), - '#config_target' => 'system.rss:items.view_mode', - '#options' => [ - 'title' => $this->t('Titles only'), - 'teaser' => $this->t('Titles plus teaser'), - 'fulltext' => $this->t('Full text'), - ], - '#description' => $this->t('Global setting for the default display of content items in each feed.'), - ]; - - return parent::buildForm($form, $form_state); - } - -} diff --git a/core/modules/system/system.config_translation.yml b/core/modules/system/system.config_translation.yml index 87cc98ce8716..e56f2395c36f 100644 --- a/core/modules/system/system.config_translation.yml +++ b/core/modules/system/system.config_translation.yml @@ -9,9 +9,3 @@ system.site_information_settings: base_route_name: system.site_information_settings names: - system.site - -system.rss_feeds_settings: - title: 'RSS publishing' - base_route_name: system.rss_feeds_settings - names: - - system.rss diff --git a/core/modules/system/system.links.menu.yml b/core/modules/system/system.links.menu.yml index 404bceeb7b36..ea9f1528530e 100644 --- a/core/modules/system/system.links.menu.yml +++ b/core/modules/system/system.links.menu.yml @@ -53,11 +53,6 @@ system.admin_config_services: title: 'Web services' parent: system.admin_config route_name: system.admin_config_services -system.rss_feeds_settings: - title: 'RSS publishing' - parent: system.admin_config_services - description: 'Configure the site description, the number of items per feed, and whether feeds should be titles/teasers/full-text.' - route_name: system.rss_feeds_settings system.admin_config_development: route_name: system.admin_config_development parent: system.admin_config diff --git a/core/modules/system/system.links.task.yml b/core/modules/system/system.links.task.yml index ed66b0595e20..369cc253ad84 100644 --- a/core/modules/system/system.links.task.yml +++ b/core/modules/system/system.links.task.yml @@ -1,8 +1,3 @@ -system.rss_feeds_settings_tab: - route_name: system.rss_feeds_settings - title: Settings - base_route: system.rss_feeds_settings - system.site_maintenance_mode_tab: route_name: system.site_maintenance_mode title: Settings diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php index ce110e2c2f36..78876aaa74ef 100644 --- a/core/modules/system/system.post_update.php +++ b/core/modules/system/system.post_update.php @@ -123,3 +123,10 @@ function system_post_update_convert_empty_description_entity_form_modes_to_null( }); } + +/** + * Delete obsolete system.rss configuration. + */ +function system_post_update_delete_rss_config(): void { + \Drupal::configFactory()->getEditable('system.rss')->delete(); +} diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index bf1ff4ca1f60..d3b67dd75177 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -191,14 +191,6 @@ system.file_system_settings: requirements: _permission: 'administer site configuration' -system.rss_feeds_settings: - path: '/admin/config/services/rss-publishing' - defaults: - _form: '\Drupal\system\Form\RssFeedsForm' - _title: 'RSS publishing' - requirements: - _permission: 'administer site configuration' - system.regional_settings: path: '/admin/config/regional/settings' defaults: diff --git a/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php new file mode 100644 index 000000000000..76d804c1af56 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php @@ -0,0 +1,37 @@ +<?php + +namespace Drupal\Tests\system\Functional\Update; + +use Drupal\FunctionalTests\Update\UpdatePathTestBase; + +/** + * Tests that system.rss config is deleted. + * + * @group Update + * @see system_post_update_delete_rss_config() + */ +class SystemRssDeleteTest extends UpdatePathTestBase { + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles() { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../fixtures/update/drupal-10.3.0.bare.standard.php.gz', + ]; + } + + /** + * Ensures that system.rss is deleted after updating. + */ + public function testUpdate() { + $config = $this->config('system.rss'); + $this->assertFalse($config->isNew()); + + $this->runUpdates(); + + $config = $this->config('system.rss'); + $this->assertTrue($config->isNew()); + } + +} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php index eba36bada4bb..28572e4e26fd 100644 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php +++ b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php @@ -95,11 +95,6 @@ class MigrateSystemConfigurationTest extends MigrateDrupal6TestBase { 'gzip' => TRUE, ], ], - 'system.rss' => [ - 'items' => [ - 'view_mode' => 'title', - ], - ], 'system.site' => [ // Neither langcode nor default_langcode are not handled by the migration. 'langcode' => 'en', @@ -141,7 +136,6 @@ protected function setUp(): void { 'system_logging', 'system_maintenance', 'd6_system_performance', - 'system_rss', 'system_site', ]; $this->executeMigrations($migrations); diff --git a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php index b8b18a5c9ba2..b677e58d5482 100644 --- a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php +++ b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php @@ -107,11 +107,6 @@ class MigrateSystemConfigurationTest extends MigrateDrupal7TestBase { 'gzip' => TRUE, ], ], - 'system.rss' => [ - 'items' => [ - 'view_mode' => 'fulltext', - ], - ], 'system.site' => [ // Neither langcode nor default_langcode are not handled by the migration. 'langcode' => 'en', @@ -176,7 +171,6 @@ protected function setUp(): void { 'd7_system_mail', 'system_maintenance', 'd7_system_performance', - 'system_rss', 'system_site', ]; $this->executeMigrations($migrations); diff --git a/core/modules/views/src/Plugin/views/row/RssPluginBase.php b/core/modules/views/src/Plugin/views/row/RssPluginBase.php index 3de7d7af3a7b..418736427b85 100644 --- a/core/modules/views/src/Plugin/views/row/RssPluginBase.php +++ b/core/modules/views/src/Plugin/views/row/RssPluginBase.php @@ -12,6 +12,11 @@ */ abstract class RssPluginBase extends RowPluginBase { + /** + * A fake view mode to only display titles. + */ + const string TITLE_VIEW_MODE = '_views.rss.title'; + /** * The entity type manager. * @@ -73,7 +78,15 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['view_mode'] = ['default' => 'default']; + // Select the rss view mode by default, otherwise select the first available + // view mode. + $view_modes = $this->entityDisplayRepository->getViewModes($this->entityTypeId); + if (isset($view_modes['rss'])) { + $options['view_mode'] = ['default' => 'rss']; + } + else { + $options['view_mode'] = ['default' => key($view_modes)]; + } return $options; } -- GitLab From b7e164f53e7c30dde01895cbd0b463caac1f72f1 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Wed, 16 Apr 2025 09:46:18 +0200 Subject: [PATCH 02/23] build: fix missing return types --- .../tests/src/Functional/Update/SystemRssDeleteTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php index 76d804c1af56..e57357543742 100644 --- a/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php +++ b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\system\Functional\Update; use Drupal\FunctionalTests\Update\UpdatePathTestBase; @@ -15,7 +17,7 @@ class SystemRssDeleteTest extends UpdatePathTestBase { /** * {@inheritdoc} */ - protected function setDatabaseDumpFiles() { + protected function setDatabaseDumpFiles(): void { $this->databaseDumpFiles = [ __DIR__ . '/../../../fixtures/update/drupal-10.3.0.bare.standard.php.gz', ]; @@ -24,7 +26,7 @@ protected function setDatabaseDumpFiles() { /** * Ensures that system.rss is deleted after updating. */ - public function testUpdate() { + public function testUpdate(): void { $config = $this->config('system.rss'); $this->assertFalse($config->isNew()); -- GitLab From 3a8210e3239ab44db9a39cdd48969d624818c4a2 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Wed, 16 Apr 2025 23:59:56 +0200 Subject: [PATCH 03/23] feat: add test for upgrading views --- core/modules/system/system.post_update.php | 19 +- core/modules/views/src/ViewsConfigUpdater.php | 23 +++ .../fixtures/update/rss-default-view-mode.php | 21 ++ .../update/views.view.test_display_feed.yml | 193 ++++++++++++++++++ .../RssDefaultRowViewModeUpdateTest.php | 62 ++++++ .../src/Kernel/ViewsConfigUpdaterTest.php | 29 +++ 6 files changed, 345 insertions(+), 2 deletions(-) create mode 100644 core/modules/views/tests/fixtures/update/rss-default-view-mode.php create mode 100644 core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml create mode 100644 core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php index 78876aaa74ef..cd940e2b711d 100644 --- a/core/modules/system/system.post_update.php +++ b/core/modules/system/system.post_update.php @@ -7,6 +7,8 @@ use Drupal\Core\Config\Entity\ConfigEntityUpdater; use Drupal\Core\Entity\EntityFormModeInterface; +use Drupal\views\ViewEntityInterface; +use Drupal\views\ViewsConfigUpdater; /** * Implements hook_removed_post_updates(). @@ -127,6 +129,19 @@ function system_post_update_convert_empty_description_entity_form_modes_to_null( /** * Delete obsolete system.rss configuration. */ -function system_post_update_delete_rss_config(): void { - \Drupal::configFactory()->getEditable('system.rss')->delete(); +function system_post_update_delete_rss_config(array &$sandbox): void { + $config = \Drupal::configFactory()->getEditable('system.rss'); + $previous_view_mode = $config->get('items.view_mode'); + if ($config->get('items.view_mode') !== NULL) { + $sandbox['#system_post_update_delete_rss_config_previous_view_mode'] = $previous_view_mode; + } + + /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ + $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); + $view_config_updater->setDeprecationsEnabled(FALSE); + \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool { + return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config_previous_view_mode']); + }); + + $config->delete(); } diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index 9c5d38e10ac5..b11e6caa5a6e 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -359,4 +359,27 @@ public function processTableCssClassUpdate(ViewEntityInterface $view): bool { return $changed; } + public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode): bool { + return $this->processRssViewModeUpdate($view, $previous_view_mode); + } + + public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode) : bool { + $changed = FALSE; + $displays = $view->get('display'); + + foreach ($displays as &$display) { + if (isset($display['display_options']['row']['options']['view_mode']) && + $display['display_options']['row']['options']['view_mode'] === 'default') { + $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; + $changed = TRUE; + } + } + + if ($changed) { + $view->set('display', $displays); + } + + return $changed; + } + } diff --git a/core/modules/views/tests/fixtures/update/rss-default-view-mode.php b/core/modules/views/tests/fixtures/update/rss-default-view-mode.php new file mode 100644 index 000000000000..6d7c83ff8941 --- /dev/null +++ b/core/modules/views/tests/fixtures/update/rss-default-view-mode.php @@ -0,0 +1,21 @@ +<?php + +/** + * @file + * Test fixture. + */ + +use Drupal\Core\Database\Database; +use Drupal\Component\Serialization\Yaml; + +$connection = Database::getConnection(); + +$config = Yaml::decode(file_get_contents(__DIR__ . '/views.view.test_display_feed.yml')); + +$connection->insert('config') + ->fields([ + 'collection' => '', + 'name' => 'views.view.test_display_feed', + 'data' => serialize($config), + ]) + ->execute(); diff --git a/core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml b/core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml new file mode 100644 index 000000000000..0dd06c7ecf76 --- /dev/null +++ b/core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml @@ -0,0 +1,193 @@ +uuid: 06456283-a609-4646-aeb4-f2b918b13111 +langcode: en +status: true +dependencies: + config: + - core.entity_view_mode.node.rss + module: + - node + - user +id: test_display_feed +label: 'rss test view' +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +display: + default: + id: default + display_title: Default + display_plugin: default + position: 0 + display_options: + fields: + title: + id: title + table: node_field_data + field: title + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: title + plugin_id: field + label: '' + exclude: false + alter: + alter_text: false + make_link: false + absolute: false + word_boundary: false + ellipsis: false + strip_tags: false + trim: false + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + pager: + type: mini + options: + offset: 0 + pagination_heading_level: h4 + items_per_page: 10 + total_pages: null + id: 0 + tags: + next: ›› + previous: ‹‹ + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: perm + options: + perm: 'access content' + cache: + type: tag + options: { } + empty: { } + sorts: + created: + id: created + table: node_field_data + field: created + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: created + plugin_id: date + order: DESC + expose: + label: '' + field_identifier: '' + exposed: false + granularity: second + arguments: { } + filters: + status: + id: status + table: node_field_data + field: status + entity_type: node + entity_field: status + plugin_id: boolean + value: '1' + group: 1 + expose: + operator: '' + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + default_field_elements: true + inline: { } + separator: '' + hide_empty: false + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + replica: false + query_tags: { } + relationships: { } + header: { } + footer: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: { } + feed_1: + id: feed_1 + display_title: Feed + display_plugin: feed + position: 1 + display_options: + row: + type: node_rss + options: + view_mode: default + display_extenders: { } + path: my-feed.xml + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php new file mode 100644 index 000000000000..9de7132cdf7c --- /dev/null +++ b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php @@ -0,0 +1,62 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\views\Functional\Update; + +use Drupal\FunctionalTests\Update\UpdatePathTestBase; +use Drupal\views\Entity\View; + +/** + * Tests the update view mode when removing system.rss. + * + * @see system_post_update_delete_rss_config() + * + * @group Update + * @group legacy + */ +class RssDefaultRowViewModeUpdateTest extends UpdatePathTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['node', 'user']; + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles(): void { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-10.3.0.filled.standard.php.gz', + __DIR__ . '/../../../fixtures/update/rss-default-view-mode.php', + ]; + } + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->installModulesFromClassProperty($this->container); + } + + /** + * Tests the upgrade path setting rss row view mode. + */ + public function testRssDefaultRowViewModeUpdate(): void { + $views = View::loadMultiple(); + $data = $views['test_display_feed']->toArray(); + + $this->assertEquals('default', $data['display']['feed_1']['display_options']['row']['options']['view_mode']); + + $this->runUpdates(); + + $views = View::loadMultiple(); + $data = $views['test_display_feed']->toArray(); + + $this->assertEquals('title', $data['display']['feed_1']['display_options']['row']['options']['view_mode']); + + } + +} diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index b99adcd105d8..9d6b83da89e3 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -5,6 +5,7 @@ namespace Drupal\Tests\views\Kernel; use Drupal\Core\Config\FileStorage; +use Drupal\views\ViewsConfigUpdater; /** * @coversDefaultClass \Drupal\views\ViewsConfigUpdater @@ -32,6 +33,34 @@ public function testViewsConfigUpdater(): void { $this->markTestSkipped(); } + /** + * Tests the `updateRssViewMode` method to ensure it correctly updates the + * view mode for RSS feed displays. + */ + public function testUpdateRssViewMode(): void { + $this->strictConfigSchema = FALSE; + + /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ + $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); + + // Load the test view. + $view_id = 'views.view.test_display_feed_view_mode'; + $test_view = $this->loadTestView($view_id); + $display = $test_view->getDisplay('feed_1'); + + // Check the initial view mode. + $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + $this->assertEquals('default', $rowViewMode); + + // Update the view mode using the method under test. + $view_config_updater->needsRssViewModeUpdate($test_view, 'old_view_mode'); + + // Assert if the view mode was updated correctly. + $display = $test_view->getDisplay('feed_1'); + $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + $this->assertEquals('old_view_mode', $updatedRowViewMode); + } + /** * Loads a test view. * -- GitLab From 1905479ffba1de6fcca1422ee885fc7f986ca14b Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Thu, 17 Apr 2025 00:10:06 +0200 Subject: [PATCH 04/23] fix: small fix --- core/modules/system/system.post_update.php | 4 ++-- .../modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php index cd940e2b711d..3d762ba862d8 100644 --- a/core/modules/system/system.post_update.php +++ b/core/modules/system/system.post_update.php @@ -133,14 +133,14 @@ function system_post_update_delete_rss_config(array &$sandbox): void { $config = \Drupal::configFactory()->getEditable('system.rss'); $previous_view_mode = $config->get('items.view_mode'); if ($config->get('items.view_mode') !== NULL) { - $sandbox['#system_post_update_delete_rss_config_previous_view_mode'] = $previous_view_mode; + $sandbox['#system_post_update_delete_rss_config__previous_view_mode'] = $previous_view_mode; } /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); $view_config_updater->setDeprecationsEnabled(FALSE); \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool { - return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config_previous_view_mode']); + return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']); }); $config->delete(); diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index 9d6b83da89e3..fd9095865c11 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -34,8 +34,7 @@ public function testViewsConfigUpdater(): void { } /** - * Tests the `updateRssViewMode` method to ensure it correctly updates the - * view mode for RSS feed displays. + * Tests the `needsRssViewModeUpdate` method. */ public function testUpdateRssViewMode(): void { $this->strictConfigSchema = FALSE; -- GitLab From a1ef022c44306020ab573b634ec08c8699ad64e4 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Thu, 17 Apr 2025 00:13:14 +0200 Subject: [PATCH 05/23] fix: don't need modules --- .../Update/RssDefaultRowViewModeUpdateTest.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php index 9de7132cdf7c..e524362dd9ff 100644 --- a/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php +++ b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php @@ -17,11 +17,6 @@ */ class RssDefaultRowViewModeUpdateTest extends UpdatePathTestBase { - /** - * {@inheritdoc} - */ - protected static $modules = ['node', 'user']; - /** * {@inheritdoc} */ @@ -32,15 +27,6 @@ protected function setDatabaseDumpFiles(): void { ]; } - /** - * {@inheritdoc} - */ - protected function setUp(): void { - parent::setUp(); - - $this->installModulesFromClassProperty($this->container); - } - /** * Tests the upgrade path setting rss row view mode. */ -- GitLab From cfc345d9cf9f3d4373ff14f40d8c6090e4b8f8cb Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Thu, 17 Apr 2025 11:54:25 +0200 Subject: [PATCH 06/23] fix: make the test work again after since the fixture was renamed --- core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index fd9095865c11..68384106b454 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -43,7 +43,7 @@ public function testUpdateRssViewMode(): void { $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); // Load the test view. - $view_id = 'views.view.test_display_feed_view_mode'; + $view_id = 'views.view.test_display_feed'; $test_view = $this->loadTestView($view_id); $display = $test_view->getDisplay('feed_1'); -- GitLab From c38664966b18003e291c321e9a588bfef0f29aff Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Thu, 17 Apr 2025 16:14:13 +0200 Subject: [PATCH 07/23] feat: wrap system update view update with a moduleExist call. --- core/modules/system/system.post_update.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php index 3d762ba862d8..c83de1019444 100644 --- a/core/modules/system/system.post_update.php +++ b/core/modules/system/system.post_update.php @@ -136,12 +136,15 @@ function system_post_update_delete_rss_config(array &$sandbox): void { $sandbox['#system_post_update_delete_rss_config__previous_view_mode'] = $previous_view_mode; } - /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ - $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); - $view_config_updater->setDeprecationsEnabled(FALSE); - \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool { - return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']); - }); + if (\Drupal::moduleHandler()->moduleExists('views')) { + /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ + $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); + $view_config_updater->setDeprecationsEnabled(FALSE); + \Drupal::classResolver(ConfigEntityUpdater::class) + ->update($sandbox, 'view', function(ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool { + return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']); + }); + } $config->delete(); } -- GitLab From 8eec5acc24c5be24a17f7852dba2e977f27e2375 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Fri, 18 Apr 2025 12:16:14 +0200 Subject: [PATCH 08/23] fix: ViewsConfigUpdater should only update views of which the row: type: are node_rss or comment_rss --- core/modules/views/src/ViewsConfigUpdater.php | 7 + .../views.view.test_display_feed_noupdate.yml | 193 ++++++++++++++++++ .../src/Kernel/ViewsConfigUpdaterTest.php | 27 +++ 3 files changed, 227 insertions(+) create mode 100644 core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index b11e6caa5a6e..7ce518a74ac8 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -367,8 +367,15 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre $changed = FALSE; $displays = $view->get('display'); + // Row types that need updating. + $row_types = [ + 'comment_rss', + 'node_rss', + ]; + foreach ($displays as &$display) { if (isset($display['display_options']['row']['options']['view_mode']) && + in_array($display['display_options']['row']['type'], $row_types, TRUE) && $display['display_options']['row']['options']['view_mode'] === 'default') { $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; $changed = TRUE; diff --git a/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml new file mode 100644 index 000000000000..b173d4ca57ca --- /dev/null +++ b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml @@ -0,0 +1,193 @@ +uuid: 06456283-a609-4646-aeb4-f2b918b13111 +langcode: en +status: true +dependencies: + config: + - core.entity_view_mode.node.rss + module: + - node + - user +id: test_display_feed_noupdate +label: 'rss test view' +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +display: + default: + id: default + display_title: Default + display_plugin: default + position: 0 + display_options: + fields: + title: + id: title + table: node_field_data + field: title + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: title + plugin_id: field + label: '' + exclude: false + alter: + alter_text: false + make_link: false + absolute: false + word_boundary: false + ellipsis: false + strip_tags: false + trim: false + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + pager: + type: mini + options: + offset: 0 + pagination_heading_level: h4 + items_per_page: 10 + total_pages: null + id: 0 + tags: + next: ›› + previous: ‹‹ + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: perm + options: + perm: 'access content' + cache: + type: tag + options: { } + empty: { } + sorts: + created: + id: created + table: node_field_data + field: created + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: created + plugin_id: date + order: DESC + expose: + label: '' + field_identifier: '' + exposed: false + granularity: second + arguments: { } + filters: + status: + id: status + table: node_field_data + field: status + entity_type: node + entity_field: status + plugin_id: boolean + value: '1' + group: 1 + expose: + operator: '' + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + default_field_elements: true + inline: { } + separator: '' + hide_empty: false + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + replica: false + query_tags: { } + relationships: { } + header: { } + footer: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: { } + feed_1: + id: feed_1 + display_title: Feed + display_plugin: feed + position: 1 + display_options: + row: + type: entity:node + options: + view_mode: default + display_extenders: { } + path: my-feed.xml + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index 68384106b454..3173680a5a02 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -60,6 +60,33 @@ public function testUpdateRssViewMode(): void { $this->assertEquals('old_view_mode', $updatedRowViewMode); } + /** + * Tests the `needsRssViewModeUpdate` method. + */ + public function testUpdateRssViewModeSkipsOtherType(): void { + $this->strictConfigSchema = FALSE; + + /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ + $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); + + // Load the test view. + $view_id = 'views.view.test_display_feed_noupdate'; + $test_view = $this->loadTestView($view_id); + $display = $test_view->getDisplay('feed_1'); + + // Check the initial view mode. + $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + $this->assertEquals('default', $rowViewMode); + + // Update the view mode using the method under test. + $view_config_updater->needsRssViewModeUpdate($test_view, 'old_view_mode'); + + // Assert if the view mode was updated correctly. + $display = $test_view->getDisplay('feed_1'); + $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + $this->assertEquals('default', $updatedRowViewMode); + } + /** * Loads a test view. * -- GitLab From e8b6853bf6b5d843d8fae74e96e2b691b1869b3f Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Fri, 18 Apr 2025 12:40:54 +0200 Subject: [PATCH 09/23] fix: Get the first available viewmode for the comment or node if the system.rss setting is missing. --- core/modules/views/src/ViewsConfigUpdater.php | 22 ++++++++---- .../src/Kernel/ViewsConfigUpdaterTest.php | 34 +++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index 7ce518a74ac8..7f64368027ac 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -5,6 +5,7 @@ use Drupal\Component\Plugin\PluginManagerInterface; use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -85,6 +86,7 @@ public function __construct( TypedConfigManagerInterface $typed_config_manager, ViewsData $views_data, PluginManagerInterface $formatter_plugin_manager, + protected EntityDisplayRepositoryInterface $entityDisplayRepository, ) { $this->entityTypeManager = $entity_type_manager; $this->entityFieldManager = $entity_field_manager; @@ -102,7 +104,8 @@ public static function create(ContainerInterface $container) { $container->get('entity_field.manager'), $container->get('config.typed'), $container->get('views.views_data'), - $container->get('plugin.manager.field.formatter') + $container->get('plugin.manager.field.formatter'), + $container->get('entity_display.repository') ); } @@ -359,25 +362,30 @@ public function processTableCssClassUpdate(ViewEntityInterface $view): bool { return $changed; } - public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode): bool { + public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL): bool { return $this->processRssViewModeUpdate($view, $previous_view_mode); } - public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode) : bool { + public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL) : bool { $changed = FALSE; $displays = $view->get('display'); // Row types that need updating. $row_types = [ - 'comment_rss', - 'node_rss', + 'comment_rss' => 'comment', + 'node_rss' => 'node', ]; foreach ($displays as &$display) { if (isset($display['display_options']['row']['options']['view_mode']) && - in_array($display['display_options']['row']['type'], $row_types, TRUE) && + array_key_exists($display['display_options']['row']['type'], $row_types) && $display['display_options']['row']['options']['view_mode'] === 'default') { - $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; + if ($previous_view_mode === NULL) { + $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]); + $display['display_options']['row']['options']['view_mode'] = array_key_first($view_modes); + } else { + $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; + } $changed = TRUE; } } diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index 3173680a5a02..39d3f9744112 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -21,7 +21,9 @@ class ViewsConfigUpdaterTest extends ViewsKernelTestBase { protected static $modules = [ 'views_config_entity_test', 'entity_test', + 'text', 'field', + 'node', ]; /** @@ -60,6 +62,38 @@ public function testUpdateRssViewMode(): void { $this->assertEquals('old_view_mode', $updatedRowViewMode); } + /** + * Tests the `needsRssViewModeUpdate` method. + */ + public function testUpdateRssViewModeWithoutKnownPreviousMode(): void { + $this->installEntitySchema('node'); + $this->installConfig(['text', 'field', 'node']); + + $this->strictConfigSchema = FALSE; + + /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ + $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); + + // Load the test view. + $view_id = 'views.view.test_display_feed'; + $test_view = $this->loadTestView($view_id); + $display = $test_view->getDisplay('feed_1'); + + // Check the initial view mode. + $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + $this->assertEquals('default', $rowViewMode); + + // Update the view mode using the method under test. + $view_config_updater->needsRssViewModeUpdate($test_view); + + // Assert if the view mode was updated correctly. + $display = $test_view->getDisplay('feed_1'); + $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + + // This should be the first node view mode since we have nothing else + $this->assertEquals('teaser', $updatedRowViewMode); + } + /** * Tests the `needsRssViewModeUpdate` method. */ -- GitLab From b4de63390d24720f782e98c3336edc6599d1d75b Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Fri, 18 Apr 2025 12:44:25 +0200 Subject: [PATCH 10/23] build: fix phpcs and spelling error --- core/modules/system/system.post_update.php | 2 +- core/modules/views/src/ViewsConfigUpdater.php | 2 ++ ..._noupdate.yml => views.view.test_display_feed_no_update.yml} | 2 +- core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) rename core/modules/views/tests/fixtures/update/{views.view.test_display_feed_noupdate.yml => views.view.test_display_feed_no_update.yml} (99%) diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php index c83de1019444..2ad4b290ba92 100644 --- a/core/modules/system/system.post_update.php +++ b/core/modules/system/system.post_update.php @@ -141,7 +141,7 @@ function system_post_update_delete_rss_config(array &$sandbox): void { $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); $view_config_updater->setDeprecationsEnabled(FALSE); \Drupal::classResolver(ConfigEntityUpdater::class) - ->update($sandbox, 'view', function(ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool { + ->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool { return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']); }); } diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index 7f64368027ac..2355c1ce6d0e 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -79,6 +79,8 @@ class ViewsConfigUpdater implements ContainerInjectionInterface { * The views data service. * @param \Drupal\Component\Plugin\PluginManagerInterface $formatter_plugin_manager * The formatter plugin manager service. + * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entityDisplayRepository + * The entity display repository service. */ public function __construct( EntityTypeManagerInterface $entity_type_manager, diff --git a/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_no_update.yml similarity index 99% rename from core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml rename to core/modules/views/tests/fixtures/update/views.view.test_display_feed_no_update.yml index b173d4ca57ca..187ae2a2ddb0 100644 --- a/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml +++ b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_no_update.yml @@ -7,7 +7,7 @@ dependencies: module: - node - user -id: test_display_feed_noupdate +id: test_display_feed_no_update label: 'rss test view' module: views description: '' diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index 39d3f9744112..9f215ac3367e 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -104,7 +104,7 @@ public function testUpdateRssViewModeSkipsOtherType(): void { $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); // Load the test view. - $view_id = 'views.view.test_display_feed_noupdate'; + $view_id = 'views.view.test_display_feed_no_update'; $test_view = $this->loadTestView($view_id); $display = $test_view->getDisplay('feed_1'); -- GitLab From 3e13ca1fd50265f7530e0d40495b686d1529a224 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Fri, 18 Apr 2025 12:56:03 +0200 Subject: [PATCH 11/23] build: fix phpcs error --- core/modules/views/src/ViewsConfigUpdater.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index 2355c1ce6d0e..c197c6ef73ba 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -385,7 +385,8 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre if ($previous_view_mode === NULL) { $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]); $display['display_options']['row']['options']['view_mode'] = array_key_first($view_modes); - } else { + } + else { $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; } $changed = TRUE; -- GitLab From 6e60a9f9b649cea59337889d83682bae97b75d92 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Fri, 18 Apr 2025 13:17:04 +0200 Subject: [PATCH 12/23] feat: also update views on save --- core/modules/views/src/ViewsConfigUpdater.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index c197c6ef73ba..e6cd65b3fcc6 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -142,6 +142,9 @@ public function updateAll(ViewEntityInterface $view) { if ($this->processTableCssClassUpdate($view)) { $changed = TRUE; } + if ($this->processRssViewModeUpdate($view)) { + $changed = TRUE; + } return $changed; }); } @@ -384,12 +387,16 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre $display['display_options']['row']['options']['view_mode'] === 'default') { if ($previous_view_mode === NULL) { $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]); - $display['display_options']['row']['options']['view_mode'] = array_key_first($view_modes); + $probable_view_mode = array_key_first($view_modes); + $display['display_options']['row']['options']['view_mode'] = $probable_view_mode; + if ($probable_view_mode !== 'default') { + $changed = TRUE; + } } else { $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; + $changed = TRUE; } - $changed = TRUE; } } -- GitLab From 105fe07d0b5840d65a2353b4bfec195085f81774 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Fri, 18 Apr 2025 13:19:31 +0200 Subject: [PATCH 13/23] feat: if there is a "default" view mode, just use that, since we don't want to loop around indefinitely --- core/modules/views/src/ViewsConfigUpdater.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index e6cd65b3fcc6..b0f25007a237 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -387,11 +387,12 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre $display['display_options']['row']['options']['view_mode'] === 'default') { if ($previous_view_mode === NULL) { $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]); + if (array_key_exists('default', $view_modes)) { + return FALSE; + } + $probable_view_mode = array_key_first($view_modes); $display['display_options']['row']['options']['view_mode'] = $probable_view_mode; - if ($probable_view_mode !== 'default') { - $changed = TRUE; - } } else { $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; -- GitLab From 9efddd6362bf30bdc4ec4151bb21ccd2b46cc887 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 07:53:52 +0200 Subject: [PATCH 14/23] fix: views.view.taxonomy_term default view_mode changed to rss --- .../taxonomy/config/optional/views.view.taxonomy_term.yml | 2 +- .../demo_umami/config/install/views.view.taxonomy_term.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml index 9763c3c057dc..01834a39ac2f 100644 --- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml +++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml @@ -277,7 +277,7 @@ display: type: node_rss options: relationship: none - view_mode: default + view_mode: rss query: type: views_query options: { } diff --git a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml index 4834b785f4f6..fbd65897f3a3 100644 --- a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml +++ b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml @@ -283,7 +283,7 @@ display: type: node_rss options: relationship: none - view_mode: default + view_mode: rss query: type: views_query options: { } -- GitLab From f2b4e17204fb3017b01b1d25fd78dca8abfb83ea Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 08:06:54 +0200 Subject: [PATCH 15/23] fix: add missing config dependencies for views.view.taxonomy_term.yml --- .../taxonomy/config/optional/views.view.taxonomy_term.yml | 1 + .../demo_umami/config/install/views.view.taxonomy_term.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml index 01834a39ac2f..eb6ad6ab3624 100644 --- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml +++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml @@ -3,6 +3,7 @@ status: true dependencies: config: - core.entity_view_mode.node.teaser + - core.entity_view_mode.node.rss module: - node - taxonomy diff --git a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml index fbd65897f3a3..1fd1315ab331 100644 --- a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml +++ b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml @@ -3,6 +3,7 @@ status: true dependencies: config: - core.entity_view_mode.node.card + - core.entity_view_mode.node.rss module: - node - taxonomy -- GitLab From 9026cd8227e7e35e6171a2e42647868168ab55a0 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 08:17:55 +0200 Subject: [PATCH 16/23] fix: prefer RSS if available and add explaination to the view_mode selection code --- core/modules/views/src/ViewsConfigUpdater.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index b0f25007a237..b4dc71eb9af6 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -385,14 +385,28 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre if (isset($display['display_options']['row']['options']['view_mode']) && array_key_exists($display['display_options']['row']['type'], $row_types) && $display['display_options']['row']['options']['view_mode'] === 'default') { + + // When system.rss is already removed but a view is saved, we still need + // to try and set the view_mode to something more sane. But detecting + // if the view mode was always default, or default because it used the + // system.rss setting is hard. So if there is a default mode available + // it will use that. + // It would make sense to use any RSS view_mode if available, but that + // would mean 'default' can never be set as a view mode. That is an + // issue, therefor, if we have a default view mode available, we will + // use that. if ($previous_view_mode === NULL) { $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]); if (array_key_exists('default', $view_modes)) { return FALSE; } - $probable_view_mode = array_key_first($view_modes); + // If there is no default, the most likely view mode is RSS. If that + // is available we use that. Otherwise fall back to the first + // available. + $probable_view_mode = isset($view_modes['rss']) ? 'rss' : array_key_first($view_modes); $display['display_options']['row']['options']['view_mode'] = $probable_view_mode; + $changed = TRUE; } else { $display['display_options']['row']['options']['view_mode'] = $previous_view_mode; -- GitLab From 61fcf6d2d5e3f266bff1b7b8484925b5d3ac3d9f Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 08:19:07 +0200 Subject: [PATCH 17/23] fix: prefer RSS if available and add explaination to the view_mode selection code --- core/modules/views/src/ViewsConfigUpdater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index b4dc71eb9af6..86304904be0c 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -402,7 +402,7 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre } // If there is no default, the most likely view mode is RSS. If that - // is available we use that. Otherwise fall back to the first + // is available we use that. Otherwise, fall back to the first // available. $probable_view_mode = isset($view_modes['rss']) ? 'rss' : array_key_first($view_modes); $display['display_options']['row']['options']['view_mode'] = $probable_view_mode; -- GitLab From 31fec23b0802289ee1f27cb1d672c4f4869eb2d0 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 08:23:02 +0200 Subject: [PATCH 18/23] fix: prefer RSS if available and add explaination to the view_mode selection code --- core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index 9f215ac3367e..cd324c9f8219 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -91,7 +91,7 @@ public function testUpdateRssViewModeWithoutKnownPreviousMode(): void { $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; // This should be the first node view mode since we have nothing else - $this->assertEquals('teaser', $updatedRowViewMode); + $this->assertEquals('rss', $updatedRowViewMode); } /** -- GitLab From a14c04ae35345521f33e909f93d0d585c8bd4425 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 10:41:18 +0200 Subject: [PATCH 19/23] feat: add test for when a view is saved that is also updates --- .../src/Kernel/ViewsConfigUpdaterTest.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index cd324c9f8219..67b6c861ed1b 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -94,6 +94,37 @@ public function testUpdateRssViewModeWithoutKnownPreviousMode(): void { $this->assertEquals('rss', $updatedRowViewMode); } + /** + * Tests if onSave also updates the view. + */ + public function testUpdateRssViewModeWithoutKnownPreviousModeOnSaveHandler(): void { + $this->installEntitySchema('node'); + $this->installConfig(['text', 'field', 'node']); + + $this->strictConfigSchema = FALSE; + + /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ + $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); + + // Load the test view. + $view_id = 'views.view.test_display_feed'; + $test_view = $this->loadTestView($view_id); + $display = $test_view->getDisplay('feed_1'); + + // Check the initial view mode. + $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + $this->assertEquals('default', $rowViewMode); + + $test_view->save(); + + // Assert if the view mode was updated correctly onSave. + $display = $test_view->getDisplay('feed_1'); + $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE; + + // This should be the first node view mode since we have nothing else + $this->assertEquals('rss', $updatedRowViewMode); + } + /** * Tests the `needsRssViewModeUpdate` method. */ -- GitLab From 60dba651855e58b33dc79ce630d7fbc522020c27 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 10:44:28 +0200 Subject: [PATCH 20/23] build: remove unused variable in ViewsConfigUpdaterTest.php --- core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php index 67b6c861ed1b..ceeb56a4787b 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php @@ -103,9 +103,6 @@ public function testUpdateRssViewModeWithoutKnownPreviousModeOnSaveHandler(): vo $this->strictConfigSchema = FALSE; - /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */ - $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class); - // Load the test view. $view_id = 'views.view.test_display_feed'; $test_view = $this->loadTestView($view_id); -- GitLab From b5c18c4882583b267ea8e0bd83f89f79f8cf2c1b Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Sat, 19 Apr 2025 13:27:39 +0200 Subject: [PATCH 21/23] fix: appearantly the config order matters when checking for config diff, which makes sense --- .../taxonomy/config/optional/views.view.taxonomy_term.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml index eb6ad6ab3624..b34348136ad4 100644 --- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml +++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml @@ -2,8 +2,8 @@ langcode: en status: true dependencies: config: - - core.entity_view_mode.node.teaser - core.entity_view_mode.node.rss + - core.entity_view_mode.node.teaser module: - node - taxonomy -- GitLab From 7e78a0e01c252b9bb25559397967d90f26488d1f Mon Sep 17 00:00:00 2001 From: Dave Long <24510-longwave@users.noreply.drupalcode.org> Date: Tue, 6 May 2025 08:30:53 +0000 Subject: [PATCH 22/23] Apply 1 suggestion(s) to 1 file(s) --- core/modules/views/src/ViewsConfigUpdater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index 86304904be0c..06a9e24f5ff2 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -393,7 +393,7 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre // it will use that. // It would make sense to use any RSS view_mode if available, but that // would mean 'default' can never be set as a view mode. That is an - // issue, therefor, if we have a default view mode available, we will + // issue, therefore, if we have a default view mode available, we will // use that. if ($previous_view_mode === NULL) { $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]); -- GitLab From 568b07ed11e5e94f79405f047c5cf99939993450 Mon Sep 17 00:00:00 2001 From: bjorn <bjorn@swis.nl> Date: Tue, 13 May 2025 13:32:17 +0200 Subject: [PATCH 23/23] chore: add documentation to the 2 ViewsConfigUpdater methods --- core/modules/views/src/ViewsConfigUpdater.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php index 06a9e24f5ff2..5531d8934f85 100644 --- a/core/modules/views/src/ViewsConfigUpdater.php +++ b/core/modules/views/src/ViewsConfigUpdater.php @@ -367,10 +367,32 @@ public function processTableCssClassUpdate(ViewEntityInterface $view): bool { return $changed; } + /** + * Checks for views needing a default RSS view mode. + * + * @param \Drupal\views\ViewEntityInterface $view + * The view entity. + * @param string|null $previous_view_mode + * The previous view mode. + * + * @return bool + * TRUE if the view has been updated. + */ public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL): bool { return $this->processRssViewModeUpdate($view, $previous_view_mode); } + /** + * Processes views and sets the default RSS view mode if necessary. + * + * @param \Drupal\views\ViewEntityInterface $view + * The view entity. + * @param string|null $previous_view_mode + * The previous view mode. + * + * @return bool + * TRUE if the view was updated with a default RSS view mode. + */ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL) : bool { $changed = FALSE; $displays = $view->get('display'); -- GitLab