From 75294a359cb2d9959d605b4dd19ba0438facea34 Mon Sep 17 00:00:00 2001 From: alexpott Date: Mon, 17 Jun 2024 12:51:59 +0100 Subject: [PATCH 01/18] Use Drupal 10.3.x * Use Drupal 10.3.x * Remove patch fixed in 10.3 * Fix deprecated code usage in test * Remove unused use * Fix MetatagTest * Fix kernel test * Update config for 10.3.x * Update minimum for media_library_media_modify * Ignore some config changes outside Thunder and covered by the views updater * Increase minimum version of Scheduler due to event dispatcher change * Fix GraphQL SchemaTest * Copy core and convert styles to webp on new thunder installs * Use new media_library_media_modify release * Update tests for webp * Update image styles * Use new commands to do upgrade testing * Add step to fix old install due to borked packages * Ensure all supported entity types have the correct fields * Update media views * Update composer.json --------- Co-authored-by: Daniel Bosen Co-authored-by: Christian Fritsch --- .github/workflows/test.yml | 2 +- composer.json | 9 ++++----- config/install/editor.editor.basic_html.yml | 6 +++--- config/install/editor.editor.full_html.yml | 6 +++--- .../install/image.style.linkit_result_thumbnail.yml | 6 ++++++ config/install/image.style.thumbnail.yml | 6 ++++++ config/install/views.view.media_library.yml | 1 + .../views.view.scheduler_scheduled_content.yml | 4 +++- .../install/views.view.scheduler_scheduled_media.yml | 4 +++- .../views.view.scheduler_scheduled_taxonomy_term.yml | 1 + config/optional/image.style.facebook.yml | 6 ++++++ config/optional/image.style.gallery.yml | 6 ++++++ config/optional/image.style.media_image.yml | 6 ++++++ config/optional/image.style.media_image_mobile.yml | 6 ++++++ config/optional/image.style.media_image_tablet.yml | 6 ++++++ config/optional/image.style.twitter.yml | 6 ++++++ config/optional/node.type.article.yml | 2 +- config/optional/node.type.news_article.yml | 2 +- config/optional/node.type.page.yml | 2 +- config/optional/taxonomy.vocabulary.channel.yml | 3 ++- config/optional/taxonomy.vocabulary.tags.yml | 1 + config/optional/views.view.content.yml | 1 + config/optional/views.view.media.yml | 1 + .../src/Kernel/DataProducer/ThunderRedirectTest.php | 1 + .../src/Functional/FilenameTransliterationTest.php | 4 ++-- tests/src/Functional/InstalledConfigurationTest.php | 12 +++++++++++- .../FunctionalJavascript/MediaImageModifyTest.php | 4 +++- .../src/FunctionalJavascript/MetaInformationTest.php | 6 ++++-- tests/src/Kernel/MetatagTest.php | 7 ++++--- thunder.info.yml | 2 +- thunder.install | 10 ++++++++++ 31 files changed, 111 insertions(+), 28 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bf21ccc4e..2f59e608c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ on: env: DRUPAL_TESTING_COMPOSER_PROJECT: thunder/thunder-project - DRUPAL_TESTING_COMPOSER_PROJECT_VERSION: "^4.0@stable" + DRUPAL_TESTING_COMPOSER_PROJECT_VERSION: "dev-TEST-update-to-10.3.x" DRUPAL_TESTING_DATABASE_USER: root DRUPAL_TESTING_DATABASE_PASSWORD: root DRUPAL_TESTING_TEST_DUMP_FILE: site-dump.tar.gz diff --git a/composer.json b/composer.json index 8cbdad155..a871c6aab 100644 --- a/composer.json +++ b/composer.json @@ -36,8 +36,7 @@ "patches": { "drupal/core": { "Fix Claro styles for exposed views filters wrapped in fieldsets": "https://www.drupal.org/files/issues/2021-05-31/3133639.19.patch", - "Let users configure the text of the \"Add media\" button": "https://www.drupal.org/files/issues/2021-10-01/3169956-34.patch", - "Issue #3388913: Checkbox for Media library modal missing after search": "https://www.drupal.org/files/issues/2024-01-30/3388913-48-d10.1.patch" + "Let users configure the text of the \"Add media\" button": "https://www.drupal.org/files/issues/2021-10-01/3169956-34.patch" }, "drupal/diff": { "Back button for comparison page": "https://www.drupal.org/files/issues/back_button_for-2853193-4.patch" @@ -56,7 +55,7 @@ "drupal/autosave_form": "^1.2", "drupal/blazy": "^2.14", "drupal/checklistapi": "^2.1", - "drupal/core-recommended": "~10.2.4@stable", + "drupal/core-recommended": "~10.3.0@rc", "drupal/config_selector": "^2.1", "drupal/config_update": "^1.7 || ^2.0", "drupal/content_lock": "^2.1", @@ -82,7 +81,7 @@ "drupal/media_entity_slideshow": "^2.0-alpha1", "drupal/media_entity_twitter": "^2.5", "drupal/media_expire": "^2.6", - "drupal/media_library_media_modify": "^1.0.0-beta14", + "drupal/media_library_media_modify": "^1.0.0-beta16", "drupal/media_file_delete": "^1.2", "drupal/metatag": "^1.26", "drupal/metatag_async_widget": "^1.0-alpha2", @@ -93,7 +92,7 @@ "drupal/pathauto": "^1.11", "drupal/responsive_preview": "^2.1", "drupal/redirect": "^1.7", - "drupal/scheduler": "^2.0", + "drupal/scheduler": "^2.0.2", "drupal/scheduler_content_moderation_integration": "^2.0", "drupal/schema_metatag": "^2.4", "drupal/select2": "^1.7", diff --git a/config/install/editor.editor.basic_html.yml b/config/install/editor.editor.basic_html.yml index 84cc9573c..0b7bb8be6 100644 --- a/config/install/editor.editor.basic_html.yml +++ b/config/install/editor.editor.basic_html.yml @@ -60,7 +60,7 @@ image_upload: status: true scheme: public directory: inline-images - max_size: '' + max_size: null max_dimensions: - width: 0 - height: 0 + width: null + height: null diff --git a/config/install/editor.editor.full_html.yml b/config/install/editor.editor.full_html.yml index 51f25c736..7a67aa5b4 100644 --- a/config/install/editor.editor.full_html.yml +++ b/config/install/editor.editor.full_html.yml @@ -98,7 +98,7 @@ image_upload: status: true scheme: public directory: inline-images - max_size: '' + max_size: null max_dimensions: - width: 0 - height: 0 + width: null + height: null diff --git a/config/install/image.style.linkit_result_thumbnail.yml b/config/install/image.style.linkit_result_thumbnail.yml index 1d6d88ea4..703d123e7 100644 --- a/config/install/image.style.linkit_result_thumbnail.yml +++ b/config/install/image.style.linkit_result_thumbnail.yml @@ -12,3 +12,9 @@ effects: width: 50 height: 50 anchor: center-center + 451bc36f-b256-43cc-adb5-4f3151fd892d: + uuid: 451bc36f-b256-43cc-adb5-4f3151fd892d + id: image_convert + weight: 2 + data: + extension: webp diff --git a/config/install/image.style.thumbnail.yml b/config/install/image.style.thumbnail.yml index 2780cc9c6..3059d4bde 100644 --- a/config/install/image.style.thumbnail.yml +++ b/config/install/image.style.thumbnail.yml @@ -14,3 +14,9 @@ effects: width: 100 height: 100 crop_type: focal_point + c4eb9942-2c9e-4a81-949f-6161a44b6559: + uuid: c4eb9942-2c9e-4a81-949f-6161a44b6559 + id: image_convert + weight: 2 + data: + extension: webp diff --git a/config/install/views.view.media_library.yml b/config/install/views.view.media_library.yml index 8e1a64aec..a329d29c4 100644 --- a/config/install/views.view.media_library.yml +++ b/config/install/views.view.media_library.yml @@ -150,6 +150,7 @@ display: items_per_page_options_all_label: '- All -' offset: false offset_label: Offset + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/config/install/views.view.scheduler_scheduled_content.yml b/config/install/views.view.scheduler_scheduled_content.yml index 73e241292..1be50ec8f 100644 --- a/config/install/views.view.scheduler_scheduled_content.yml +++ b/config/install/views.view.scheduler_scheduled_content.yml @@ -537,6 +537,7 @@ display: previous: '‹ previous' first: '« first' last: 'last »' + pagination_heading_level: h4 exposed_form: type: basic options: @@ -1080,7 +1081,7 @@ display: admin_label: '' entity_type: node entity_field: uid - plugin_id: numeric + plugin_id: entity_target_id default_action: empty exception: value: all @@ -1112,6 +1113,7 @@ display: roles: { } break_phrase: false not: false + target_entity_type_id: user defaults: empty: false access: false diff --git a/config/install/views.view.scheduler_scheduled_media.yml b/config/install/views.view.scheduler_scheduled_media.yml index d2235ad80..2ef91dc19 100644 --- a/config/install/views.view.scheduler_scheduled_media.yml +++ b/config/install/views.view.scheduler_scheduled_media.yml @@ -563,6 +563,7 @@ display: items_per_page_options_all_label: '- All -' offset: false offset_label: Offset + pagination_heading_level: h4 exposed_form: type: basic options: @@ -1077,7 +1078,8 @@ display: field: uid entity_type: media entity_field: uid - plugin_id: numeric + plugin_id: entity_target_id + target_entity_type_id: user defaults: empty: false access: false diff --git a/config/install/views.view.scheduler_scheduled_taxonomy_term.yml b/config/install/views.view.scheduler_scheduled_taxonomy_term.yml index 382044bb8..8fdac6400 100644 --- a/config/install/views.view.scheduler_scheduled_taxonomy_term.yml +++ b/config/install/views.view.scheduler_scheduled_taxonomy_term.yml @@ -499,6 +499,7 @@ display: items_per_page_options_all_label: '- All -' offset: false offset_label: Offset + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/config/optional/image.style.facebook.yml b/config/optional/image.style.facebook.yml index ef5a3bd73..d61808606 100644 --- a/config/optional/image.style.facebook.yml +++ b/config/optional/image.style.facebook.yml @@ -14,3 +14,9 @@ effects: width: 1200 height: 630 crop_type: focal_point + ddffc1b0-0ba5-4137-bc44-90354696de13: + uuid: ddffc1b0-0ba5-4137-bc44-90354696de13 + id: image_convert + weight: 2 + data: + extension: webp diff --git a/config/optional/image.style.gallery.yml b/config/optional/image.style.gallery.yml index 32ad3e162..b2281adf2 100644 --- a/config/optional/image.style.gallery.yml +++ b/config/optional/image.style.gallery.yml @@ -14,3 +14,9 @@ effects: width: 853 height: 480 crop_type: focal_point + 9d5cfaec-9903-444e-964b-4ea2ccdb6608: + uuid: 9d5cfaec-9903-444e-964b-4ea2ccdb6608 + id: image_convert + weight: 2 + data: + extension: webp diff --git a/config/optional/image.style.media_image.yml b/config/optional/image.style.media_image.yml index c00cd73f4..3bd0d82e6 100644 --- a/config/optional/image.style.media_image.yml +++ b/config/optional/image.style.media_image.yml @@ -14,3 +14,9 @@ effects: width: 938 height: 527 crop_type: focal_point + 8963e07c-e414-417d-a0dd-59b2c29399d6: + uuid: 8963e07c-e414-417d-a0dd-59b2c29399d6 + id: image_convert + weight: 2 + data: + extension: webp diff --git a/config/optional/image.style.media_image_mobile.yml b/config/optional/image.style.media_image_mobile.yml index c32a291b0..c2e73a7dc 100644 --- a/config/optional/image.style.media_image_mobile.yml +++ b/config/optional/image.style.media_image_mobile.yml @@ -14,3 +14,9 @@ effects: width: 560 height: 315 crop_type: focal_point + ee591d84-f108-4b47-a0a4-bd3802b38284: + uuid: ee591d84-f108-4b47-a0a4-bd3802b38284 + id: image_convert + weight: 2 + data: + extension: webp diff --git a/config/optional/image.style.media_image_tablet.yml b/config/optional/image.style.media_image_tablet.yml index baa63534b..c2d4b7d65 100644 --- a/config/optional/image.style.media_image_tablet.yml +++ b/config/optional/image.style.media_image_tablet.yml @@ -14,3 +14,9 @@ effects: width: 850 height: 478 crop_type: focal_point + 3898254c-5ffd-47d9-ac3c-6f2d0be0d9ec: + uuid: 3898254c-5ffd-47d9-ac3c-6f2d0be0d9ec + id: image_convert + weight: 2 + data: + extension: webp \ No newline at end of file diff --git a/config/optional/image.style.twitter.yml b/config/optional/image.style.twitter.yml index 47ab518ea..c24a32c82 100644 --- a/config/optional/image.style.twitter.yml +++ b/config/optional/image.style.twitter.yml @@ -14,3 +14,9 @@ effects: width: 1024 height: 512 crop_type: focal_point + 2c85b491-12ad-48cd-9a33-2d32905c2cf5: + uuid: 2c85b491-12ad-48cd-9a33-2d32905c2cf5 + id: image_convert + weight: 2 + data: + extension: webp diff --git a/config/optional/node.type.article.yml b/config/optional/node.type.article.yml index dababc5f2..81324fb24 100644 --- a/config/optional/node.type.article.yml +++ b/config/optional/node.type.article.yml @@ -22,7 +22,7 @@ third_party_settings: name: Article type: article description: 'Use articles for evergreen content.' -help: '' +help: null new_revision: true preview_mode: 1 display_submitted: true diff --git a/config/optional/node.type.news_article.yml b/config/optional/node.type.news_article.yml index 8ef812c03..c8b47a217 100644 --- a/config/optional/node.type.news_article.yml +++ b/config/optional/node.type.news_article.yml @@ -25,7 +25,7 @@ third_party_settings: name: 'News Article' type: news_article description: 'Use news articles for time-sensitive content like news, press releases or blog posts.' -help: '' +help: null new_revision: true preview_mode: 1 display_submitted: true diff --git a/config/optional/node.type.page.yml b/config/optional/node.type.page.yml index 4c1a522ad..755e8ed8c 100644 --- a/config/optional/node.type.page.yml +++ b/config/optional/node.type.page.yml @@ -4,7 +4,7 @@ dependencies: { } name: 'Basic page' type: page description: "Use basic pages for your static content, such as an 'About us' page." -help: '' +help: null new_revision: true preview_mode: 1 display_submitted: false diff --git a/config/optional/taxonomy.vocabulary.channel.yml b/config/optional/taxonomy.vocabulary.channel.yml index 8293c1bba..b9173d86c 100644 --- a/config/optional/taxonomy.vocabulary.channel.yml +++ b/config/optional/taxonomy.vocabulary.channel.yml @@ -3,5 +3,6 @@ status: true dependencies: { } name: Channel vid: channel -description: '' +description: null weight: 0 +new_revision: false diff --git a/config/optional/taxonomy.vocabulary.tags.yml b/config/optional/taxonomy.vocabulary.tags.yml index 4c754e86c..0d0313cf6 100644 --- a/config/optional/taxonomy.vocabulary.tags.yml +++ b/config/optional/taxonomy.vocabulary.tags.yml @@ -5,3 +5,4 @@ name: Tags vid: tags description: 'Use tags to group articles on similar topics into categories.' weight: 0 +new_revision: false diff --git a/config/optional/views.view.content.yml b/config/optional/views.view.content.yml index 3b4677b27..d90a10b33 100644 --- a/config/optional/views.view.content.yml +++ b/config/optional/views.view.content.yml @@ -412,6 +412,7 @@ display: previous: '‹ Previous' first: '« First' last: 'Last »' + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/config/optional/views.view.media.yml b/config/optional/views.view.media.yml index 6f98eaff8..6f44b8942 100644 --- a/config/optional/views.view.media.yml +++ b/config/optional/views.view.media.yml @@ -602,6 +602,7 @@ display: offset: false offset_label: Offset quantity: 9 + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/modules/thunder_gqls/tests/src/Kernel/DataProducer/ThunderRedirectTest.php b/modules/thunder_gqls/tests/src/Kernel/DataProducer/ThunderRedirectTest.php index cd72e851e..422909e1e 100644 --- a/modules/thunder_gqls/tests/src/Kernel/DataProducer/ThunderRedirectTest.php +++ b/modules/thunder_gqls/tests/src/Kernel/DataProducer/ThunderRedirectTest.php @@ -43,6 +43,7 @@ class ThunderRedirectTest extends GraphQLTestBase { */ public function setUp(): void { parent::setUp(); + $this->installEntitySchema('path_alias'); $this->installConfig(['redirect']); $this->installEntitySchema('redirect'); diff --git a/modules/thunder_media/tests/src/Functional/FilenameTransliterationTest.php b/modules/thunder_media/tests/src/Functional/FilenameTransliterationTest.php index 4e7e0b5e6..d5e6845c5 100644 --- a/modules/thunder_media/tests/src/Functional/FilenameTransliterationTest.php +++ b/modules/thunder_media/tests/src/Functional/FilenameTransliterationTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\thunder_media\Functional; -use Drupal\Core\File\FileSystemInterface; +use Drupal\Core\File\FileExists; use Drupal\Core\StreamWrapper\PublicStream; use Drupal\file\Entity\File; use Drupal\Tests\thunder\Functional\ThunderTestBase; @@ -55,7 +55,7 @@ public function testFileTransliteration(): void { // Upload with replace to guarantee there's something there. $edit = [ - 'file_test_replace' => FileSystemInterface::EXISTS_RENAME, + 'file_test_replace' => FileExists::Rename->name, 'files[file_test_upload]' => \Drupal::service('file_system')->realpath('public://foo°.png'), ]; $this->drupalGet('file-test/upload'); diff --git a/tests/src/Functional/InstalledConfigurationTest.php b/tests/src/Functional/InstalledConfigurationTest.php index 4b0d60c91..1fbeb35e8 100644 --- a/tests/src/Functional/InstalledConfigurationTest.php +++ b/tests/src/Functional/InstalledConfigurationTest.php @@ -278,7 +278,17 @@ class InstalledConfigurationTest extends ThunderTestBase { ], 'views.view.locked_content' => [ 'display' => [ - 'default' => ['display_options' => ['sorts' => ['created' => ['expose' => ['field_identifier' => TRUE]]]]], + 'default' => [ + 'display_options' => [ + 'sorts' => ['created' => ['expose' => ['field_identifier' => TRUE]]], + 'pager' => ['options' => ['pagination_heading_level' => TRUE]], + ], + ], + ], + ], + 'views.view.redirect' => [ + 'display' => [ + 'default' => ['display_options' => ['pager' => ['options' => ['pagination_heading_level' => TRUE]]]], ], ], ]; diff --git a/tests/src/FunctionalJavascript/MediaImageModifyTest.php b/tests/src/FunctionalJavascript/MediaImageModifyTest.php index 5891b7aa8..ede0e3bc6 100644 --- a/tests/src/FunctionalJavascript/MediaImageModifyTest.php +++ b/tests/src/FunctionalJavascript/MediaImageModifyTest.php @@ -88,7 +88,9 @@ public function testRemoveAdd(): void { $this->clickAjaxButtonCssSelector('[name="field_paragraphs_0_collapse"]'); /** @var \Drupal\file\FileInterface $file */ $file = $image2->field_image->entity; - $this->assertEquals([$file->getFilename()], $this->getSession()->evaluateScript('jQuery(\'[data-drupal-selector="edit-field-paragraphs-0-preview"] article.media--view-mode-paragraph-preview img\').attr(\'src\').split(\'?\')[0].split(\'/\').splice(-1)'), 'Image file should be identical to previously selected.'); + // On installs that use Drupal 10.3 onwards, the image will be converted to + // a webp image. + $this->assertMatchesRegularExpression('/^' . preg_quote($file->getFilename()) . '(.webp)?$/', $this->getSession()->evaluateScript('jQuery(\'[data-drupal-selector="edit-field-paragraphs-0-preview"] article.media--view-mode-paragraph-preview img\').attr(\'src\').split(\'?\')[0].split(\'/\').splice(-1)')[0], 'Image file should be identical to previously selected.'); // Go to the media view and try deleting the image media. $this->drupalGet('admin/content/media'); diff --git a/tests/src/FunctionalJavascript/MetaInformationTest.php b/tests/src/FunctionalJavascript/MetaInformationTest.php index 25a561a1b..43bb678ee 100644 --- a/tests/src/FunctionalJavascript/MetaInformationTest.php +++ b/tests/src/FunctionalJavascript/MetaInformationTest.php @@ -104,8 +104,8 @@ class MetaInformationTest extends ThunderJavascriptTestBase { '[node:title]' => 'Test Note Title', // For testing Media:1 is used for teaser. - '[node:field_teaser_media:entity:field_image:facebook]' => 'LIKE:/files/styles/facebook/public/2016-05/thunder.jpg?', - '[node:field_teaser_media:entity:field_image:facebook:mimetype]' => 'image/jpeg', + '[node:field_teaser_media:entity:field_image:facebook]' => 'LIKE:/files/styles/facebook/public/2016-05/thunder.jpg.webp?', + '[node:field_teaser_media:entity:field_image:facebook:mimetype]' => 'image/webp', '[node:field_teaser_media:entity:field_image:facebook:height]' => '630', '[node:field_teaser_media:entity:field_image:facebook:width]' => '1200', ]; @@ -204,6 +204,8 @@ protected function checkSavedConfiguration(string $configurationUrl, array $conf * Test Meta Tag default configuration and custom configuration for article. * * @dataProvider providerContentTypes + * + * @group NoUpdate */ public function testArticleMetaTags(string $contentType): void { $globalConfigs = $this->generateMetaTagConfiguration([static::$globalMetaTags]); diff --git a/tests/src/Kernel/MetatagTest.php b/tests/src/Kernel/MetatagTest.php index 565cfb81e..23b76d3bb 100644 --- a/tests/src/Kernel/MetatagTest.php +++ b/tests/src/Kernel/MetatagTest.php @@ -37,6 +37,7 @@ class MetatagTest extends KernelTestBase { 'views', 'image', 'file', + 'filter', 'focal_point', 'crop', 'media_expire', @@ -113,14 +114,14 @@ public function testTagDefaultValues(): void { $this->assertStringContainsString('/files/styles/facebook/public/image-test.png', $elements['og_image_0']['#attributes']['content']); $this->assertEquals('630', $elements['og_image_height']['#attributes']['content']); $this->assertEquals('1200', $elements['og_image_width']['#attributes']['content']); - $this->assertEquals('image/png', $elements['og_image_type']['#attributes']['content']); + $this->assertEquals('image/webp', $elements['og_image_type']['#attributes']['content']); $this->assertEquals('Test Site', $elements['og_site_name']['#attributes']['content']); $this->assertEquals($title, $elements['og_title']['#attributes']['content']); $this->assertNotEmpty($elements['og_updated_time']['#attributes']['content']); $this->assertStringEndsWith('/node/1', $elements['og_url']['#attributes']['content']); $this->assertEquals($description, $elements['twitter_cards_description']['#attributes']['content']); - $this->assertStringContainsString('/files/styles/twitter/public/image-test.png', $elements['twitter_cards_image']['#attributes']['content']); + $this->assertStringContainsString('/files/styles/twitter/public/image-test.png.webp', $elements['twitter_cards_image']['#attributes']['content']); $this->assertEquals('512', $elements['twitter_cards_image_height']['#attributes']['content']); $this->assertEquals('1024', $elements['twitter_cards_image_width']['#attributes']['content']); $this->assertEquals('summary_large_image', $elements['twitter_cards_type']['#attributes']['content']); @@ -129,7 +130,7 @@ public function testTagDefaultValues(): void { $this->assertEquals($title, $elements['schema_article_headline']['#attributes']['content']); $this->assertEquals('Title', $elements['schema_article_name']['#attributes']['content']); $this->assertEquals($description, $elements['schema_article_description']['#attributes']['content']); - $this->assertStringContainsString('/files/styles/facebook/public/image-test.png', $elements['schema_article_image']['#attributes']['content']['url']); + $this->assertStringContainsString('/files/styles/facebook/public/image-test.png.webp', $elements['schema_article_image']['#attributes']['content']['url']); $this->assertEquals('Test Site', $elements['schema_article_publisher']['#attributes']['content']['name']); $this->assertEquals('Organization', $elements['schema_article_publisher']['#attributes']['content']['@type']); } diff --git a/thunder.info.yml b/thunder.info.yml index 0ba6b3747..dc6ee3f67 100644 --- a/thunder.info.yml +++ b/thunder.info.yml @@ -2,7 +2,7 @@ name: Thunder type: profile description: 'The Drupal based CMS for professional publishing.' project: thunder -core_version_requirement: ~10.2.4 +core_version_requirement: ~10.3.0 version: '7.2.2' distribution: diff --git a/thunder.install b/thunder.install index 0fb23417b..72c0b3ea3 100644 --- a/thunder.install +++ b/thunder.install @@ -44,3 +44,13 @@ function _thunder_mark_update_checklist(string $update_id, bool $successful, Upd function thunder_update_last_removed(): int { return 8327; } + +/** + * Add publish state and unpublish state fields to newly supported entity types. + * + * In Drupal 10.3 taxonomy terms can be moderated. + */ +function thunder_update_8328(): \Stringable|string { + $output = _scheduler_content_moderation_integration_add_fields(); + return $output ? implode('
  • ', $output) : t('No update required.'); +} From dda3e2777b1f8c91dd0edd09501f53dbef96d9f1 Mon Sep 17 00:00:00 2001 From: Christian Fritsch Date: Tue, 18 Jun 2024 10:56:25 +0200 Subject: [PATCH 02/18] Check for module existance before in update hook Co-authored-by: Christian Fritsch --- thunder.install | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/thunder.install b/thunder.install index 72c0b3ea3..c31c7c6a1 100644 --- a/thunder.install +++ b/thunder.install @@ -51,6 +51,9 @@ function thunder_update_last_removed(): int { * In Drupal 10.3 taxonomy terms can be moderated. */ function thunder_update_8328(): \Stringable|string { - $output = _scheduler_content_moderation_integration_add_fields(); - return $output ? implode('
  • ', $output) : t('No update required.'); + if (\Drupal::moduleHandler()->moduleExists('scheduler_content_moderation_integration')) { + $output = _scheduler_content_moderation_integration_add_fields(); + return $output ? implode('
  • ', $output) : t('No update required.'); + } + return t('No update required.'); } From ea3224827d0e95ab3c545644ffa3a1b74323e22c Mon Sep 17 00:00:00 2001 From: Christian Fritsch Date: Fri, 21 Jun 2024 09:10:23 +0200 Subject: [PATCH 03/18] Use stable d10.3 release Co-authored-by: Christian Fritsch --- .github/workflows/test.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2f59e608c..bf21ccc4e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ on: env: DRUPAL_TESTING_COMPOSER_PROJECT: thunder/thunder-project - DRUPAL_TESTING_COMPOSER_PROJECT_VERSION: "dev-TEST-update-to-10.3.x" + DRUPAL_TESTING_COMPOSER_PROJECT_VERSION: "^4.0@stable" DRUPAL_TESTING_DATABASE_USER: root DRUPAL_TESTING_DATABASE_PASSWORD: root DRUPAL_TESTING_TEST_DUMP_FILE: site-dump.tar.gz diff --git a/composer.json b/composer.json index a871c6aab..4497f5463 100644 --- a/composer.json +++ b/composer.json @@ -55,7 +55,7 @@ "drupal/autosave_form": "^1.2", "drupal/blazy": "^2.14", "drupal/checklistapi": "^2.1", - "drupal/core-recommended": "~10.3.0@rc", + "drupal/core-recommended": "~10.3.0@stable", "drupal/config_selector": "^2.1", "drupal/config_update": "^1.7 || ^2.0", "drupal/content_lock": "^2.1", From 98b7b81d0b76b5ca9bc2c489d414b149a14c8868 Mon Sep 17 00:00:00 2001 From: Christian Fritsch Date: Mon, 24 Jun 2024 10:25:09 +0200 Subject: [PATCH 04/18] Update to gin RC11 * Update to gin RC11 * Update composer.json * Update toolbar * Gin foo * Enable sticke action buttons * Fix tests * migrate phpunit config * Add return type * lets see * remove try catch * fix UnusedUseStatement --------- Co-authored-by: Christian Fritsch Co-authored-by: Killesreiter Volker --- composer.json | 4 +- config/install/gin.settings.yml | 1 + .../src/ThunderWorkflowFormHelper.php | 5 + phpunit.xml.dist | 52 ++++----- tests/src/Functional/ThunderTestBase.php | 2 + .../MediaImageModifyTest.php | 6 +- tests/src/Traits/ThunderGinTestTrait.php | 104 ++++++++++++++++++ thunder.post_update.php | 11 ++ 8 files changed, 150 insertions(+), 35 deletions(-) create mode 100644 tests/src/Traits/ThunderGinTestTrait.php diff --git a/composer.json b/composer.json index 4497f5463..d4e19fa34 100644 --- a/composer.json +++ b/composer.json @@ -69,8 +69,8 @@ "drupal/field_group": "^3.4", "drupal/focal_point": "2.0.2", "drupal/facets": "^2.0.6", - "drupal/gin": "3.0-rc9", - "drupal/gin_toolbar": "^1.0-rc5", + "drupal/gin": "3.0-rc11", + "drupal/gin_toolbar": "^1.0-rc6", "drupal/graphql": "^4.7", "drupal/inline_entity_form": "^1.0-rc14", "drupal/ivw_integration": "^2.0", diff --git a/config/install/gin.settings.yml b/config/install/gin.settings.yml index f57d0a8fa..19738d29f 100644 --- a/config/install/gin.settings.yml +++ b/config/install/gin.settings.yml @@ -24,3 +24,4 @@ focus_color: '' layout_density: small show_description_toggle: true show_user_theme_settings: true +sticky_action_buttons: true diff --git a/modules/thunder_workflow/src/ThunderWorkflowFormHelper.php b/modules/thunder_workflow/src/ThunderWorkflowFormHelper.php index 3be126b1e..091662a10 100644 --- a/modules/thunder_workflow/src/ThunderWorkflowFormHelper.php +++ b/modules/thunder_workflow/src/ThunderWorkflowFormHelper.php @@ -204,6 +204,11 @@ public function moveStateToActions(NodeInterface $entity, array $form): array { $form['actions']['moderation_state'] = $form['moderation_state']; unset($form['moderation_state']); + // Promote moderation_state in gin theme to not end up in + // dropdown button. + $form['actions']['moderation_state']['#gin_action_item'] = TRUE; + $form['actions']['moderation_state']['widget'][0]['#attributes']['form'] = $form['#id']; + return $form; } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 1bf1a0520..f63099d0d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,17 +1,27 @@ - - + + + + ./includes + ./lib + ./modules + ../modules + ../sites + + + ./modules/*/src/Tests + ./modules/*/tests + ../modules/*/src/Tests + ../modules/*/tests + ../modules/*/*/src/Tests + ../modules/*/*/tests + + @@ -31,11 +41,11 @@ - + - + - + @@ -59,24 +69,4 @@ - - - ./includes - ./lib - - ./modules - - ./modules/*/src/Tests - ./modules/*/tests - - ../modules - - ../modules/*/src/Tests - ../modules/*/tests - ../modules/*/*/src/Tests - ../modules/*/*/tests - - ../sites - - diff --git a/tests/src/Functional/ThunderTestBase.php b/tests/src/Functional/ThunderTestBase.php index 5b7f7546a..44e79c2fd 100644 --- a/tests/src/Functional/ThunderTestBase.php +++ b/tests/src/Functional/ThunderTestBase.php @@ -4,6 +4,7 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Tests\BrowserTestBase; +use Drupal\Tests\thunder\Traits\ThunderGinTestTrait; use Drupal\Tests\thunder\Traits\ThunderTestTrait; use Prophecy\PhpUnit\ProphecyTrait; @@ -15,6 +16,7 @@ abstract class ThunderTestBase extends BrowserTestBase { use ThunderTestTrait; use StringTranslationTrait; use ProphecyTrait; + use ThunderGinTestTrait; /** * {@inheritdoc} diff --git a/tests/src/FunctionalJavascript/MediaImageModifyTest.php b/tests/src/FunctionalJavascript/MediaImageModifyTest.php index ede0e3bc6..701fc3e8e 100644 --- a/tests/src/FunctionalJavascript/MediaImageModifyTest.php +++ b/tests/src/FunctionalJavascript/MediaImageModifyTest.php @@ -100,14 +100,16 @@ public function testRemoveAdd(): void { /** @var \Drupal\file\FileInterface $file */ $file = $media->get($media->getSource()->getConfiguration()['source_field'])->entity; $this->assertFileExists($file->getFileUri()); - $this->getSession()->getPage()->find('css', 'div.gin-sidebar')->clickLink('Delete'); + $this->getSession()->getPage()->find('css', '[data-drupal-selector="edit-actions"] .gin-more-actions__trigger')->click(); + $this->getSession()->getPage()->find('css', '[data-drupal-selector="edit-actions"]')->clickLink('Delete'); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertNotEmpty($this->assertSession()->waitForElementVisible('css', '#drupal-modal')); $this->assertSession()->fieldNotExists('also_delete_file'); $this->assertSession()->pageTextContains('This action cannot be undone.The file attached to this media is owned by admin so will be retained.'); Role::load(static::$defaultUserRole)->grantPermission('delete any file')->save(); $this->getSession()->reload(); - $this->getSession()->getPage()->find('css', 'div.gin-sidebar')->clickLink('Delete'); + $this->getSession()->getPage()->find('css', '[data-drupal-selector="edit-actions"] .gin-more-actions__trigger')->click(); + $this->getSession()->getPage()->find('css', '[data-drupal-selector="edit-actions"]')->clickLink('Delete'); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertNotEmpty($this->assertSession()->waitForElementVisible('css', '#drupal-modal')); $this->assertSession()->fieldExists('also_delete_file')->check(); diff --git a/tests/src/Traits/ThunderGinTestTrait.php b/tests/src/Traits/ThunderGinTestTrait.php new file mode 100644 index 000000000..6672f993c --- /dev/null +++ b/tests/src/Traits/ThunderGinTestTrait.php @@ -0,0 +1,104 @@ +assertSession(); + $submit_button = $assert_session->buttonExists($submit); + + // Check if button has a form attribute set. + if ($form_id = $submit_button->getAttribute('form')) { + $form = $assert_session->elementExists('xpath', "//form[@id='$form_id']"); + $action = $form->getAttribute('action'); + } + // Get the form. + elseif (isset($form_html_id)) { + $form = $assert_session->elementExists('xpath', "//form[@id='$form_html_id']"); + $submit_button = $assert_session->buttonExists($submit, $form); + $action = $form->getAttribute('action'); + } + else { + // Gin Form Test: Change check to include //form + // so we keep the search in scope of a form. + $submit_button = $assert_session->elementExists('xpath', "//input[@value='$submit']"); + $form = $assert_session->elementExists('xpath', './ancestor::form', $submit_button); + $action = $form->getAttribute('action'); + } + + // Edit the form values. + foreach ($edit as $name => $value) { + // Fields / buttons in static area are not in form context. + $field = $assert_session->fieldExists($name); + + // Provide support for the values '1' and '0' for checkboxes instead of + // TRUE and FALSE. + // @todo Get rid of supporting 1/0 by converting all tests cases using + // this to boolean values. + $field_type = $field->getAttribute('type'); + if ($field_type === 'checkbox') { + $value = (bool) $value; + } + $field->setValue($value); + } + + // Submit form. + $this->prepareRequest(); + $submit_button->press(); + + // Ensure that any changes to variables in the other thread are picked up. + $this->refreshVariables(); + + // Check if there are any meta refresh redirects (like Batch API pages). + if ($this->checkForMetaRefresh()) { + // We are finished with all meta refresh redirects, so reset the counter. + $this->metaRefreshCount = 0; + } + + // Log only for WebDriverTestBase tests because for tests using + // DrupalTestBrowser we log with ::getResponseLogHandler. + if ($this->htmlOutputEnabled && !$this->isTestUsingGuzzleClient()) { + $out = $this->getSession()->getPage()->getContent(); + $html_output = 'POST request to: ' . $action . + '
    Ending URL: ' . $this->getSession()->getCurrentUrl(); + $html_output .= '
    ' . $out; + $html_output .= $this->getHtmlOutputHeaders(); + $this->htmlOutput($html_output); + } + + } + +} diff --git a/thunder.post_update.php b/thunder.post_update.php index d8e8af5f7..f2a19b737 100644 --- a/thunder.post_update.php +++ b/thunder.post_update.php @@ -115,3 +115,14 @@ function thunder_post_update_0002_enable_paragraphs_split(array &$sandbox): stri // Output logged messages to related channel of update execution. return $updater->logger()->output(); } + +/** + * Enable sticky action buttons for the Gin theme. + */ +function thunder_post_update_0003_enable_sticky_action_buttons(array &$sandbox): string { + \Drupal::configFactory()->getEditable('gin.settings') + ->set('sticky_action_buttons', TRUE) + ->save(); + + return t('Sticky action buttons enabled.'); +} From 058b57e4754301e79be2d63da168277551fd549f Mon Sep 17 00:00:00 2001 From: Christian Fritsch Date: Mon, 24 Jun 2024 10:54:25 +0200 Subject: [PATCH 05/18] Update diff and focal_point Co-authored-by: Christian Fritsch --- composer.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index d4e19fa34..a764a783f 100644 --- a/composer.json +++ b/composer.json @@ -40,9 +40,6 @@ }, "drupal/diff": { "Back button for comparison page": "https://www.drupal.org/files/issues/back_button_for-2853193-4.patch" - }, - "drupal/focal_point": { - "Preview link accidentally closes the media library": "https://www.drupal.org/files/issues/2020-10-11/preview_link_accidentally_closes_the_media_library-3162210-19.patch" } } }, @@ -61,13 +58,13 @@ "drupal/content_lock": "^2.1", "drupal/crop": "^2.2", "drupal/default_content": "^1.0-alpha7||^2.0@ALPHA", - "drupal/diff": "1.3", + "drupal/diff": "1.7", "drupal/dropzonejs": "^2.8", "drupal/empty_fields": "^1.0-alpha1", "drupal/entity_reference_actions": "^1.0", "drupal/entity_reference_revisions": "^1.3", "drupal/field_group": "^3.4", - "drupal/focal_point": "2.0.2", + "drupal/focal_point": "^2.1", "drupal/facets": "^2.0.6", "drupal/gin": "3.0-rc11", "drupal/gin_toolbar": "^1.0-rc6", From f5d3be3b6f2b97b1fb748094e67f275fc511c462 Mon Sep 17 00:00:00 2001 From: Volker Killesreiter Date: Mon, 24 Jun 2024 11:24:15 +0200 Subject: [PATCH 06/18] Remove orphan form helper * Remove zombie ThunderNodeFormHelper reintroduced in https://github.com/thunder/thunder-distribution/pull/688 * remove from baseline --------- Co-authored-by: Christian Fritsch --- .../src/Form/ThunderNodeFormHelper.php | 199 ------------------ phpstan-baseline.neon | 5 - 2 files changed, 204 deletions(-) delete mode 100644 modules/thunder_article/src/Form/ThunderNodeFormHelper.php diff --git a/modules/thunder_article/src/Form/ThunderNodeFormHelper.php b/modules/thunder_article/src/Form/ThunderNodeFormHelper.php deleted file mode 100644 index ded7f1fba..000000000 --- a/modules/thunder_article/src/Form/ThunderNodeFormHelper.php +++ /dev/null @@ -1,199 +0,0 @@ -currentUser = $current_user; - $this->messenger = $messenger; - $this->request = $requestStack->getCurrentRequest(); - $this->entityTypeManager = $entity_type_manager; - $this->themeManager = $theme_manager; - $this->moderationInfo = $moderationInfo; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container): self { - return new static( - $container->get('current_user'), - $container->get('messenger'), - $container->get('request_stack'), - $container->get('entity_type.manager'), - $container->get('theme.manager'), - $container->get('content_moderation.moderation_information', ContainerInterface::NULL_ON_INVALID_REFERENCE) - ); - } - - /** - * {@inheritdoc} - */ - public function formAlter(array &$form, FormStateInterface $form_state): array { - /** @var \Drupal\Core\Entity\ContentEntityFormInterface $form_object */ - $form_object = $form_state->getFormObject(); - /** @var \Drupal\node\NodeInterface $entity */ - $entity = $form_object->getEntity(); - - /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ - $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId()); - $latest_revision_id = $storage->getLatestTranslationAffectedRevisionId($entity->id(), $entity->language()->getId()); - if ($latest_revision_id !== NULL && $this->moderationInfo && $this->moderationInfo->hasPendingRevision($entity)) { - $this->messenger->addWarning($this->t('This %entity_type has unpublished changes from user %user.', [ - '%entity_type' => $entity->get('type')->entity->label(), - '%user' => $entity->getRevisionUser()->label(), - ])); - } - - $form['actions'] = array_merge($form['actions'], $this->actions($entity)); - - return $form; - } - - /** - * {@inheritdoc} - */ - protected function actions(NodeInterface $entity): array { - /** @var \Drupal\node\Entity\Node $entity */ - /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ - $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId()); - $latest_revision_id = $storage->getLatestTranslationAffectedRevisionId($entity->id(), $entity->language()->getId()); - - if ($latest_revision_id == NULL || !$this->moderationInfo || !$this->moderationInfo->isModeratedEntity($entity)) { - return []; - } - - $element = []; - // @todo Remove after seven / thunder_admin support is dropped. - $activeTheme = $this->themeManager->getActiveTheme(); - $activeThemes = array_keys($activeTheme->getBaseThemeExtensions()); - $activeThemes[] = $activeTheme->getName(); - - if (!empty(array_intersect($activeThemes, ['seven', 'thunder_admin']))) { - /** @var \Drupal\content_moderation\ContentModerationState $state */ - $state = $this->moderationInfo->getWorkflowForEntity($entity)->getTypePlugin()->getState($entity->moderation_state->value); - $element['status'] = [ - '#type' => 'item', - '#markup' => $entity->isNew() || !$this->moderationInfo->isDefaultRevisionPublished($entity) ? $this->t('of unpublished @entity_type', ['@entity_type' => strtolower($entity->type->entity->label())]) : $this->t('of published @entity_type', ['@entity_type' => strtolower($entity->type->entity->label())]), - '#weight' => 200, - '#wrapper_attributes' => [ - 'class' => ['status'], - ], - '#access' => !$state->isDefaultRevisionState(), - ]; - - $element['moderation_state_current'] = [ - '#type' => 'item', - '#markup' => $state->label(), - '#weight' => 210, - '#wrapper_attributes' => [ - 'class' => ['status', $state->id()], - ], - ]; - } - - if ($this->moderationInfo->hasPendingRevision($entity)) { - $route_info = Url::fromRoute('node.revision_revert_default_confirm', [ - 'node' => $entity->id(), - 'node_revision' => $entity->getRevisionId(), - ]); - if ($this->request->query->has('destination')) { - $query = $route_info->getOption('query'); - $query['destination'] = $this->request->query->get('destination'); - $route_info->setOption('query', $query); - } - - $element['revert_to_default'] = [ - '#type' => 'link', - '#title' => $this->t('Revert to default revision'), - '#access' => $entity->access('revert revision', $this->currentUser), - '#weight' => 101, - '#attributes' => [ - 'class' => ['button', 'button--danger'], - ], - ]; - $element['revert_to_default']['#url'] = $route_info; - } - - return $element; - } - -} diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ea4730437..3fcf0a4db 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5,11 +5,6 @@ parameters: count: 1 path: modules/thunder_article/src/Form/NodeRevisionRevertDefaultForm.php - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_article/src/Form/ThunderNodeFormHelper.php - - message: "#^Unsafe usage of new static\\(\\)\\.$#" count: 1 From 2e5de00e2432603db4f6d8a98be653252c3b9fb4 Mon Sep 17 00:00:00 2001 From: alexpott Date: Mon, 24 Jun 2024 14:01:57 +0100 Subject: [PATCH 07/18] Test php 8.3 support * Use Drupal 10.3.x * Remove patch fixed in 10.3 * Fix deprecated code usage in test * Remove unused use * Rerigger build * Add fixes for 10.3.x * Fix MetatagTest * Fix kernel test * Update config for 10.3.x * Update minimum for media_library_media_modify * Ignore some config changes outside Thunder and covered by the views updater * Increase minimum version of Scheduler due to event dispatcher change * PHPCS * Fix GraphQL SchemaTest * Rmove core 10.3.x patch that has been fixed * Copy core and convert styles to webp on new thunder installs * Doh * Use new media_library_media_modify release * Update tests for webp * Update tests for webp pt 2 * tmate * Update image styles * Use new commands to do upgrade testing * Rerun * Rerun * Rerun * Set workspace directory * Magic sauce * Workspace fun * tmate * Rerun * Rerun * Rerun * Add step to fix old install due to borked packages * Fix webp assertion after updating * Ensure all supported entity types have the correct fields * Add return type * PHPCS * Add NoUpdate group to test that is hard to do in an update scenario * Rerun * Remove unneeded thunder 6 composer lock file * Use a stable version of DRUPAL_TESTING_VERSION * Better constraint * Add a comment about how expectations * Use ApiRequestTrait to make debugging tests with XDebug easier * Improve SchemaTest::testNonExistingEntityLinks() * One less phpstan error * Run tests on PHP 8.3 * Add patch for autosave_form * Update content_lock to latest version that supports PHP 8.3 without errors * Revert "Update content_lock to latest version that supports PHP 8.3 without errors" This reverts commit def4c8e1c20ae32038262de468962526becef599. * Use patch for entity reference actions * Add 8.3 build * Fix PHPStan issues on PHP 8.3 to do with dynamic properties * Ensure we are using Content Lock 2.4 so our test is consistent. Given the number of bug fixes in 2.4 that's not a bad thing. * Fix PHP 8.3 deprecation and make tests work regardless of the path * Add linting * Merge error * Remove unnecesary change * Missed a thing in the merge * Re-test on latest 10.3.x * Update media views * Update to releases * No jquery_ui_draggable needed anymore * Try * Foo * Foo * Foo * Foo --------- Co-authored-by: Daniel Bosen Co-authored-by: Christian Fritsch Co-authored-by: Christian Fritsch --- .github/workflows/test.yml | 8 +++++--- composer.json | 4 ++-- thunder.post_update.php | 1 - 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bf21ccc4e..b2a699ae0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,7 +50,7 @@ jobs: strategy: matrix: - PHP_VERSION: [ '8.1' ] + PHP_VERSION: [ '8.1', '8.3' ] env: DRUPAL_TESTING_TEST_DEPRECATION: true @@ -124,7 +124,7 @@ jobs: strategy: fail-fast: false matrix: - PHP_VERSION: [ '8.1' ] + PHP_VERSION: [ '8.3' ] CHUNK: [ 1, 2, 3 ] steps: @@ -336,7 +336,9 @@ jobs: run: test-drupal-project prepare_build - name: Install suggested dependencies - run: composer require "league/container:^4.2" "consolidation/config:^2.1.2" --no-update --no-progress --working-dir=/tmp/test/thunder/install + run: | + composer require "league/container:^4.2" "drupal/core-dev:^10.3" --no-update --no-progress --working-dir=/tmp/test/thunder/install + composer config allow-plugins.php-http/discovery true --no-plugins --working-dir=/tmp/test/thunder/install - name: Build the docroot run: test-drupal-project build diff --git a/composer.json b/composer.json index a764a783f..6dd974e56 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "drupal/access_unpublished": "^1.5", "drupal/admin_toolbar": "^3.4", "drupal/autofill": "^1.1", - "drupal/autosave_form": "^1.2", + "drupal/autosave_form": "^1.6", "drupal/blazy": "^2.14", "drupal/checklistapi": "^2.1", "drupal/core-recommended": "~10.3.0@stable", @@ -61,7 +61,7 @@ "drupal/diff": "1.7", "drupal/dropzonejs": "^2.8", "drupal/empty_fields": "^1.0-alpha1", - "drupal/entity_reference_actions": "^1.0", + "drupal/entity_reference_actions": "^1.1", "drupal/entity_reference_revisions": "^1.3", "drupal/field_group": "^3.4", "drupal/focal_point": "^2.1", diff --git a/thunder.post_update.php b/thunder.post_update.php index f2a19b737..e34b956ee 100644 --- a/thunder.post_update.php +++ b/thunder.post_update.php @@ -21,7 +21,6 @@ function thunder_post_update_0001_upgrade_to_thunder7(array &$sandbox): string { 'media_library_media_modify', 'gin_toolbar', 'jquery_ui', - 'jquery_ui_draggable', 'ckeditor5', ]); From 383fa344f7e1b22a8d61be695055a00a97a6b404 Mon Sep 17 00:00:00 2001 From: Christian Fritsch Date: Mon, 24 Jun 2024 15:26:09 +0200 Subject: [PATCH 08/18] Require jQuery UI Draggable Co-authored-by: Christian Fritsch --- composer.json | 3 +- docs/developer-guide/migration/migrate-7-8.md | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 docs/developer-guide/migration/migrate-7-8.md diff --git a/composer.json b/composer.json index 6dd974e56..f54ca7e7e 100644 --- a/composer.json +++ b/composer.json @@ -110,7 +110,8 @@ "npm-asset/select2": "^4.0.7", "caxy/php-htmldiff": "^0.1.14", "webonyx/graphql-php": "^14.11.8", - "drupal/jquery_ui": "^1.6" + "drupal/jquery_ui": "^1.6", + "drupal/jquery_ui_draggable": "^2.1" }, "suggest": { "drupal/search_api_solr": "Provides a Apache Solr backend for the Search API module" diff --git a/docs/developer-guide/migration/migrate-7-8.md b/docs/developer-guide/migration/migrate-7-8.md new file mode 100644 index 000000000..53026603b --- /dev/null +++ b/docs/developer-guide/migration/migrate-7-8.md @@ -0,0 +1,39 @@ +# Update Thunder 7 -> Thunder 8 + +## Prerequisites + +These are the instructions to manually update your existing Thunder 7 installation to Thunder 8. If +you want to do a fresh installation of thunder please visit [install Thunder](../setup.md#install-thunder). + +You have to make sure that your Thunder 7 project and all its dependencies are fully updated to the most current +versions. Run the following command in your docroot: + +```bash +drush ev "print drupal_get_installed_schema_version('thunder') . PHP_EOL;" +``` + +This should print the number XXXX or greater. If that is not the case, update your project. + +```bash +cd .. +composer update +``` + +This should update to Thunder 7.3 or greater. + +Now run database updates: + +```bash +cd docroot +drush updb +``` + +You should at least see the Thunder XXXX schema update. If not, double check that the correct version of Thunder +is installed, and that `drush updb` did not throw any errors. + +Before you start with the code and database update please disable the jQuery UI Draggable module or require it on your own. + +```bash +composer require drupal/jquery_ui_draggable +``` + From 268df6b6e49c771efd48e32147686f43a8c6a750 Mon Sep 17 00:00:00 2001 From: Christian Fritsch Date: Mon, 24 Jun 2024 17:10:41 +0200 Subject: [PATCH 09/18] Thunder 7.3 release Co-authored-by: Christian Fritsch --- CHANGELOG.md | 8 ++++++++ thunder.info.yml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f6899bab..989a9c641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [7.3.0](https://github.com/thunder/thunder-distribution/tree/7.1.0) 2024-06-024 + +[Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.2.2...7.3.0) + +* Drupal 10.3 compatibility. +* Updated Gin theme. +* PHP8.3 compatibility. + ## [7.2.2](https://github.com/thunder/thunder-distribution/tree/7.2.2) 2024-04-30 [Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.2.1...7.2.2) diff --git a/thunder.info.yml b/thunder.info.yml index dc6ee3f67..8e024d289 100644 --- a/thunder.info.yml +++ b/thunder.info.yml @@ -3,7 +3,7 @@ type: profile description: 'The Drupal based CMS for professional publishing.' project: thunder core_version_requirement: ~10.3.0 -version: '7.2.2' +version: '7.3.0' distribution: name: Thunder From 483d60f357aec9ab76b3a3a9c18c6e048d210a5f Mon Sep 17 00:00:00 2001 From: Volker Killesreiter Date: Tue, 6 Aug 2024 14:14:00 +0200 Subject: [PATCH 10/18] Add password policy patch to fix password reset (#825) --- README.md | 2 +- composer.json | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0569bc307..35e66e0a9 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ For general help using Thunder, please refer to [the official Thunder documentat ### Community support -For additional help, you can use one of this channel to ask question: +For additional help, you can use one of these channels to ask question: * [Slack](https://thunder.org/contact-us) (highly recommended for faster support) * [Twitter](https://twitter.com/ThunderCoreTeam) diff --git a/composer.json b/composer.json index f54ca7e7e..7d0c2afd5 100644 --- a/composer.json +++ b/composer.json @@ -40,6 +40,9 @@ }, "drupal/diff": { "Back button for comparison page": "https://www.drupal.org/files/issues/back_button_for-2853193-4.patch" + }, + "drupal/password_policy": { + "Issue #3465364: Fatal error when changing password when password_policy_history is enabled": "https://www.drupal.org/files/issues/2024-08-05/3465364-1.patch" } } }, @@ -85,7 +88,7 @@ "drupal/paragraphs": "^1.12", "drupal/paragraphs_features": "^2.0.0-beta3", "drupal/paragraphs_paste": "^2.0-beta3", - "drupal/password_policy": "^4.0", + "drupal/password_policy": "4.0.2", "drupal/pathauto": "^1.11", "drupal/responsive_preview": "^2.1", "drupal/redirect": "^1.7", From acb8950247e2c31a78a9161498d26aa7c595aaec Mon Sep 17 00:00:00 2001 From: Volker Killesreiter Date: Tue, 6 Aug 2024 16:07:14 +0200 Subject: [PATCH 11/18] Fix checkbox problem in firefox (#824) --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index 7d0c2afd5..a5d402f6a 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,9 @@ "drupal/diff": { "Back button for comparison page": "https://www.drupal.org/files/issues/back_button_for-2853193-4.patch" }, + "drupal/gin": { + "Issue #3455558: There is no visible change to a toggle when pressed (but it does trigger conditional fields, value is saved, etc)": "https://www.drupal.org/files/issues/2024-08-06/3455558-Refactor-toggle-styles-mr438.patch" + }, "drupal/password_policy": { "Issue #3465364: Fatal error when changing password when password_policy_history is enabled": "https://www.drupal.org/files/issues/2024-08-05/3465364-1.patch" } From f526e4ee4ed3a1726ca9813f227ba06544cca486 Mon Sep 17 00:00:00 2001 From: Volker Killesreiter Date: Tue, 6 Aug 2024 16:15:37 +0200 Subject: [PATCH 12/18] Issue #3466311: Release Thunder 7.3.1 --- CHANGELOG.md | 9 +++++++++ thunder.info.yml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 989a9c641..b97f5302a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [7.3.1](https://github.com/thunder/thunder-distribution/tree/7.3.1) 2024-06-024 + +[Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.3.0...7.3.1) + +Add patches for upstream issues. + +* [Issue #3465364: Fatal error when changing password when password_policy_history is enabled](https://www.drupal.org/project/password_policy/issues/3465364) +* [Issue #3455558: There is no visible change to a toggle when pressed (but it does trigger conditional fields, value is saved, etc)](https://www.drupal.org/project/gin/issues/3455558) + ## [7.3.0](https://github.com/thunder/thunder-distribution/tree/7.1.0) 2024-06-024 [Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.2.2...7.3.0) diff --git a/thunder.info.yml b/thunder.info.yml index 8e024d289..9d3c25a4e 100644 --- a/thunder.info.yml +++ b/thunder.info.yml @@ -3,7 +3,7 @@ type: profile description: 'The Drupal based CMS for professional publishing.' project: thunder core_version_requirement: ~10.3.0 -version: '7.3.0' +version: '7.3.1' distribution: name: Thunder From 8ee0c941d5ee2cb1989cd610bc7677aa14dc8925 Mon Sep 17 00:00:00 2001 From: Volker Killesreiter Date: Wed, 14 Aug 2024 14:12:41 +0200 Subject: [PATCH 13/18] Fix Testing --- .github/workflows/{test.yml => tests.yml} | 8 ++++---- composer.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) rename .github/workflows/{test.yml => tests.yml} (99%) diff --git a/.github/workflows/test.yml b/.github/workflows/tests.yml similarity index 99% rename from .github/workflows/test.yml rename to .github/workflows/tests.yml index b2a699ae0..8dec3a546 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/tests.yml @@ -38,7 +38,7 @@ jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 services: mysql: @@ -106,7 +106,7 @@ jobs: test-max: needs: build - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 services: mysql: @@ -170,7 +170,7 @@ jobs: test-upgrade: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 services: mysql: @@ -281,7 +281,7 @@ jobs: test-min: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 services: mysql: diff --git a/composer.json b/composer.json index a5d402f6a..cff7bf130 100644 --- a/composer.json +++ b/composer.json @@ -67,7 +67,7 @@ "drupal/diff": "1.7", "drupal/dropzonejs": "^2.8", "drupal/empty_fields": "^1.0-alpha1", - "drupal/entity_reference_actions": "^1.1", + "drupal/entity_reference_actions": "^1.1.1", "drupal/entity_reference_revisions": "^1.3", "drupal/field_group": "^3.4", "drupal/focal_point": "^2.1", @@ -84,7 +84,7 @@ "drupal/media_entity_slideshow": "^2.0-alpha1", "drupal/media_entity_twitter": "^2.5", "drupal/media_expire": "^2.6", - "drupal/media_library_media_modify": "^1.0.0-beta16", + "drupal/media_library_media_modify": "^1.0.0", "drupal/media_file_delete": "^1.2", "drupal/metatag": "^1.26", "drupal/metatag_async_widget": "^1.0-alpha2", From ef206e4e042a0c18d70e00dd0e92e830811b3cbf Mon Sep 17 00:00:00 2001 From: Volker Killesreiter Date: Wed, 14 Aug 2024 15:50:18 +0200 Subject: [PATCH 14/18] Add focal_point patch from #3462165 --- composer.json | 3 +++ .../Integration/FocalPointTest.php | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/src/FunctionalJavascript/Integration/FocalPointTest.php diff --git a/composer.json b/composer.json index cff7bf130..b14b9f3c9 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,9 @@ "drupal/diff": { "Back button for comparison page": "https://www.drupal.org/files/issues/back_button_for-2853193-4.patch" }, + "drupal/focal_point": { + "Issue #3462165: Preview results in Error: Call to a member function getDefinitions() on null": "https://www.drupal.org/files/issues/2024-07-18/Preview-results-in-Error-3462165.patch" + }, "drupal/gin": { "Issue #3455558: There is no visible change to a toggle when pressed (but it does trigger conditional fields, value is saved, etc)": "https://www.drupal.org/files/issues/2024-08-06/3455558-Refactor-toggle-styles-mr438.patch" }, diff --git a/tests/src/FunctionalJavascript/Integration/FocalPointTest.php b/tests/src/FunctionalJavascript/Integration/FocalPointTest.php new file mode 100644 index 000000000..cfa49561d --- /dev/null +++ b/tests/src/FunctionalJavascript/Integration/FocalPointTest.php @@ -0,0 +1,25 @@ +loadNodeByUuid('0bd5c257-2231-450f-b4c2-ab156af7b78d'); + $this->drupalGet($node->toUrl('edit-form')); + $this->clickDrupalSelector('edit-field-teaser-media-selection-0-edit'); + $this->clickDrupalSelector('edit-field-image-0-preview-preview-link'); + + $this->assertSession()->elementExists('css', '#focal-point-derivatives .focal-point-derivative-preview-image'); + $this->assertSession()->elementExists('css', '.focal-point-original-image > #focal-point-preview-image'); + } + +} From 662fc95c680d90d3720baca60d5f3cec5bdc528a Mon Sep 17 00:00:00 2001 From: Daniel Bosen Date: Wed, 14 Aug 2024 17:01:32 +0200 Subject: [PATCH 15/18] Issue #3468098 by daniel.bosen, volkerk: Release Thunder 7.3.2 --- CHANGELOG.md | 6 ++++++ composer.json | 2 +- thunder.info.yml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b97f5302a..1f71ebe97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [7.3.2](https://github.com/thunder/thunder-distribution/tree/7.3.2) 2024-08-14 + +[Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.3.1...7.3.2) + +* [Issue #3462165: Add focal_point patch](https://www.drupal.org/node/3462165) + ## [7.3.1](https://github.com/thunder/thunder-distribution/tree/7.3.1) 2024-06-024 [Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.3.0...7.3.1) diff --git a/composer.json b/composer.json index b14b9f3c9..7ad849466 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,7 @@ "drupal/entity_reference_actions": "^1.1.1", "drupal/entity_reference_revisions": "^1.3", "drupal/field_group": "^3.4", - "drupal/focal_point": "^2.1", + "drupal/focal_point": "2.1.1", "drupal/facets": "^2.0.6", "drupal/gin": "3.0-rc11", "drupal/gin_toolbar": "^1.0-rc6", diff --git a/thunder.info.yml b/thunder.info.yml index 9d3c25a4e..a69fe0a75 100644 --- a/thunder.info.yml +++ b/thunder.info.yml @@ -3,7 +3,7 @@ type: profile description: 'The Drupal based CMS for professional publishing.' project: thunder core_version_requirement: ~10.3.0 -version: '7.3.1' +version: '7.3.2' distribution: name: Thunder From 7c83a0d1034189089f53668edcce70b8bdb7b595 Mon Sep 17 00:00:00 2001 From: Daniel Bosen Date: Thu, 22 Aug 2024 15:16:32 +0200 Subject: [PATCH 16/18] GraphQL query for Search API --- .../graphql/thunder_menu.base.graphqls | 1 - .../graphql/thunder_search_api.base.graphqls | 4 + .../thunder_search_api.extension.graphqls | 0 .../GraphQL/Buffers/SearchApiResultBuffer.php | 101 +++++++ .../GraphQL/DataProducer/EntitiesWithTerm.php | 3 +- .../DataProducer/ThunderEntityList.php | 3 +- .../ThunderEntityListProducerBase.php | 82 +++++- .../GraphQL/DataProducer/ThunderSearchApi.php | 122 ++++++++ .../ThunderSearchApiProducerBase.php | 181 ++++++++++++ .../ThunderSearchApiSchemaExtension.php | 39 +++ .../src/Traits/ResolverHelperTrait.php | 5 +- .../src/Wrappers/EntityListResponse.php | 50 +++- .../src/Wrappers/SearchApiResponse.php | 273 ++++++++++++++++++ .../Wrappers/SearchApiResponseInterface.php | 18 ++ .../DataProducer/ThunderSearchApiTest.php | 85 ++++++ .../thunder_gqls/thunder_gqls.services.yml | 12 + phpstan-baseline.neon | 60 ---- phpstan.neon | 7 +- 18 files changed, 955 insertions(+), 91 deletions(-) create mode 100644 modules/thunder_gqls/graphql/thunder_search_api.base.graphqls create mode 100644 modules/thunder_gqls/graphql/thunder_search_api.extension.graphqls create mode 100644 modules/thunder_gqls/src/GraphQL/Buffers/SearchApiResultBuffer.php create mode 100644 modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApi.php create mode 100644 modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApiProducerBase.php create mode 100644 modules/thunder_gqls/src/Plugin/GraphQL/SchemaExtension/ThunderSearchApiSchemaExtension.php create mode 100644 modules/thunder_gqls/src/Wrappers/SearchApiResponse.php create mode 100644 modules/thunder_gqls/src/Wrappers/SearchApiResponseInterface.php create mode 100644 modules/thunder_gqls/tests/src/Functional/DataProducer/ThunderSearchApiTest.php create mode 100644 modules/thunder_gqls/thunder_gqls.services.yml diff --git a/modules/thunder_gqls/graphql/thunder_menu.base.graphqls b/modules/thunder_gqls/graphql/thunder_menu.base.graphqls index a61951f9a..eadd9339d 100644 --- a/modules/thunder_gqls/graphql/thunder_menu.base.graphqls +++ b/modules/thunder_gqls/graphql/thunder_menu.base.graphqls @@ -1,7 +1,6 @@ type Menu { id: String! name: String! - items: [MenuItem] } diff --git a/modules/thunder_gqls/graphql/thunder_search_api.base.graphqls b/modules/thunder_gqls/graphql/thunder_search_api.base.graphqls new file mode 100644 index 000000000..29db90559 --- /dev/null +++ b/modules/thunder_gqls/graphql/thunder_search_api.base.graphqls @@ -0,0 +1,4 @@ +type SearchApiResult { + items: [Page!] + total: Int! +} diff --git a/modules/thunder_gqls/graphql/thunder_search_api.extension.graphqls b/modules/thunder_gqls/graphql/thunder_search_api.extension.graphqls new file mode 100644 index 000000000..e69de29bb diff --git a/modules/thunder_gqls/src/GraphQL/Buffers/SearchApiResultBuffer.php b/modules/thunder_gqls/src/GraphQL/Buffers/SearchApiResultBuffer.php new file mode 100644 index 000000000..354dfa53f --- /dev/null +++ b/modules/thunder_gqls/src/GraphQL/Buffers/SearchApiResultBuffer.php @@ -0,0 +1,101 @@ +entityTypeManager = $entityTypeManager; + } + + /** + * Add an item to the buffer. + * + * @param string|int|null $index + * The entity type of the given entity ids. + * @param array|int $id + * The entity id(s) to load. + * + * @return \Closure + * The callback to invoke to load the result for this buffer item. + */ + public function add($index, $id) { + $item = new \ArrayObject([ + 'index' => $index, + 'id' => $id, + ]); + + return $this->createBufferResolver($item); + } + + /** + * {@inheritdoc} + */ + protected function getBufferId($item) { + return $item['index']; + } + + /** + * {@inheritdoc} + */ + public function resolveBufferArray(array $buffer) { + $index = reset($buffer)['index']; + $ids = array_map(function (\ArrayObject $item) { + return (array) $item['id']; + }, $buffer); + + $ids = call_user_func_array('array_merge', $ids); + $ids = array_values(array_unique($ids)); + + // Load the buffered entities. + /** @var \Drupal\search_api\IndexInterface $index */ + $index = $this->entityTypeManager + ->getStorage('search_api_index') + ->load($index); + + $resultSet = $index->loadItemsMultiple($ids); + $entities = []; + + foreach ($resultSet as $key => $resultItem) { + if ($resultItem instanceof EntityAdapter) { + $entities[$key] = $resultItem->getEntity(); + } + } + + return array_map(function ($item) use ($entities) { + if (is_array($item['id'])) { + return array_reduce($item['id'], static function ($carry, $current) use ($entities) { + if (!empty($entities[$current])) { + $carry[] = $entities[$current]; + return $carry; + } + + return $carry; + }, []); + } + + return $entities[$item['id']] ?? NULL; + }, $buffer); + } + +} diff --git a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/EntitiesWithTerm.php b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/EntitiesWithTerm.php index 8788b2539..9ac9953ae 100644 --- a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/EntitiesWithTerm.php +++ b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/EntitiesWithTerm.php @@ -4,7 +4,6 @@ use Drupal\graphql\GraphQL\Execution\FieldContext; use Drupal\taxonomy\TermInterface; -use Drupal\thunder_gqls\Wrappers\EntityListResponse; use Drupal\thunder_gqls\Wrappers\EntityListResponseInterface; /** @@ -119,7 +118,7 @@ public function resolve(TermInterface $term, string $type, array $bundles, strin $cacheContext ); - return new EntityListResponse($query); + return $this->entityListResponse($query); } /** diff --git a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityList.php b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityList.php index 3afcc2965..43ea0aa03 100644 --- a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityList.php +++ b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityList.php @@ -3,7 +3,6 @@ namespace Drupal\thunder_gqls\Plugin\GraphQL\DataProducer; use Drupal\graphql\GraphQL\Execution\FieldContext; -use Drupal\thunder_gqls\Wrappers\EntityListResponse; use Drupal\thunder_gqls\Wrappers\EntityListResponseInterface; /** @@ -97,7 +96,7 @@ protected function resolve(string $type, array $bundles, int $offset, int $limit $cacheContext ); - return new EntityListResponse($query); + return $this->entityListResponse($query); } } diff --git a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityListProducerBase.php b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityListProducerBase.php index 610700ab2..c2ad6bbe8 100644 --- a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityListProducerBase.php +++ b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityListProducerBase.php @@ -2,12 +2,13 @@ namespace Drupal\thunder_gqls\Plugin\GraphQL\DataProducer; -use Drupal\Core\Entity\EntityTypeManager; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\Query\QueryInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; use Drupal\graphql\GraphQL\Execution\FieldContext; use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase; +use Drupal\thunder_gqls\Wrappers\EntityListResponse; use GraphQL\Error\UserError; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -21,32 +22,43 @@ abstract class ThunderEntityListProducerBase extends DataProducerPluginBase impl /** * The entity type manager service. * - * @var \Drupal\Core\Entity\EntityTypeManager + * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ - protected $entityTypeManager; + protected EntityTypeManagerInterface $entityTypeManager; /** * The current user. * * @var \Drupal\Core\Session\AccountInterface */ - protected $currentUser; + protected AccountInterface $currentUser; + + /** + * The response wrapper service. + * + * @var \Drupal\thunder_gqls\Wrappers\EntityListResponse + */ + protected EntityListResponse $responseWrapper; /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self { - return new static( + $instance = new static( $configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'), $container->get('current_user') ); + + $instance->setResponseWrapper($container->get('thunder_gqls.entity_list_response_wrapper')); + + return $instance; } /** - * EntityLoad constructor. + * ThunderEntityListProducerBase constructor. * * @param array $configuration * The plugin configuration array. @@ -54,21 +66,51 @@ public static function create(ContainerInterface $container, array $configuratio * The plugin id. * @param array $pluginDefinition * The plugin definition array. - * @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager * The entity type manager service. - * @param \Drupal\Core\Session\AccountInterface $current_user + * @param \Drupal\Core\Session\AccountInterface $currentUser * The current user. */ public function __construct( array $configuration, string $pluginId, array $pluginDefinition, - EntityTypeManager $entityTypeManager, - AccountInterface $current_user, + EntityTypeManagerInterface $entityTypeManager, + AccountInterface $currentUser, ) { parent::__construct($configuration, $pluginId, $pluginDefinition); + $this->setEntityTypeManager($entityTypeManager); + $this->setCurrentUser($currentUser); + } + + /** + * Set the entity type manager service. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager service. + */ + public function setEntityTypeManager(EntityTypeManagerInterface $entityTypeManager): void { $this->entityTypeManager = $entityTypeManager; - $this->currentUser = $current_user; + } + + /** + * Set the current user. + * + * @param \Drupal\Core\Session\AccountInterface $currentUser + * The current user. + */ + public function setCurrentUser(AccountInterface $currentUser): void { + $this->currentUser = $currentUser; + } + + /** + * Set the response wrapper service. + * + * @param \Drupal\thunder_gqls\Wrappers\EntityListResponse $responseWrapper + * The response wrapper service. + */ + public function setResponseWrapper(EntityListResponse $responseWrapper): void { + $this->responseWrapper = $responseWrapper; } /** @@ -163,10 +205,7 @@ protected function query( $query->range($offset, $limit); $storage = $this->entityTypeManager->getStorage($type); - $entityType = $storage->getEntityType(); - - $cacheContext->addCacheTags($entityType->getListCacheTags()); - $cacheContext->addCacheContexts($entityType->getListCacheContexts()); + $cacheContext->addCacheableDependency($storage->getEntityType()); return $query; } @@ -202,4 +241,17 @@ protected function createPublishedCondition(string $type, array $conditions) { ]; } + /** + * The entity list response. + * + * @param \Drupal\Core\Entity\Query\QueryInterface $query + * The entity query. + * + * @return \Drupal\thunder_gqls\Wrappers\EntityListResponse + * The entity list response. + */ + protected function entityListResponse(QueryInterface $query): EntityListResponse { + return $this->responseWrapper->setQuery($query); + } + } diff --git a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApi.php b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApi.php new file mode 100644 index 000000000..d26ecc9c6 --- /dev/null +++ b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApi.php @@ -0,0 +1,122 @@ + 'status', + 'value' => TRUE, + 'operator' => '=', + ], + [ + 'field' => 'search_api_language', + 'value' => $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(), + 'operator' => '=', + ], + ]; + + // Add default sorts. + $sortBy = $sortBy ?: [ + [ + 'field' => 'search_api_relevance', + 'direction' => QueryInterface::SORT_DESC, + ], + ]; + + $query = $this->buildBaseQuery( + $limit, + $offset, + $index, + $sortBy, + $conditions, + $search, + $cacheContext + ); + + return $this->searchApiResponse($query); + } + +} diff --git a/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApiProducerBase.php b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApiProducerBase.php new file mode 100644 index 000000000..e568b6971 --- /dev/null +++ b/modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderSearchApiProducerBase.php @@ -0,0 +1,181 @@ +setEntityTypeManager($container->get('entity_type.manager')); + $instance->setLanguageManager($container->get('language_manager')); + $instance->setResponseWrapper($container->get('thunder_gqls.search_api_response_wrapper')); + + return $instance; + } + + /** + * Set the entity type manager service. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager service. + */ + public function setEntityTypeManager(EntityTypeManagerInterface $entityTypeManager): void { + $this->entityTypeManager = $entityTypeManager; + } + + /** + * Set the language manager service. + * + * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager + * The language manager service. + */ + public function setLanguageManager(LanguageManagerInterface $languageManager): void { + $this->languageManager = $languageManager; + } + + /** + * Set the response wrapper service. + * + * @param \Drupal\thunder_gqls\Wrappers\SearchApiResponse $responseWrapper + * The response wrapper service. + */ + public function setResponseWrapper(SearchApiResponse $responseWrapper): void { + $this->responseWrapper = $responseWrapper; + } + + /** + * Build base search api query. + * + * @param int $limit + * Limit of the query. + * @param int $offset + * Offset of the query. + * @param string $index + * Id of the search api index. + * @param array|null $sortBy + * List of sorts. + * @param array|null $conditions + * List of conditions to filter the result. + * @param string|null $search + * Query Search. + * @param \Drupal\graphql\GraphQL\Execution\FieldContext $cacheContext + * The caching context related to the current field. + * + * @return \Drupal\search_api\Query\QueryInterface|null + * The query interface. + * + * @throws \Drupal\search_api\SearchApiException + */ + protected function buildBaseQuery( + int $limit, + int $offset, + string $index, + ?array $sortBy, + ?array $conditions, + ?string $search, + FieldContext $cacheContext, + ): ?QueryInterface { + + // Make sure offset is zero or positive. + $offset = max($offset, 0); + + // Make sure limit is positive and cap the max items. + if ($limit <= 0) { + $limit = 10; + } + if ($limit > static::MAX_ITEMS) { + throw new UserError( + sprintf('Exceeded maximum query limit: %s.', static::MAX_ITEMS) + ); + } + + $searchIndex = Index::load($index); + if (!$searchIndex) { + return NULL; + } + + $query = $searchIndex->query(); + + foreach ($conditions as $condition) { + $query->addCondition($condition['field'], $condition['value'], $condition['operator']); + } + + foreach ($sortBy as $sort) { + $direction = $sort['direction'] ?? QueryInterface::SORT_ASC; + $query->sort($sort['field'], $direction); + } + + if (!empty($search)) { + $query->keys($search); + } + + $query->range($offset, $limit); + $cacheContext->addCacheableDependency($searchIndex); + + return $query; + } + + /** + * The search api response. + * + * @param \Drupal\search_api\Query\QueryInterface $query + * The search api query. + * + * @return \Drupal\thunder_gqls\Wrappers\SearchApiResponse + * The search api response. + */ + protected function searchApiResponse(QueryInterface $query): SearchApiResponse { + return $this->responseWrapper->setQuery($query); + } + +} diff --git a/modules/thunder_gqls/src/Plugin/GraphQL/SchemaExtension/ThunderSearchApiSchemaExtension.php b/modules/thunder_gqls/src/Plugin/GraphQL/SchemaExtension/ThunderSearchApiSchemaExtension.php new file mode 100644 index 000000000..dc9c2fbeb --- /dev/null +++ b/modules/thunder_gqls/src/Plugin/GraphQL/SchemaExtension/ThunderSearchApiSchemaExtension.php @@ -0,0 +1,39 @@ +addFieldResolverIfNotExists('SearchApiResult', 'total', + $this->builder->callback(function (SearchApiResponse $result) { + return $result->total(); + }) + ); + + $this->addFieldResolverIfNotExists('SearchApiResult', 'items', + $this->builder->callback(function (SearchApiResponse $result) { + return $result->items(); + }) + ); + } + +} diff --git a/modules/thunder_gqls/src/Traits/ResolverHelperTrait.php b/modules/thunder_gqls/src/Traits/ResolverHelperTrait.php index d09fbca9e..86d66c1e9 100644 --- a/modules/thunder_gqls/src/Traits/ResolverHelperTrait.php +++ b/modules/thunder_gqls/src/Traits/ResolverHelperTrait.php @@ -4,6 +4,7 @@ use Drupal\graphql\GraphQL\Resolver\ResolverInterface; use Drupal\graphql\GraphQL\ResolverBuilder; +use Drupal\graphql\GraphQL\ResolverRegistryInterface; /** * Helper functions for field resolvers. @@ -15,14 +16,14 @@ trait ResolverHelperTrait { * * @var \Drupal\graphql\GraphQL\ResolverBuilder */ - protected $builder; + protected ResolverBuilder $builder; /** * ResolverRegistryInterface. * * @var \Drupal\graphql\GraphQL\ResolverRegistryInterface */ - protected $registry; + protected ResolverRegistryInterface $registry; /** * Add field resolver to registry, if it does not already exist. diff --git a/modules/thunder_gqls/src/Wrappers/EntityListResponse.php b/modules/thunder_gqls/src/Wrappers/EntityListResponse.php index d2502ac23..4b25e5044 100644 --- a/modules/thunder_gqls/src/Wrappers/EntityListResponse.php +++ b/modules/thunder_gqls/src/Wrappers/EntityListResponse.php @@ -2,29 +2,66 @@ namespace Drupal\thunder_gqls\Wrappers; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\Query\QueryInterface; +use Drupal\graphql\GraphQL\Buffers\EntityBuffer; use GraphQL\Deferred; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * The thunder entity list response class. */ -class EntityListResponse implements EntityListResponseInterface { +class EntityListResponse implements EntityListResponseInterface, ContainerInjectionInterface { /** * The query interface. * * @var \Drupal\Core\Entity\Query\QueryInterface */ - protected $query; + protected QueryInterface $query; + + /** + * The entity buffer. + * + * @var \Drupal\graphql\GraphQL\Buffers\EntityBuffer + */ + protected EntityBuffer $buffer; /** * EntityListResponse constructor. * + * @param \Drupal\Core\Entity\Query\QueryInterface|\Drupal\graphql\GraphQL\Buffers\EntityBuffer $buffer + * The query or buffer parameter. + */ + public function __construct(QueryInterface|EntityBuffer $buffer) { + if ($buffer instanceof QueryInterface) { + // phpcs:ignore + @trigger_error('Calling the constructor with a query parameter is deprecated in Thunder 7.3.3 and will be removed in Thunder 8.0. Use service injection and ::setQuery() instead.', E_USER_DEPRECATED); + $this->setQuery($buffer); + // phpcs:ignore + $buffer = \Drupal::service('graphql.buffer.entity'); + } + $this->buffer = $buffer; + } + + /** + * {@inheritDoc} + */ + public static function create(ContainerInterface $container): self { + return new static( + $container->get('graphql.buffer.entity'), + ); + } + + /** + * Set query. + * * @param \Drupal\Core\Entity\Query\QueryInterface $query - * The query interface. + * The query. */ - public function __construct(QueryInterface $query) { + public function setQuery(QueryInterface $query): EntityListResponse { $this->query = $query; + return $this; } /** @@ -36,7 +73,7 @@ public function __construct(QueryInterface $query) { public function total(): int { $query = clone $this->query; $query->range(NULL, NULL)->count(); - return intval($query->execute()); + return (int) $query->execute(); } /** @@ -51,8 +88,7 @@ public function items() { return []; } - $buffer = \Drupal::service('graphql.buffer.entity'); - $callback = $buffer->add($this->query->getEntityTypeId(), array_values($result)); + $callback = $this->buffer->add($this->query->getEntityTypeId(), array_values($result)); return new Deferred(fn() => $callback()); } diff --git a/modules/thunder_gqls/src/Wrappers/SearchApiResponse.php b/modules/thunder_gqls/src/Wrappers/SearchApiResponse.php new file mode 100644 index 000000000..612c56d03 --- /dev/null +++ b/modules/thunder_gqls/src/Wrappers/SearchApiResponse.php @@ -0,0 +1,273 @@ +get('thunder_gqls.buffer.search_api_result'), + $container->get('entity_field.manager'), + ); + } + + /** + * Set query. + * + * @param \Drupal\search_api\Query\QueryInterface $query + * The query. + */ + public function setQuery(QueryInterface $query): SearchApiResponse { + $this->query = $query; + return $this; + } + + /** + * Set Facet mapping. + * + * @param array $facetMapping + * The facet mapping. + */ + public function setFacetMapping(array $facetMapping): SearchApiResponse { + $this->facetMapping = $facetMapping; + return $this; + } + + /** + * Set bundle. + * + * @param string $bundle + * The bundle. + */ + public function setBundle(string $bundle): SearchApiResponse { + $this->bundle = $bundle; + return $this; + } + + /** + * Set facets. + * + * @param array $facets + * The facets. + */ + public function setFacets(array $facets): SearchApiResponse { + $this->facets = $facets; + return $this; + } + + /** + * {@inheritdoc} + * + * @throws \Drupal\search_api\SearchApiException + */ + public function facets(): array { + if (!$this->facets || !$this->facetMapping) { + return []; + } + + if (!$this->result) { + $this->result = $this->query->execute(); + } + + $facets = []; + + $facetData = $this->result->getExtraData('search_api_facets'); + foreach ($facetData as $facetFieldId => $facetResults) { + $facets[] = [ + 'key' => $this->facetMapping[$facetFieldId], + 'values' => $this->processFacetResults($this->facets[$facetFieldId], $facetResults), + ]; + } + + return $facets; + } + + /** + * Get search result items. + * + * @return array|\GraphQL\Deferred + * The search result items. + * + * @throws \Drupal\search_api\SearchApiException + */ + public function items(): array|Deferred { + if (!$this->result) { + $this->result = $this->query->execute(); + } + + $ids = array_map(static function ($item) { + return $item->getId(); + }, $this->result->getResultItems()); + + $ids = array_unique($ids); + + if (empty($ids)) { + return []; + } + + $callback = $this->buffer->add( + $this->query->getIndex()->id(), + array_values($ids) + ); + + return new Deferred(function () use ($callback) { + return $callback(); + }); + } + + /** + * Returns the total results. + * + * @return int + * The total results. + * + * @throws \Drupal\search_api\SearchApiException + */ + public function total(): int { + $query = clone $this->query; + $query->range(0, NULL); + $result = $query->execute(); + + return (int) $result->getResultCount(); + } + + /** + * Handles processing of facet values. + * + * @param \Drupal\facets\Entity\Facet $facet + * The facet to process. + * @param array $facetResults + * The facet results. + * + * @return array + * The processed facet results. + */ + private function processFacetResults( + Facet $facet, + array $facetResults, + ): array { + // First process facet results which contain filter like filter=""9"". + // @see Drupal\facets\Plugin\facets\query_type\SearchApiString#build(). + foreach ($facetResults as $i => $facetResult) { + $facetResult['filter'] = $facetResult['filter'] ?? ''; + + if ($facetResult['filter'][0] === '"') { + $facetResult['filter'] = substr($facetResult['filter'], 1); + } + if ($facetResult['filter'][strlen($facetResult['filter']) - 1] === '"') { + $facetResult['filter'] = substr($facetResult['filter'], 0, -1); + } + + $facetResults[$i] = $facetResult; + } + + return $this->processFacetResultsFromFieldConfig($facet, $facetResults); + } + + /** + * Populates label for facet values from allowed options field config. + * + * @param \Drupal\facets\Entity\Facet $facet + * The facet. + * @param array $facetResults + * The facet results. + * + * @return array + * The processed facet results. + */ + private function processFacetResultsFromFieldConfig( + Facet $facet, + array $facetResults, + ): array { + if (!$this->bundle) { + return $facetResults; + } + + $fieldName = $facet->getFieldIdentifier(); + $fieldConfig = $this->entityFieldManager->getFieldDefinitions('node', $this->bundle); + + if (isset($fieldConfig[$fieldName])) { + $allowedValues = options_allowed_values($fieldConfig[$fieldName]->getFieldStorageDefinition()); + + // Use order of allowedValues. + foreach ($facetResults as $key => $facetResult) { + $facetResults[$key]['label'] = $allowedValues[$facetResult['filter']] ?? $facetResult['filter']; + $facetResults[$key]['value'] = $facetResult['filter']; + } + + $allowedValueKeys = array_keys($allowedValues); + usort($facetResults, function ($a, $b) use ($allowedValueKeys) { + $indexA = array_search($a['filter'], $allowedValueKeys, TRUE); + $indexB = array_search($b['filter'], $allowedValueKeys, TRUE); + + return $indexA < $indexB ? -1 : 1; + }); + } + + return $facetResults; + } + +} diff --git a/modules/thunder_gqls/src/Wrappers/SearchApiResponseInterface.php b/modules/thunder_gqls/src/Wrappers/SearchApiResponseInterface.php new file mode 100644 index 000000000..82d2158aa --- /dev/null +++ b/modules/thunder_gqls/src/Wrappers/SearchApiResponseInterface.php @@ -0,0 +1,18 @@ +logWithRole('administrator'); + + $this->drupalGet('admin/config/search/search-api/index/content'); + $this->submitForm([], 'Index now'); + $this->assertSession()->statusCodeEquals(200); + $this->checkForMetaRefresh(); + + $options = [ + 'index' => 'content', + 'search' => 'the', + 'limit' => 10, + 'offset' => 0, + ]; + + $result = $this->executeDataProducer('thunder_search_api', $options); + $this->assertEquals(3, $result->total()); + + $items = $result->items(); + $items->runQueue(); + $this->assertEquals('Burda Launches Open-Source CMS Thunder', $items->result[0]->getTitle()); + + // Change sort order. + $options['sortBy'] = [ + [ + 'field' => 'search_api_relevance', + 'direction' => QueryInterface::SORT_ASC, + ], + ]; + + $this->container->get('kernel')->rebuildContainer(); + $result = $this->executeDataProducer('thunder_search_api', $options); + + $items = $result->items(); + $items->runQueue(); + $this->assertEquals('Legal notice', $items->result[0]->getTitle()); + + // Get articles only. + $options['conditions'] = [ + [ + 'field' => 'type', + 'value' => 'article', + 'operator' => '=', + ], + ]; + + $this->container->get('kernel')->rebuildContainer(); + $result = $this->executeDataProducer('thunder_search_api', $options); + + $items = $result->items(); + $items->runQueue(); + $this->assertEquals('Come to DrupalCon New Orleans', $items->result[0]->getTitle()); + + } + +} diff --git a/modules/thunder_gqls/thunder_gqls.services.yml b/modules/thunder_gqls/thunder_gqls.services.yml new file mode 100644 index 000000000..863299712 --- /dev/null +++ b/modules/thunder_gqls/thunder_gqls.services.yml @@ -0,0 +1,12 @@ +services: + _defaults: + autowire: true + thunder_gqls.buffer.search_api_result: + class: Drupal\thunder_gqls\GraphQL\Buffers\SearchApiResultBuffer + Drupal\thunder_gqls\GraphQL\Buffers\SearchApiResultBuffer: '@thunder_gqls.buffer.search_api_result' + thunder_gqls.search_api_response_wrapper: + class: Drupal\thunder_gqls\Wrappers\SearchApiResponse + thunder_gqls.entity_list_response_wrapper: + autowire: false + class: Drupal\thunder_gqls\Wrappers\EntityListResponse + arguments: [ '@graphql.buffer.entity' ] diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 3fcf0a4db..576ad8cca 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,55 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_article/src/Form/NodeRevisionRevertDefaultForm.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_article/src/Plugin/Derivative/DynamicLocalTasks.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/EntityLinks.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/FocalPoint.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/MenuLinksActiveTrail.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/MetaTags.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntityListProducerBase.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderEntitySubRequestBase.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderImage.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_gqls/src/Plugin/GraphQL/DataProducer/ThunderRedirect.php - - message: "#^Access to an undefined property Drupal\\\\Core\\\\Entity\\\\ContentEntityInterface\\:\\:\\$field_teaser_media\\.$#" count: 1 @@ -70,11 +20,6 @@ parameters: count: 4 path: modules/thunder_gqls/tests/src/Kernel/DataProducer/EntityLinksTest.php - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: modules/thunder_taxonomy/src/ThunderTaxonomyPermissions.php - - message: "#^Access to an undefined property Drupal\\\\Core\\\\Entity\\\\EntityInterface\\:\\:\\$status\\.$#" count: 1 @@ -225,11 +170,6 @@ parameters: count: 1 path: tests/src/TestSuites/ThunderTestSuite.php - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 1 - path: tests/src/TestSuites/ThunderTestSuite.php - - message: "#^Call to method id\\(\\) on an unknown class Drupal\\\\entity_browser\\\\Entity\\\\EntityBrowser\\.$#" count: 1 diff --git a/phpstan.neon b/phpstan.neon index 654ea7304..a604bc45c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,8 +1,11 @@ parameters: customRulesetUsed: true - checkGenericClassInNonGenericObjectType: false - checkMissingIterableValueType: false reportUnmatchedIgnoredErrors: true level: 6 + ignoreErrors: + # new static() is a best practice in Drupal, so we cannot fix that. + - "#^Unsafe usage of new static#" + - identifier: missingType.generics + - identifier: missingType.iterableValue includes: - ./phpstan-baseline.neon From f6902baf9f399de9511dd829cbd233861b38fd4e Mon Sep 17 00:00:00 2001 From: Daniel Bosen Date: Thu, 22 Aug 2024 16:50:53 +0200 Subject: [PATCH 17/18] Issue #3469715 by volkerk: Release Thunder 7.3.3 --- CHANGELOG.md | 6 ++++++ composer.json | 11 ++++------- thunder.info.yml | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f71ebe97..1456541b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [7.3.3](https://github.com/thunder/thunder-distribution/tree/7.3.3) 2024-08-22 + +[Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.3.2...7.3.3) + +Add search api GraphQl schema and data producer. + ## [7.3.2](https://github.com/thunder/thunder-distribution/tree/7.3.2) 2024-08-14 [Full Changelog](https://github.com/thunder/thunder-distribution/compare/7.3.1...7.3.2) diff --git a/composer.json b/composer.json index 7ad849466..4a0390142 100644 --- a/composer.json +++ b/composer.json @@ -41,14 +41,11 @@ "drupal/diff": { "Back button for comparison page": "https://www.drupal.org/files/issues/back_button_for-2853193-4.patch" }, - "drupal/focal_point": { - "Issue #3462165: Preview results in Error: Call to a member function getDefinitions() on null": "https://www.drupal.org/files/issues/2024-07-18/Preview-results-in-Error-3462165.patch" - }, + "drupal/focal_point": { + "Issue #3462165: Preview results in Error: Call to a member function getDefinitions() on null": "https://www.drupal.org/files/issues/2024-07-18/Preview-results-in-Error-3462165.patch" + }, "drupal/gin": { "Issue #3455558: There is no visible change to a toggle when pressed (but it does trigger conditional fields, value is saved, etc)": "https://www.drupal.org/files/issues/2024-08-06/3455558-Refactor-toggle-styles-mr438.patch" - }, - "drupal/password_policy": { - "Issue #3465364: Fatal error when changing password when password_policy_history is enabled": "https://www.drupal.org/files/issues/2024-08-05/3465364-1.patch" } } }, @@ -94,7 +91,7 @@ "drupal/paragraphs": "^1.12", "drupal/paragraphs_features": "^2.0.0-beta3", "drupal/paragraphs_paste": "^2.0-beta3", - "drupal/password_policy": "4.0.2", + "drupal/password_policy": "^4.0.3", "drupal/pathauto": "^1.11", "drupal/responsive_preview": "^2.1", "drupal/redirect": "^1.7", diff --git a/thunder.info.yml b/thunder.info.yml index a69fe0a75..0a166329a 100644 --- a/thunder.info.yml +++ b/thunder.info.yml @@ -3,7 +3,7 @@ type: profile description: 'The Drupal based CMS for professional publishing.' project: thunder core_version_requirement: ~10.3.0 -version: '7.3.2' +version: '7.3.3' distribution: name: Thunder From f6c24add09a1e8990dc1fd234b9ce6f6bc8a4fcb Mon Sep 17 00:00:00 2001 From: Volker Killesreiter Date: Mon, 2 Sep 2024 09:50:42 +0200 Subject: [PATCH 18/18] Upload test output --- .github/workflows/tests.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8dec3a546..17b425c78 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,6 +12,7 @@ on: env: DRUPAL_TESTING_COMPOSER_PROJECT: thunder/thunder-project DRUPAL_TESTING_COMPOSER_PROJECT_VERSION: "^4.0@stable" + DRUPAL_TESTING_CLEANUP: false DRUPAL_TESTING_DATABASE_USER: root DRUPAL_TESTING_DATABASE_PASSWORD: root DRUPAL_TESTING_TEST_DUMP_FILE: site-dump.tar.gz @@ -28,6 +29,7 @@ env: DRUPAL_TESTING_PARALLEL_TESTING: false MINK_DRIVER_ARGS_WEBDRIVER: '["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu","--headless", "--no-sandbox", "--disable-dev-shm-usage"]}}, "http://127.0.0.1:9515"]' SIMPLETEST_BASE_URL: http://thunder-testing:8888 + BROWSERTEST_OUTPUT_DIRECTORY: /tmp SKIP_TEST_CLEANUP: true # The following variable set the version that the upgrade test starts with. DRUPAL_TESTING_UPGRADE_COMPOSER_PROJECT_VERSION: 3.0.12 @@ -168,6 +170,13 @@ jobs: THUNDER_TEST_CHUNK: ${{ matrix.CHUNK }} DRUPAL_TESTING_TEST_PATH: /tmp/test/thunder/install/docroot/profiles/contrib/thunder/tests/src/TestSuites/ThunderTestSuite.php + - name: Upload test output + uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: text-max-output-${{ matrix.CHUNK }}-${{ matrix.PHP_VERSION }} + path: /tmp/test/thunder/install/docroot/sites/simpletest/browser_output/ + test-upgrade: runs-on: ubuntu-24.04