From e89145d4c95c379f60ffa690b8913fc28e68255b Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 23 Aug 2024 14:20:21 +0200 Subject: [PATCH 001/149] ISAICP-8996: Dutch catalogue. --- web/modules/custom/eu_oss_catalogue/README.md | 5 + .../Provider/DutchCatalogue.php | 215 ++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php diff --git a/web/modules/custom/eu_oss_catalogue/README.md b/web/modules/custom/eu_oss_catalogue/README.md index 94dfaba69c..707441975f 100644 --- a/web/modules/custom/eu_oss_catalogue/README.md +++ b/web/modules/custom/eu_oss_catalogue/README.md @@ -245,6 +245,11 @@ Run the following, to fetch from ./vendor/bin/drush eu-oss:fetch hosting_platform:code_europa_eu ``` +Run the following, to fetch from +Dutch catalogue onboarding +```bash +./vendor/bin/drush eu-oss:fetch dutch_catalogue + This command queries the Developers Italia provider endpoint, fetches the data and populates the queue. Later, the cronjob is triggering the queue worker which is gradually creating or updating the OSS Solutions. diff --git a/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php new file mode 100644 index 0000000000..68bbff45f6 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php @@ -0,0 +1,215 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_catalogue\Plugin\eu_oss_catalogue\Provider; + +use Drupal\Component\Serialization\Json; +use Drupal\Core\Logger\LoggerChannelInterface; +use Drupal\eu_oss_catalogue\ApiGuesserInterface; +use Drupal\eu_oss_catalogue\EuOssCataloguePluginManagerInterface; +use Drupal\eu_oss_catalogue\EuOssCatalogueProviderPluginBase; +use Drupal\eu_oss_catalogue\Exception\HostingPlatformFetchException; +use Drupal\eu_oss_catalogue\Exception\ProviderFetchException; +use Drupal\eu_oss_catalogue\Model\Project; +use GuzzleHttp\Client; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Dutch catalogue provider. + * + * @EuOssCatalogueProvider( + * id = "dutch_catalogue", + * label = @Translation("Dutch catalogue"), + * description = @Translation("Dutch catalogue onboarding."), + * parser = "publiccode_yml", + * ) + */ +class DutchCatalogue extends EuOssCatalogueProviderPluginBase { + + /** + * Developers Italia API endpoint. + * + * @var string + */ + protected const string ENDPOINT = 'https://gist.githubusercontent.com/dvh/95a09cf9df9b4567c256c188a0e8f4b2/raw'; + + /** + * List of projects fetched from Developers Italia API. + * + * @var array[][] + * A list of fetched projects keyed by the coding platform base URL. The + * values are associative arrays keyed by namespace and having a list of + * project IDs as values. + */ + protected array $fetched; + + /** + * Fetched URLs collector. + */ + protected array $fetchedUrls = []; + + /** + * Processed URLs collector. + */ + protected array $processedUrls = []; + + /** + * Number of solutions provided by API. + * + * @var int + */ + protected int $numberOfProvidedSolutions = 0; + + public function __construct( + array $configuration, + $pluginId, + $pluginDefinition, + protected EuOssCataloguePluginManagerInterface $parserManager, + protected LoggerChannelInterface $logger, + protected Client $httpClient, + protected EuOssCataloguePluginManagerInterface $platformManager, + protected ApiGuesserInterface $apiGuesser, + ) { + parent::__construct($configuration, $pluginId, $pluginDefinition, $parserManager, $logger); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition): self { + return new static( + $configuration, + $pluginId, + $pluginDefinition, + $container->get('plugin.manager.eu_oss_catalogue.parser'), + $container->get('logger.channel.eu_oss_catalogue'), + $container->get('http_client'), + $container->get('plugin.manager.eu_oss_catalogue.hosting_platform'), + $container->get('eu_oss_catalogue.git_remote.api_guesser'), + ); + } + + /** + * {@inheritdoc} + */ + public function fetch(): iterable { + if (!isset($this->fetched)) { + $this->getData(); + } + + $collectedExceptions = []; + foreach ($this->fetched as $baseUrl => $namespaces) { + // Remove this entry to avoid fetching again on the next iteration. + unset($this->fetched[$baseUrl]); + + $platformConfig = [ + 'baseUrl' => $baseUrl, + 'projects' => $namespaces['projects'], + ]; + /** @var \Drupal\eu_oss_catalogue\EuOssCatalogueHostingPlatformInterface $hostingPlatform */ + $hostingPlatform = $this->platformManager->createInstance($namespaces['api']->pluginId, $platformConfig); + + /** @var \Drupal\eu_oss_catalogue\Model\Project $project */ + try { + foreach ($hostingPlatform->getProjects([ + 'publiccodeYml' => 'publiccode.yml', + 'publiccodeYaml' => 'publiccode.yaml', + ]) as $project) { + $this->processedUrls[] = $project->url; + + // Try to use "publiccode.yaml". + if (isset($project->files['publiccodeYaml'])) { + $values = $project->toArray(); + $values['files']['publiccodeYml'] = $values['files']['publiccodeYaml']; + unset ($values['files']['publiccodeYaml']); + yield new Project(...$values); + continue; + } + + yield $project; + } + } + catch (HostingPlatformFetchException $exception) { + // Collect provider fetch exceptions, and throw them at the end of the + // fetch operation. + $collectedExceptions[] = $exception->getMessage(); + } + + // Only log when all solutions were processed. + if (empty($this->fetched)) { + $this->logResults(); + } + } + + if (!empty($collectedExceptions)) { + throw new ProviderFetchException(implode(PHP_EOL, $collectedExceptions)); + } + } + + /** + * Gets data. + * + * @throws \Drupal\eu_oss_catalogue\Exception\ProviderFetchException + */ + protected function getData(): void { + $this->fetched = []; + try { + $response = $this->httpClient->get(static::ENDPOINT); + + // Fix not valid data. + $responseData = str_replace('""publiccode_url":', '", "publiccode_url":', (string) $response->getBody()); + $responseData = Json::decode($responseData); + } + catch (\Exception $exception) { + throw new ProviderFetchException( + $exception->getMessage() + ); + } + + $this->numberOfProvidedSolutions = count($responseData); + foreach ($responseData as $row) { + $required = ['url', 'owner_name', 'name', 'publiccode_url']; + foreach ($required as $field) { + if (empty($row[$field])) { + $this->logger->error('Lacks the mandatory @field in @row', [ + '@field' => $row[$field], + '@row' => print_r($row, TRUE), + ]); + continue 2; + } + } + + if (!$api = $this->apiGuesser->getHostingPlatformApi($row['url'])) { + $this->logger->error('Can\'t determinate hosting platform for @repository repository', + ['@repository' => $row['url']]); + continue; + } + + $this->fetched[$api->baseUrl]['api'] = $api; + $this->fetched[$api->baseUrl]['projects'][$row['owner_name']][] = $row['name']; + $this->fetchedUrls[] = $row['url']; + } + } + + /** + * Logs statistics about fetched and processed OSS Solutions. + */ + protected function logResults(): void { + if ($unProcessed = array_diff($this->fetchedUrls, $this->processedUrls)) { + $this->logger->warning('Processed @processed out of @fetched fetched solutions from Dutch catalogue. The following @unprocessed solutions failed: ' . implode(', ', $unProcessed), [ + '@processed' => count($this->processedUrls), + '@fetched' => $this->numberOfProvidedSolutions, + '@unprocessed' => count($unProcessed), + 'list' => $unProcessed, + ]); + } + else { + $this->logger->info('Processed @processed out of @fetched fetched solutions from Dutch catalogue.', [ + '@processed' => count($this->processedUrls), + '@fetched' => $this->numberOfProvidedSolutions, + ]); + } + } + +} -- GitLab From 391d1577f469d80b0a630ca2d698f8484ac78dd3 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 23 Aug 2024 14:21:07 +0200 Subject: [PATCH 002/149] ISAICP-8996: Impove coding standards. --- .../src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php index 68bbff45f6..ba4ba37a4c 100644 --- a/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php +++ b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php @@ -122,7 +122,7 @@ public function fetch(): iterable { if (isset($project->files['publiccodeYaml'])) { $values = $project->toArray(); $values['files']['publiccodeYml'] = $values['files']['publiccodeYaml']; - unset ($values['files']['publiccodeYaml']); + unset($values['files']['publiccodeYaml']); yield new Project(...$values); continue; } -- GitLab From 27188db2153cffa47c13a96b9680683f7edcfae4 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 26 Aug 2024 08:46:59 +0200 Subject: [PATCH 003/149] ISAICP-8996: Dutch catalogue mock service. --- .../http_response/dutch_catalogue.yml | 58 +++++++++++++++++++ .../src/Plugin/ServiceMock/DutchCatalogue.php | 48 +++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml create mode 100644 web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php diff --git a/web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml b/web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml new file mode 100644 index 0000000000..a19ad341b5 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml @@ -0,0 +1,58 @@ +data: + + - id: 3248 + source: github + owner_name: Amsterdam + name: signals-frontend + url: 'https://github.com/Amsterdam/signals-frontend' + description: 'Frontend of the SIA (Signalen Informatievoorziening Amsterdam)' + last_change: '2024-07-08T14:56:18.000Z' + stars: 8 + avatar_url: 'https://avatars.githubusercontent.com/u/14022058?v=4' + fork_count: 24 + issue_open_count: 0 + last_fetched_at: '2024-07-11T13:01:28.157Z' + merge_request_open_count: 15 + archived: false + organization_id: 15 + readme_url: '' + slug: 'amsterdam-signals-frontend-25698' + publiccode_url: 'https://github.com/Amsterdam/signals-frontend/blob/main/publiccode.yml' + + - id: 6011 + source: 'github' + owner_name: 'GemeenteNijmegen' + name: 'verwerkingenlogging', + url: 'https://github.com/GemeenteNijmegen/verwerkingenlogging' + description: 'Implementatie mbv IaC van de verwerkinglogging standaard' + last_change: '2024-07-11T00:05:41.000Z' + stars: 5 + avatar_url: 'https://avatars.githubusercontent.com/u/29945117?v=4' + fork_count: 0 + issue_open_count: 14 + last_fetched_at: '2024-07-11T13:22:46.916Z' + merge_request_open_count: 0 + archived: false + organization_id: 9 + readme_url: '' + slug: 'gemeentenijmegen-verwerkingenlogging-33391' + publiccode_url: 'https://github.com/GemeenteNijmegen/verwerkingenlogging/blob/main/publiccode.yaml' + + - id: 5967 + source: 'github' + owner_name: 'Haarlem' + name: 'zds-stuf-to-zgw-api-translator' + url: 'https://github.com/Haarlem/zds-stuf-to-zgw-api-translator' + description: 'This project is a proof of concept of a service that can translate StUF ZDS 1.2 SOAP messages to their corresponding ZGW 1.0 API calls.' + last_change: '2024-02-13T10:41:21.000Z' + stars: 0 + avatar_url: 'https://avatars.githubusercontent.com/u/15446184?v=4' + fork_count: 8 + issue_open_count: 1 + last_fetched_at: '2024-07-11T13:22:04.801Z' + merge_request_open_count: 4 + archived: false + organization_id: 8 + readme_url: '' + slug: 'haarlem-zds-stuf-to-zgw-api-translator-38688' + publiccode_url: 'https://github.com/Haarlem/zds-stuf-to-zgw-api-translator/blob/master/publiccode.yml' diff --git a/web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php b/web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php new file mode 100644 index 0000000000..65a9abf18f --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php @@ -0,0 +1,48 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_catalogue_test\Plugin\ServiceMock; + +use Drupal\Component\Serialization\Json; +use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Serialization\Yaml; +use Drupal\eu_oss_catalogue_test\IntegrationTestTrait; +use Drupal\http_request_mock\ServiceMockPluginInterface; +use GuzzleHttp\Psr7\Response; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Intercepts any HTTP requests made to Dutch catalogue API. + * + * @ServiceMock( + * id = "dutch_catalogue", + * label = @Translation("Dutch catalogue API"), + * weight = 0, + * ) + */ +class DutchCatalogue extends PluginBase implements ServiceMockPluginInterface { + + use IntegrationTestTrait; + + /** + * {@inheritdoc} + */ + public function applies(RequestInterface $request, array $options): bool { + return !$this->isIntegrationTest() && ($request->getUri() + ->getHost() === 'gist.githubusercontent.com'); + } + + /** + * {@inheritdoc} + */ + public function getResponse(RequestInterface $request, array $options): ResponseInterface { + $response = Json::encode(Yaml::decode(file_get_contents(__DIR__ . '/../../../../../fixtures/http_response/dutch_catalogue.yml'))); + return new Response(200, [ + 'Content-Type' => 'application/json', + 'Content-Length' => strlen($response), + ], $response); + } + +} -- GitLab From c4ed611eca5d14cdd056ed5ef535d8824d58186c Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 26 Aug 2024 10:51:38 +0200 Subject: [PATCH 004/149] ISAICP-8996: Add tests. --- .../Provider/DutchCatalogue.php | 2 +- .../DutchCatalogueFetchTest.testImport.yml | 169 ++++++++++++++++++ .../http_response/dutch_catalogue.yml | 110 ++++++------ .../Functional/DutchCatalogueFetchTest.php | 33 ++++ 4 files changed, 257 insertions(+), 57 deletions(-) create mode 100644 web/modules/custom/eu_oss_catalogue/tests/fixtures/expectancy/DutchCatalogueFetchTest.testImport.yml create mode 100644 web/modules/custom/eu_oss_catalogue/tests/src/Functional/DutchCatalogueFetchTest.php diff --git a/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php index ba4ba37a4c..16a467faee 100644 --- a/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php +++ b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php @@ -169,7 +169,7 @@ protected function getData(): void { $this->numberOfProvidedSolutions = count($responseData); foreach ($responseData as $row) { - $required = ['url', 'owner_name', 'name', 'publiccode_url']; + $required = ['url', 'owner_name', 'name']; foreach ($required as $field) { if (empty($row[$field])) { $this->logger->error('Lacks the mandatory @field in @row', [ diff --git a/web/modules/custom/eu_oss_catalogue/tests/fixtures/expectancy/DutchCatalogueFetchTest.testImport.yml b/web/modules/custom/eu_oss_catalogue/tests/fixtures/expectancy/DutchCatalogueFetchTest.testImport.yml new file mode 100644 index 0000000000..d3acde2281 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/tests/fixtures/expectancy/DutchCatalogueFetchTest.testImport.yml @@ -0,0 +1,169 @@ +GitHub solution 1: + en: + langcode: en + default_langcode: '1' + status: '1' + oss_available_languages: + - it + - en + - de + oss_categories: + - digital-citizenship + oss_development_status: stable + oss_git_url: https://github.com/dummy-namespace-1/dummy-name-1 + oss_license: AGPL-3.0-or-later + oss_logo: https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/images/logo-solution-1.png + oss_git_forks: 103 + oss_git_stars: 123 + oss_git_open_issues: 143 + oss_maintenance_contacts: + - Peter Gregory + oss_maintenance_contractors: + - ACME Ltd + - Das Auto GmbH + oss_maintenance_type: contract + oss_owner: Sin City + oss_platforms: + - web + oss_publiccode_yml_version: '0.2' + oss_release_date: '2017-05-01' + oss_software_type: standalone/web + oss_software_version: '1.4' + oss_source: + - dutch_catalogue + oss_source_hash: _RnRGlJcP5QA_tiadP_JTMJyyOypigHzRYjIY-LlQMM + oss_long_description: | + [EN] Solution 1: Long description + **Some bold text** + * Some list item + * Another list item + + _Some italic text_ + oss_short_description: '[EN] Solution 1: **Short description**' + oss_features: + - '[EN] Solution 1: Feature 1' + - '[EN] Solution 1: Feature 2' + - '[EN] Solution 1: Feature 3' + oss_screenshots: + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_EN_Screenshot1.jpg + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_EN_Screenshot2.jpg + oss_git_open_pull_requests: 3 + de: + langcode: de + default_langcode: '0' + oss_features: + - '[DE] Solution 1: Feature 1' + oss_long_description: | + [DE] Solution 1: Long description + **Some bold text** + * Some list item + * Another list item + + _Some italic text_ + oss_short_description: '[DE] Solution 1: **Short description**' + oss_screenshots: + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_DE_Screenshot1.jpg + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_DE_Screenshot3.jpg + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_DE_Screenshot4.jpg + it: + langcode: it + default_langcode: '0' + oss_features: + - '[IT] Solution 1: Feature 1' + - '[IT] Solution 1: Feature 2' + oss_long_description: | + [IT] Solution 1: Long description + **Some bold text** + * Some list item + * Another list item + + _Some italic text_ + oss_short_description: '[IT] Solution 1: **Short description**' + oss_screenshots: + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_IT_Screenshot1.jpg + +Project 1.1: + it: + langcode: it + default_langcode: '0' + oss_categories: + - data-collection + oss_git_url: https://limited.self-hosted.gitlab.example.com/group1/project-1-1 + oss_git_description: 'Group 1: Project 1: description' + oss_default_branch: branch-project-1-1 + oss_software_version: '2.0.0-alpha12' + oss_release_date: '2010-07-08' + oss_platform_reference: gid://gitlab/Project/11 + oss_logo: https://limited.self-hosted.gitlab.example.com/group1/project-1-1/raw/HEAD/images/logo-of-project-1-1.svg + oss_git_forks: 206 + oss_git_stars: 226 + oss_git_open_issues: 246 + oss_publiccode_yml_version: '0.2' + oss_documentation: https://example.com/group1/project-1-1/it/docs.md + oss_features: + - '[IT] feat 1' + - '[IT] feat 2' + - '[IT] feat 3' + oss_long_description: '[IT] Group1: Project 1: Long description' + oss_short_description: '[IT] Group1: Project 1: Short description' + oss_screenshots: + - 'https://limited.self-hosted.gitlab.example.com/group1/project-1-1/raw/HEAD/Group_1_Project1_IT_Screenshot.jpg' + oss_git_open_pull_requests: 32 + de: + langcode: de + oss_documentation: https://example.com/group1/project-1-1/de/docs.md + oss_features: + - '[DE] feat 1' + - '[DE] feat 2' + oss_long_description: '[DE] Group1: Project 1: Long description' + oss_short_description: '[DE] Group1: Project 1: Short description' + +Project 1.2: + de: + langcode: de + default_langcode: '0' + oss_categories: + - data-collection + - data-analytics + oss_git_url: https://limited.self-hosted.gitlab.example.com/group1/project-1-2 + oss_git_description: 'Group 1: Project 2: description' + oss_default_branch: branch-project-1-2 + oss_software_version: '220.0.1' + oss_release_date: '2013-08-19' + oss_platform_reference: gid://gitlab/Project/12 + oss_logo: https://all.self-hosted.gitlab.example.com/uploads/-/system/project/avatar/12/logo.jpg + oss_git_forks: 207 + oss_git_stars: 227 + oss_git_open_issues: 247 + oss_publiccode_yml_version: '0.2' + oss_documentation: https://example.com/group1/project-1-2/de/docs.md + oss_features: + - '[DE] feat 1' + - '[DE] feat 2' + oss_long_description: '[DE] Group1: Project 2: Long description' + oss_short_description: '[DE] Group1: Project 2: Short description' + oss_git_open_pull_requests: 2 + it: + langcode: it + default_langcode: '0' + oss_documentation: https://example.com/group1/project-1-2/it/docs.md + oss_features: + - '[IT] feat 1' + - '[IT] feat 2' + oss_long_description: '[IT] Group1: Project 2: Long description' + oss_short_description: '[IT] Group1: Project 2: Short description' + en: + langcode: en + default_langcode: '1' + oss_documentation: https://example.com/group1/project-1-2/en/docs.md + oss_features: + - '[EN] feat 1' + oss_long_description: '[EN] Group1: Project 2: Long description' + oss_short_description: '[EN] Group1: Project 2: Short description' + oss_used_by: + - 'Abbanoa' + - 'abbanoa' + - 'abbanoa ' + - 'Comune Di Malè' + - 'Comune Di Male' + - 'comune di male' diff --git a/web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml b/web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml index a19ad341b5..34c84b6776 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml +++ b/web/modules/custom/eu_oss_catalogue/tests/fixtures/http_response/dutch_catalogue.yml @@ -1,58 +1,56 @@ -data: +- id: 3248 + source: github + owner_name: dummy-namespace-1 + name: dummy-name-1 + url: 'https://github.com/dummy-namespace-1/dummy-name-1.git' + description: 'Frontend of the SIA (Signalen Informatievoorziening Amsterdam)' + last_change: '2024-07-08T14:56:18.000Z' + stars: 8 + avatar_url: 'https://avatars.githubusercontent.com/u/14022058?v=4' + fork_count: 24 + issue_open_count: 0 + last_fetched_at: '2024-07-11T13:01:28.157Z' + merge_request_open_count: 15 + archived: false + organization_id: 15 + readme_url: '' + slug: 'amsterdam-signals-frontend-25698' + publiccode_url: 'https://github.com/Amsterdam/signals-frontend/blob/main/publiccode.yml' - - id: 3248 - source: github - owner_name: Amsterdam - name: signals-frontend - url: 'https://github.com/Amsterdam/signals-frontend' - description: 'Frontend of the SIA (Signalen Informatievoorziening Amsterdam)' - last_change: '2024-07-08T14:56:18.000Z' - stars: 8 - avatar_url: 'https://avatars.githubusercontent.com/u/14022058?v=4' - fork_count: 24 - issue_open_count: 0 - last_fetched_at: '2024-07-11T13:01:28.157Z' - merge_request_open_count: 15 - archived: false - organization_id: 15 - readme_url: '' - slug: 'amsterdam-signals-frontend-25698' - publiccode_url: 'https://github.com/Amsterdam/signals-frontend/blob/main/publiccode.yml' +- id: 6011 + source: 'gitlab' + owner_name: 'group1' + name: 'project-1-1' + url: 'https://limited.self-hosted.gitlab.example.com/group1/project-1-1' + description: 'Implementatie mbv IaC van de verwerkinglogging standaard' + last_change: '2024-07-11T00:05:41.000Z' + stars: 5 + avatar_url: 'https://avatars.githubusercontent.com/u/29945117?v=4' + fork_count: 0 + issue_open_count: 14 + last_fetched_at: '2024-07-11T13:22:46.916Z' + merge_request_open_count: 0 + archived: false + organization_id: 9 + readme_url: '' + slug: 'gemeentenijmegen-verwerkingenlogging-33391' + publiccode_url: 'https://github.com/GemeenteNijmegen/verwerkingenlogging/blob/main/publiccode.yaml' - - id: 6011 - source: 'github' - owner_name: 'GemeenteNijmegen' - name: 'verwerkingenlogging', - url: 'https://github.com/GemeenteNijmegen/verwerkingenlogging' - description: 'Implementatie mbv IaC van de verwerkinglogging standaard' - last_change: '2024-07-11T00:05:41.000Z' - stars: 5 - avatar_url: 'https://avatars.githubusercontent.com/u/29945117?v=4' - fork_count: 0 - issue_open_count: 14 - last_fetched_at: '2024-07-11T13:22:46.916Z' - merge_request_open_count: 0 - archived: false - organization_id: 9 - readme_url: '' - slug: 'gemeentenijmegen-verwerkingenlogging-33391' - publiccode_url: 'https://github.com/GemeenteNijmegen/verwerkingenlogging/blob/main/publiccode.yaml' - - - id: 5967 - source: 'github' - owner_name: 'Haarlem' - name: 'zds-stuf-to-zgw-api-translator' - url: 'https://github.com/Haarlem/zds-stuf-to-zgw-api-translator' - description: 'This project is a proof of concept of a service that can translate StUF ZDS 1.2 SOAP messages to their corresponding ZGW 1.0 API calls.' - last_change: '2024-02-13T10:41:21.000Z' - stars: 0 - avatar_url: 'https://avatars.githubusercontent.com/u/15446184?v=4' - fork_count: 8 - issue_open_count: 1 - last_fetched_at: '2024-07-11T13:22:04.801Z' - merge_request_open_count: 4 - archived: false - organization_id: 8 - readme_url: '' - slug: 'haarlem-zds-stuf-to-zgw-api-translator-38688' - publiccode_url: 'https://github.com/Haarlem/zds-stuf-to-zgw-api-translator/blob/master/publiccode.yml' +- id: 5967 + source: 'gitlab' + owner_name: 'group1' + name: 'project-1-2' + url: 'https://limited.self-hosted.gitlab.example.com/group1/project-1-2' + description: 'This project is a proof of concept of a service that can translate StUF ZDS 1.2 SOAP messages to their corresponding ZGW 1.0 API calls.' + last_change: '2024-02-13T10:41:21.000Z' + stars: 0 + avatar_url: 'https://avatars.githubusercontent.com/u/15446184?v=4' + fork_count: 8 + issue_open_count: 1 + last_fetched_at: '2024-07-11T13:22:04.801Z' + merge_request_open_count: 4 + archived: false + organization_id: 8 + readme_url: '' + slug: 'haarlem-zds-stuf-to-zgw-api-translator-38688' + publiccode_url: 'https://github.com/Haarlem/zds-stuf-to-zgw-api-translator/blob/master/publiccode.yml' diff --git a/web/modules/custom/eu_oss_catalogue/tests/src/Functional/DutchCatalogueFetchTest.php b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/DutchCatalogueFetchTest.php new file mode 100644 index 0000000000..cac08da7c6 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/DutchCatalogueFetchTest.php @@ -0,0 +1,33 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\eu_oss_catalogue\Functional; + +/** + * EU OSS Catalogue test. + * + * @group eu_oss_catalogue + */ +class DutchCatalogueFetchTest extends FetchTestBase { + + /** + * {@inheritdoc} + */ + protected array $controlledVocabTerms = [ + 'oss_licence' => ['AGPL-3.0-or-later'], + 'oss_category' => ['digital-citizenship'], + ]; + + /** + * @covers + */ + public function testImport(): void { + $this->fetchSolutions('dutch_catalogue', 3); + + $this->assertOssSolution('GitHub solution 1', 'en'); + $this->assertOssSolution('Project 1.1', 'it'); + $this->assertOssSolution('Project 1.2', 'de'); + } + +} -- GitLab From 4d42c193036792cae1d5271704db74ef6ea468b5 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 26 Aug 2024 11:02:43 +0200 Subject: [PATCH 005/149] ISAICP-8996: Improve code. --- .../src/Plugin/ServiceMock/DutchCatalogue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php b/web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php index 65a9abf18f..12cdc0a507 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php +++ b/web/modules/custom/eu_oss_catalogue/tests/modules/eu_oss_catalogue_test/src/Plugin/ServiceMock/DutchCatalogue.php @@ -31,7 +31,7 @@ class DutchCatalogue extends PluginBase implements ServiceMockPluginInterface { */ public function applies(RequestInterface $request, array $options): bool { return !$this->isIntegrationTest() && ($request->getUri() - ->getHost() === 'gist.githubusercontent.com'); + ->getHost() === 'gist.githubusercontent.com'); } /** -- GitLab From 7595d557e7aedb339d5f73252535631fcb1ae823 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 28 Aug 2024 15:17:48 +0200 Subject: [PATCH 006/149] ISAICP-8691: Remove view_mode_featured. --- ...ay.node.custom_page.view_mode_featured.yml | 53 ------ ...lay.node.discussion.view_mode_featured.yml | 112 ------------ ...y.node.distribution.view_mode_featured.yml | 106 ------------ ...splay.node.document.view_mode_featured.yml | 87 ---------- ..._display.node.event.view_mode_featured.yml | 127 -------------- ...w_display.node.news.view_mode_featured.yml | 90 ---------- ...isplay.node.release.view_mode_featured.yml | 75 -------- ...lay.paragraph.entity_reference.default.yml | 2 +- ...f_entity.collection.view_mode_featured.yml | 103 ----------- ...rdf_entity.solution.view_mode_featured.yml | 163 ------------------ ...w_display.user.user.view_mode_featured.yml | 71 -------- ...tity_view_mode.node.view_mode_featured.yml | 13 -- ...iew_mode.rdf_entity.view_mode_featured.yml | 13 -- ...tity_view_mode.user.view_mode_featured.yml | 13 -- config/sync/views.view.in_the_spotlight.yml | 92 ---------- config/sync/views.view.members_overview.yml | 6 - .../templates/joinup-tiles.html.twig | 1 - .../node--glossary--view-mode-tile.html.twig | 5 +- 18 files changed, 4 insertions(+), 1128 deletions(-) delete mode 100644 config/sync/core.entity_view_display.node.custom_page.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.node.discussion.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.node.distribution.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.node.document.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.node.event.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.node.news.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.node.release.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.rdf_entity.collection.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.rdf_entity.solution.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_display.user.user.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_mode.node.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_mode.rdf_entity.view_mode_featured.yml delete mode 100644 config/sync/core.entity_view_mode.user.view_mode_featured.yml diff --git a/config/sync/core.entity_view_display.node.custom_page.view_mode_featured.yml b/config/sync/core.entity_view_display.node.custom_page.view_mode_featured.yml deleted file mode 100644 index 492eb12170..0000000000 --- a/config/sync/core.entity_view_display.node.custom_page.view_mode_featured.yml +++ /dev/null @@ -1,53 +0,0 @@ -uuid: 863328f4-1100-4fda-be49-605244e1aa36 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.node.view_mode_featured - - field.field.node.custom_page.field_attachment - - field.field.node.custom_page.field_custom_page_logo - - field.field.node.custom_page.field_hide_title - - field.field.node.custom_page.field_keywords - - field.field.node.custom_page.field_paragraphs_body - - field.field.node.custom_page.field_state - - field.field.node.custom_page.field_topic - - field.field.node.custom_page.og_audience - - node.type.custom_page - module: - - layout_paragraphs - - template_suggestion - - user -_core: - default_config_hash: DWb669UswawqVOlf5T9Ak9DOZ7EQRFXjnmhJMA9YpH4 -id: node.custom_page.view_mode_featured -targetEntityType: node -bundle: custom_page -mode: view_mode_featured -content: - field_paragraphs_body: - type: layout_paragraphs - label: hidden - settings: - view_mode: preview - link: '' - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 0 - region: content -hidden: - field_attachment: true - field_custom_page_logo: true - field_hide_title: true - field_keywords: true - field_state: true - field_topic: true - flag_like_node: true - langcode: true - links: true - og_audience: true - published_at: true - read_more: true - report: true - search_api_excerpt: true - share_link: true diff --git a/config/sync/core.entity_view_display.node.discussion.view_mode_featured.yml b/config/sync/core.entity_view_display.node.discussion.view_mode_featured.yml deleted file mode 100644 index 336cee94ac..0000000000 --- a/config/sync/core.entity_view_display.node.discussion.view_mode_featured.yml +++ /dev/null @@ -1,112 +0,0 @@ -uuid: f1c3abfc-3d7d-4c5a-acf2-58c2d0de9ded -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.node.view_mode_featured - - field.field.node.discussion.body - - field.field.node.discussion.field_attachment - - field.field.node.discussion.field_discussion_logo - - field.field.node.discussion.field_keywords - - field.field.node.discussion.field_replies - - field.field.node.discussion.field_shared_in - - field.field.node.discussion.field_site_featured - - field.field.node.discussion.field_state - - field.field.node.discussion.field_topic - - field.field.node.discussion.og_audience - - image.style.vertical_medium_image - - node.type.discussion - module: - - smart_trim - - svg_image - - template_suggestion - - user -_core: - default_config_hash: cizZmiLASa4LC9pPsT-05UiASc3zruNIGHWh2P8NfZc -id: node.discussion.view_mode_featured -targetEntityType: node -bundle: discussion -mode: view_mode_featured -content: - body: - type: smart_trim - label: hidden - settings: - trim_length: 200 - trim_type: chars - trim_suffix: … - wrap_output: false - wrap_class: trimmed - more: - display_link: false - target_blank: false - link_trim_only: false - class: more-link - text: More - aria_label: 'Read more about [node:title]' - summary_handler: trim - trim_options: - text: false - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 2 - region: content - field_discussion_logo: - type: image - label: hidden - settings: - image_link: content - image_style: vertical_medium_image - image_loading: - attribute: lazy - svg_attributes: - width: null - height: null - svg_render_as_image: true - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 1 - region: content - field_keywords: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: - template_suggestion: - template_suggestion: comma_separated - weight: 3 - region: content - field_topic: - type: entity_reference_label - label: hidden - settings: - link: false - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 0 - region: content -hidden: - featured: true - field_attachment: true - field_replies: true - field_shared_in: true - field_site_featured: true - field_state: true - flag_like_node: true - flag_subscribe_discussions: true - invite_link: true - langcode: true - latest_update_time: true - links: true - og_audience: true - pinned_in: true - published_at: true - read_more: true - report: true - search_api_excerpt: true - share_link: true - visit_count: true diff --git a/config/sync/core.entity_view_display.node.distribution.view_mode_featured.yml b/config/sync/core.entity_view_display.node.distribution.view_mode_featured.yml deleted file mode 100644 index 1bccec6730..0000000000 --- a/config/sync/core.entity_view_display.node.distribution.view_mode_featured.yml +++ /dev/null @@ -1,106 +0,0 @@ -uuid: 67d6a12f-f8f1-4552-a147-808a07b58913 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.node.view_mode_featured - - field.field.node.distribution.access_url - - field.field.node.distribution.description - - field.field.node.distribution.field_licence - - field.field.node.distribution.field_state - - field.field.node.distribution.file_size - - field.field.node.distribution.format - - field.field.node.distribution.og_audience - - field.field.node.distribution.process_status - - field.field.node.distribution.release - - field.field.node.distribution.representation_technique - - node.type.distribution - module: - - digital_size_formatter - - field_group - - joinup_distribution - - layout_builder - - template_suggestion - - text - - user -third_party_settings: - field_group: - group_categorisation: - children: - - format - - process_status - - representation_technique - label: Categorisation - parent_name: '' - region: hidden - weight: 15 - format_type: html_element - format_settings: - classes: '' - show_empty_fields: false - id: '' - element: div - show_label: true - label_element: h3 - label_element_classes: '' - attributes: '' - effect: none - speed: fast - layout_builder: - enabled: false - allow_custom: false -id: node.distribution.view_mode_featured -targetEntityType: node -bundle: distribution -mode: view_mode_featured -content: - access_url: - type: tracked_hosted_file_download - label: hidden - settings: - hosted_files_title: Download - remote_files_title: External - show_remote_files: false - third_party_settings: - template_suggestion: - template_suggestion: no_wrappers - weight: 1 - region: content - description: - type: text_default - label: hidden - settings: { } - third_party_settings: { } - weight: 2 - region: content - field_licence: - type: entity_reference_label - label: hidden - settings: - link: true - third_party_settings: - template_suggestion: - template_suggestion: fieldset - weight: 0 - region: content - file_size: - type: digital_size - label: hidden - settings: { } - third_party_settings: { } - weight: 3 - region: content -hidden: - download_count: true - field_state: true - format: true - langcode: true - links: true - og_audience: true - process_status: true - published_at: true - release: true - report: true - representation_technique: true - search_api_excerpt: true - uri: true diff --git a/config/sync/core.entity_view_display.node.document.view_mode_featured.yml b/config/sync/core.entity_view_display.node.document.view_mode_featured.yml deleted file mode 100644 index 9429c34caf..0000000000 --- a/config/sync/core.entity_view_display.node.document.view_mode_featured.yml +++ /dev/null @@ -1,87 +0,0 @@ -uuid: fc301cf5-0518-4c9e-a949-e572d76a0bc4 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.node.view_mode_featured - - field.field.node.document.abstract - - field.field.node.document.field_comments - - field.field.node.document.field_document_logo - - field.field.node.document.field_document_publication_date - - field.field.node.document.field_document_spatial_coverage - - field.field.node.document.field_file - - field.field.node.document.field_keywords - - field.field.node.document.field_licence - - field.field.node.document.field_paragraphs_body - - field.field.node.document.field_shared_in - - field.field.node.document.field_short_title - - field.field.node.document.field_site_featured - - field.field.node.document.field_state - - field.field.node.document.field_topic - - field.field.node.document.field_type - - field.field.node.document.og_audience - - node.type.document - module: - - file_url - - options - - template_suggestion - - user -_core: - default_config_hash: KhChNXOH45ERRneGRlPr6AZmdrB2ScUM5d6GqtQLD4Y -id: node.document.view_mode_featured -targetEntityType: node -bundle: document -mode: view_mode_featured -content: - field_file: - type: file_url_default - label: hidden - settings: - mode: link - third_party_settings: { } - weight: 2 - region: content - field_keywords: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: - template_suggestion: - template_suggestion: comma_separated - weight: 3 - region: content - field_type: - type: list_default - label: hidden - settings: { } - third_party_settings: - template_suggestion: - template_suggestion: no_wrappers - weight: 1 - region: content -hidden: - abstract: true - featured: true - field_comments: true - field_document_logo: true - field_document_publication_date: true - field_document_spatial_coverage: true - field_licence: true - field_paragraphs_body: true - field_shared_in: true - field_short_title: true - field_site_featured: true - field_state: true - field_topic: true - flag_like_node: true - langcode: true - links: true - og_audience: true - pinned_in: true - published_at: true - read_more: true - report: true - search_api_excerpt: true - share_link: true - visit_count: true diff --git a/config/sync/core.entity_view_display.node.event.view_mode_featured.yml b/config/sync/core.entity_view_display.node.event.view_mode_featured.yml deleted file mode 100644 index 9769c8d8d1..0000000000 --- a/config/sync/core.entity_view_display.node.event.view_mode_featured.yml +++ /dev/null @@ -1,127 +0,0 @@ -uuid: 67dc6aa1-8062-4eee-b485-36ab6add764d -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.node.view_mode_featured - - field.field.node.event.abstract - - field.field.node.event.field_attachment - - field.field.node.event.field_comments - - field.field.node.event.field_event_agenda - - field.field.node.event.field_event_contact_email - - field.field.node.event.field_event_coordinates - - field.field.node.event.field_event_date - - field.field.node.event.field_event_logo - - field.field.node.event.field_event_online_location - - field.field.node.event.field_event_spatial_coverage - - field.field.node.event.field_event_web_url - - field.field.node.event.field_keywords - - field.field.node.event.field_location - - field.field.node.event.field_organisation - - field.field.node.event.field_organisation_type - - field.field.node.event.field_paragraphs_body - - field.field.node.event.field_scope - - field.field.node.event.field_shared_in - - field.field.node.event.field_short_title - - field.field.node.event.field_site_featured - - field.field.node.event.field_state - - field.field.node.event.field_topic - - field.field.node.event.og_audience - - image.style.vertical_medium_image - - node.type.event - module: - - datetime_range - - entity_reference_revisions - - field_fallback_formatter - - joinup_html_stripper - - svg_image - - template_suggestion - - user -id: node.event.view_mode_featured -targetEntityType: node -bundle: event -mode: view_mode_featured -content: - abstract: - type: field_fallback_formatter - label: hidden - settings: - main_field_formatter_id: joinup_html_stripper_stripped - main_field_formatter_settings: - trim_length: 200 - fallback_field_id: field_paragraphs_body - fallback_field_formatter_id: entity_reference_revisions_entity_view - fallback_field_formatter_settings: - view_mode: tile - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 2 - region: content - field_event_date: - type: daterange_default - label: hidden - settings: - timezone_override: '' - format_type: date_only - from_to: both - separator: '-' - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 3 - region: content - field_event_logo: - type: image - label: hidden - settings: - image_link: content - image_style: vertical_medium_image - image_loading: - attribute: lazy - svg_attributes: - width: null - height: null - svg_render_as_image: true - third_party_settings: { } - weight: 1 - region: content - field_short_title: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: { } - weight: 0 - region: content -hidden: - featured: true - field_attachment: true - field_comments: true - field_event_agenda: true - field_event_contact_email: true - field_event_coordinates: true - field_event_online_location: true - field_event_spatial_coverage: true - field_event_web_url: true - field_keywords: true - field_location: true - field_organisation: true - field_organisation_type: true - field_paragraphs_body: true - field_scope: true - field_shared_in: true - field_site_featured: true - field_state: true - field_topic: true - flag_like_node: true - langcode: true - links: true - og_audience: true - pinned_in: true - published_at: true - read_more: true - report: true - search_api_excerpt: true - share_link: true - visit_count: true diff --git a/config/sync/core.entity_view_display.node.news.view_mode_featured.yml b/config/sync/core.entity_view_display.node.news.view_mode_featured.yml deleted file mode 100644 index f86632ca85..0000000000 --- a/config/sync/core.entity_view_display.node.news.view_mode_featured.yml +++ /dev/null @@ -1,90 +0,0 @@ -uuid: 9557be08-34a4-4da7-a264-7ef0163d7f65 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.node.view_mode_featured - - field.field.node.news.abstract - - field.field.node.news.field_attachment - - field.field.node.news.field_comments - - field.field.node.news.field_keywords - - field.field.node.news.field_news_headline - - field.field.node.news.field_news_logo - - field.field.node.news.field_news_referenced_solution - - field.field.node.news.field_news_source_url - - field.field.node.news.field_news_spatial_coverage - - field.field.node.news.field_paragraphs_body - - field.field.node.news.field_shared_in - - field.field.node.news.field_site_featured - - field.field.node.news.field_state - - field.field.node.news.field_topic - - field.field.node.news.og_audience - - node.type.news - module: - - field_fallback_formatter - - joinup_core - - template_suggestion - - user -_core: - default_config_hash: zB_g9fFRAkNl7WVU2yHNDomDoXIgABpLs-e30eu_uOw -id: node.news.view_mode_featured -targetEntityType: node -bundle: news -mode: view_mode_featured -content: - abstract: - type: field_fallback_formatter - label: hidden - settings: - main_field_formatter_id: string - main_field_formatter_settings: - link_to_entity: false - fallback_field_id: field_paragraphs_body - fallback_field_formatter_id: filtered_entity_reference_bundles - fallback_field_formatter_settings: - view_mode: tile - filtered_entity_bundles: - - simple_paragraph - - text - trim_length: 200 - trim_chars: ... - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 0 - region: content - field_keywords: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: - template_suggestion: - template_suggestion: comma_separated - weight: 1 - region: content -hidden: - featured: true - field_attachment: true - field_comments: true - field_news_headline: true - field_news_logo: true - field_news_referenced_solution: true - field_news_source_url: true - field_news_spatial_coverage: true - field_paragraphs_body: true - field_shared_in: true - field_site_featured: true - field_state: true - field_topic: true - flag_like_node: true - langcode: true - links: true - og_audience: true - pinned_in: true - published_at: true - read_more: true - report: true - search_api_excerpt: true - share_link: true - visit_count: true diff --git a/config/sync/core.entity_view_display.node.release.view_mode_featured.yml b/config/sync/core.entity_view_display.node.release.view_mode_featured.yml deleted file mode 100644 index a20780ce77..0000000000 --- a/config/sync/core.entity_view_display.node.release.view_mode_featured.yml +++ /dev/null @@ -1,75 +0,0 @@ -uuid: b9f766f6-a0b1-41b0-9758-0a8a9ecbb6e2 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.node.view_mode_featured - - field.field.node.release.description - - field.field.node.release.documentation - - field.field.node.release.field_keywords - - field.field.node.release.field_state - - field.field.node.release.og_audience - - field.field.node.release.language - - field.field.node.release.process_status - - field.field.node.release.release_number - - field.field.node.release.solution_data - - field.field.node.release.spatial_coverage - - node.type.release - module: - - svg_image - - template_suggestion - - user -id: node.release.view_mode_featured -targetEntityType: node -bundle: release -mode: view_mode_featured -content: - process_status: - type: entity_reference_label - label: hidden - settings: - link: false - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 2 - region: content - release_number: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: { } - weight: 0 - region: content - solution_logo: - type: image - label: hidden - settings: - image_link: '' - image_style: '' - image_loading: - attribute: lazy - svg_attributes: - width: null - height: null - svg_render_as_image: true - third_party_settings: { } - weight: 1 - region: content -hidden: - description: true - distributions: true - documentation: true - field_keywords: true - field_state: true - langcode: true - language: true - links: true - og_audience: true - published_at: true - report: true - search_api_excerpt: true - solution_data: true - spatial_coverage: true - uri: true diff --git a/config/sync/core.entity_view_display.paragraph.entity_reference.default.yml b/config/sync/core.entity_view_display.paragraph.entity_reference.default.yml index a09a878ecd..afd17bae80 100644 --- a/config/sync/core.entity_view_display.paragraph.entity_reference.default.yml +++ b/config/sync/core.entity_view_display.paragraph.entity_reference.default.yml @@ -16,7 +16,7 @@ content: type: entity_reference_entity_view label: above settings: - view_mode: view_mode_featured + view_mode: view_mode_tile_horizontal link: false third_party_settings: template_suggestion: diff --git a/config/sync/core.entity_view_display.rdf_entity.collection.view_mode_featured.yml b/config/sync/core.entity_view_display.rdf_entity.collection.view_mode_featured.yml deleted file mode 100644 index 57a80785f8..0000000000 --- a/config/sync/core.entity_view_display.rdf_entity.collection.view_mode_featured.yml +++ /dev/null @@ -1,103 +0,0 @@ -uuid: 3e01e165-792c-4584-947a-39590bb070b4 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.rdf_entity.view_mode_featured - - field.field.rdf_entity.collection.field_ar_abstract - - field.field.rdf_entity.collection.field_ar_access_url - - field.field.rdf_entity.collection.field_ar_affiliates - - field.field.rdf_entity.collection.field_ar_closed - - field.field.rdf_entity.collection.field_ar_contact_information - - field.field.rdf_entity.collection.field_ar_content_creation - - field.field.rdf_entity.collection.field_ar_description - - field.field.rdf_entity.collection.field_ar_logo - - field.field.rdf_entity.collection.field_ar_moderation - - field.field.rdf_entity.collection.field_ar_owner - - field.field.rdf_entity.collection.field_ar_state - - field.field.rdf_entity.collection.field_collection_content - - field.field.rdf_entity.collection.field_keywords - - field.field.rdf_entity.collection.field_newsletter - - field.field.rdf_entity.collection.field_short_id - - field.field.rdf_entity.collection.field_site_featured - - field.field.rdf_entity.collection.field_spatial_coverage - - field.field.rdf_entity.collection.field_topic - - image.style.vertical_medium_image - - rdf_entity.rdfentity.collection - module: - - svg_image - - user -id: rdf_entity.collection.view_mode_featured -targetEntityType: rdf_entity -bundle: collection -mode: view_mode_featured -content: - field_ar_abstract: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 3 - region: content - field_ar_logo: - type: image - label: hidden - settings: - image_link: content - image_style: vertical_medium_image - image_loading: - attribute: lazy - svg_attributes: - width: null - height: null - svg_render_as_image: true - third_party_settings: { } - weight: 0 - region: content - label: - type: string - label: hidden - settings: - link_to_entity: true - third_party_settings: { } - weight: 1 - region: content - members: - settings: { } - third_party_settings: { } - weight: 2 - region: content -hidden: - changed: true - created: true - featured: true - field_ar_access_url: true - field_ar_affiliates: true - field_ar_closed: true - field_ar_contact_information: true - field_ar_content_creation: true - field_ar_description: true - field_ar_moderation: true - field_ar_owner: true - field_ar_state: true - field_collection_content: true - field_keywords: true - field_newsletter: true - field_short_id: true - field_site_featured: true - field_spatial_coverage: true - field_topic: true - join_collection: true - langcode: true - last_update: true - og_group: true - published_at: true - rdf_entity_collection_field_collection_content_inline_facets: true - rdf_entity_collection_field_collection_content_top: true - read_more: true - search_api_excerpt: true - settings: true - solutions: true diff --git a/config/sync/core.entity_view_display.rdf_entity.solution.view_mode_featured.yml b/config/sync/core.entity_view_display.rdf_entity.solution.view_mode_featured.yml deleted file mode 100644 index 9d4ccb54c9..0000000000 --- a/config/sync/core.entity_view_display.rdf_entity.solution.view_mode_featured.yml +++ /dev/null @@ -1,163 +0,0 @@ -uuid: 3f406182-0fc3-4ec7-91f0-c84da196e7c3 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.rdf_entity.view_mode_featured - - field.field.rdf_entity.solution.field_is_abstract - - field.field.rdf_entity.solution.field_is_affiliations_requests - - field.field.rdf_entity.solution.field_is_contact_information - - field.field.rdf_entity.solution.field_is_content - - field.field.rdf_entity.solution.field_is_content_creation - - field.field.rdf_entity.solution.field_is_description - - field.field.rdf_entity.solution.field_is_documentation - - field.field.rdf_entity.solution.field_is_included_asset - - field.field.rdf_entity.solution.field_is_issue_tracker - - field.field.rdf_entity.solution.field_is_landing_page - - field.field.rdf_entity.solution.field_is_language - - field.field.rdf_entity.solution.field_is_logo - - field.field.rdf_entity.solution.field_is_metrics_page - - field.field.rdf_entity.solution.field_is_moderation - - field.field.rdf_entity.solution.field_is_owner - - field.field.rdf_entity.solution.field_is_related_solutions - - field.field.rdf_entity.solution.field_is_shared_in - - field.field.rdf_entity.solution.field_is_show_eira_related - - field.field.rdf_entity.solution.field_is_solution_type - - field.field.rdf_entity.solution.field_is_source_code_repository - - field.field.rdf_entity.solution.field_is_state - - field.field.rdf_entity.solution.field_is_translation - - field.field.rdf_entity.solution.field_is_version - - field.field.rdf_entity.solution.field_is_webdav_creation - - field.field.rdf_entity.solution.field_is_webdav_url - - field.field.rdf_entity.solution.field_is_wiki - - field.field.rdf_entity.solution.field_keywords - - field.field.rdf_entity.solution.field_short_id - - field.field.rdf_entity.solution.field_site_featured - - field.field.rdf_entity.solution.field_spatial_coverage - - field.field.rdf_entity.solution.field_status - - field.field.rdf_entity.solution.field_topic - - image.style.vertical_medium_image - - rdf_entity.rdfentity.solution - module: - - field_fallback_formatter - - smart_trim - - svg_image - - template_suggestion - - user -id: rdf_entity.solution.view_mode_featured -targetEntityType: rdf_entity -bundle: solution -mode: view_mode_featured -content: - download_total: - settings: { } - third_party_settings: { } - weight: 3 - region: content - field_is_abstract: - type: field_fallback_formatter - label: hidden - settings: - main_field_formatter_id: string - main_field_formatter_settings: - link_to_entity: false - fallback_field_id: field_is_description - fallback_field_formatter_id: smart_trim - fallback_field_formatter_settings: - trim_length: 200 - trim_type: chars - trim_suffix: ... - wrap_output: false - wrap_class: trimmed - more: - display_link: false - target_blank: false - link_trim_only: false - class: more-link - text: More - aria_label: 'Read more about [node:title]' - trim_options: - text: true - trim_zero: false - replace_tokens: false - third_party_settings: - template_suggestion: - template_suggestion: '' - weight: 2 - region: content - field_is_logo: - type: image - label: hidden - settings: - image_link: content - image_style: vertical_medium_image - image_loading: - attribute: lazy - svg_attributes: - width: null - height: null - svg_render_as_image: true - third_party_settings: { } - weight: 1 - region: content - label: - type: string - label: hidden - settings: - link_to_entity: true - third_party_settings: { } - weight: 0 - region: content -hidden: - changed: true - collections: true - created: true - distributions: true - eif_perspective: true - featured: true - field_is_affiliations_requests: true - field_is_contact_information: true - field_is_content: true - field_is_content_creation: true - field_is_description: true - field_is_documentation: true - field_is_included_asset: true - field_is_issue_tracker: true - field_is_landing_page: true - field_is_language: true - field_is_metrics_page: true - field_is_moderation: true - field_is_owner: true - field_is_related_solutions: true - field_is_shared_in: true - field_is_show_eira_related: true - field_is_solution_type: true - field_is_source_code_repository: true - field_is_state: true - field_is_translation: true - field_is_version: true - field_is_webdav_creation: true - field_is_webdav_url: true - field_is_wiki: true - field_keywords: true - field_short_id: true - field_site_featured: true - field_spatial_coverage: true - field_status: true - field_topic: true - flag_interoperability: true - flag_like_rdf_entity: true - langcode: true - members: true - og_group: true - pinned_in: true - published_at: true - rdf_entity_solution_field_is_content_inline_facets: true - rdf_entity_solution_field_is_content_top: true - read_more: true - related_solution: true - related_solutions: true - releases_overview: true - search_api_excerpt: true - share_link: true - solution_subscribe: true diff --git a/config/sync/core.entity_view_display.user.user.view_mode_featured.yml b/config/sync/core.entity_view_display.user.user.view_mode_featured.yml deleted file mode 100644 index ae76f53611..0000000000 --- a/config/sync/core.entity_view_display.user.user.view_mode_featured.yml +++ /dev/null @@ -1,71 +0,0 @@ -uuid: 96202048-3e21-43d3-bc64-696007d8a8f9 -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.user.view_mode_featured - - field.field.user.user.field_social_media - - field.field.user.user.field_user_business_title - - field.field.user.user.field_user_content - - field.field.user.user.field_user_family_name - - field.field.user.user.field_user_first_name - - field.field.user.user.field_user_frequency - - field.field.user.user.field_user_nationality - - field.field.user.user.field_user_organisation - - field.field.user.user.field_user_photo - - field.field.user.user.field_user_professional_domain - - image.style.vertical_medium_image - module: - - image - - user -id: user.user.view_mode_featured -targetEntityType: user -bundle: user -mode: view_mode_featured -content: - field_user_business_title: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: { } - weight: 3 - region: content - field_user_family_name: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: { } - weight: 1 - region: content - field_user_first_name: - type: string - label: hidden - settings: - link_to_entity: false - third_party_settings: { } - weight: 2 - region: content - field_user_photo: - type: image - label: hidden - settings: - image_link: content - image_style: vertical_medium_image - image_loading: - attribute: lazy - third_party_settings: { } - weight: 0 - region: content -hidden: - field_social_media: true - field_user_content: true - field_user_frequency: true - field_user_nationality: true - field_user_organisation: true - field_user_professional_domain: true - langcode: true - member_for: true - search_api_excerpt: true - user_user_field_user_content_top: true diff --git a/config/sync/core.entity_view_mode.node.view_mode_featured.yml b/config/sync/core.entity_view_mode.node.view_mode_featured.yml deleted file mode 100644 index 3484bed9d0..0000000000 --- a/config/sync/core.entity_view_mode.node.view_mode_featured.yml +++ /dev/null @@ -1,13 +0,0 @@ -uuid: 1a0fc8fe-29da-481c-8628-4bba0df0273e -langcode: en -status: true -dependencies: - module: - - node -_core: - default_config_hash: 5k72FtJ9esgHSZHe3ZSolef7tJt0Bd4jpBkEhEN6UbM -id: node.view_mode_featured -label: Featured -description: '' -targetEntityType: node -cache: true diff --git a/config/sync/core.entity_view_mode.rdf_entity.view_mode_featured.yml b/config/sync/core.entity_view_mode.rdf_entity.view_mode_featured.yml deleted file mode 100644 index f397790cda..0000000000 --- a/config/sync/core.entity_view_mode.rdf_entity.view_mode_featured.yml +++ /dev/null @@ -1,13 +0,0 @@ -uuid: 1c1ddab2-1312-41ba-83a0-36eb12c7e0c4 -langcode: en -status: true -dependencies: - module: - - rdf_entity -_core: - default_config_hash: Ggclz9My2ahpEs9JniKrjC7QNGt0nenU0hTU0sY05SE -id: rdf_entity.view_mode_featured -label: Featured -description: '' -targetEntityType: rdf_entity -cache: true diff --git a/config/sync/core.entity_view_mode.user.view_mode_featured.yml b/config/sync/core.entity_view_mode.user.view_mode_featured.yml deleted file mode 100644 index e6be60b62f..0000000000 --- a/config/sync/core.entity_view_mode.user.view_mode_featured.yml +++ /dev/null @@ -1,13 +0,0 @@ -uuid: 9944b9bc-cd13-4372-a96e-83a774aeb9f2 -langcode: en -status: true -dependencies: - module: - - user -_core: - default_config_hash: znH60RCRSMIJZF_6GbR6jymTmlSPHY-sfSAr_3THkBE -id: user.view_mode_featured -label: Featured -description: '' -targetEntityType: user -cache: true diff --git a/config/sync/views.view.in_the_spotlight.yml b/config/sync/views.view.in_the_spotlight.yml index 1628d55d08..772904f137 100644 --- a/config/sync/views.view.in_the_spotlight.yml +++ b/config/sync/views.view.in_the_spotlight.yml @@ -172,53 +172,7 @@ display: - 'user.node_grants:view' - user.permissions tags: - - 'config:core.entity_view_display.node.custom_page.carousel' - - 'config:core.entity_view_display.node.custom_page.default' - - 'config:core.entity_view_display.node.custom_page.view_mode_featured' - - 'config:core.entity_view_display.node.custom_page.view_mode_tile' - - 'config:core.entity_view_display.node.custom_page.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.discussion.carousel' - - 'config:core.entity_view_display.node.discussion.default' - - 'config:core.entity_view_display.node.discussion.digest_message' - - 'config:core.entity_view_display.node.discussion.moderation' - - 'config:core.entity_view_display.node.discussion.view_mode_featured' - - 'config:core.entity_view_display.node.discussion.view_mode_tile' - - 'config:core.entity_view_display.node.discussion.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.document.carousel' - - 'config:core.entity_view_display.node.document.default' - - 'config:core.entity_view_display.node.document.digest_message' - - 'config:core.entity_view_display.node.document.highlighted' - - 'config:core.entity_view_display.node.document.moderation' - - 'config:core.entity_view_display.node.document.view_mode_featured' - - 'config:core.entity_view_display.node.document.view_mode_tile' - - 'config:core.entity_view_display.node.document.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.event.carousel' - - 'config:core.entity_view_display.node.event.default' - - 'config:core.entity_view_display.node.event.digest_message' - - 'config:core.entity_view_display.node.event.explore_item' - - 'config:core.entity_view_display.node.event.highlighted' - - 'config:core.entity_view_display.node.event.highlighted_event' - - 'config:core.entity_view_display.node.event.moderation' - - 'config:core.entity_view_display.node.event.view_mode_featured' - - 'config:core.entity_view_display.node.event.view_mode_tile' - - 'config:core.entity_view_display.node.event.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.glossary.default' - - 'config:core.entity_view_display.node.glossary.view_mode_tile' - - 'config:core.entity_view_display.node.news.carousel' - - 'config:core.entity_view_display.node.news.default' - - 'config:core.entity_view_display.node.news.digest_message' - - 'config:core.entity_view_display.node.news.explore_item' - - 'config:core.entity_view_display.node.news.highlighted' - - 'config:core.entity_view_display.node.news.moderation' - - 'config:core.entity_view_display.node.news.view_mode_featured' - - 'config:core.entity_view_display.node.news.view_mode_tile' - - 'config:core.entity_view_display.node.news.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.video.default' - - 'config:core.entity_view_display.node.video.view_mode_featured' - - 'config:core.entity_view_display.node.video.view_mode_tile' - 'config:entityqueue.entity_queue.spotlight' - - entity_field_info - - views_data block: id: block display_title: Block @@ -236,50 +190,4 @@ display: - 'user.node_grants:view' - user.permissions tags: - - 'config:core.entity_view_display.node.custom_page.carousel' - - 'config:core.entity_view_display.node.custom_page.default' - - 'config:core.entity_view_display.node.custom_page.view_mode_featured' - - 'config:core.entity_view_display.node.custom_page.view_mode_tile' - - 'config:core.entity_view_display.node.custom_page.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.discussion.carousel' - - 'config:core.entity_view_display.node.discussion.default' - - 'config:core.entity_view_display.node.discussion.digest_message' - - 'config:core.entity_view_display.node.discussion.moderation' - - 'config:core.entity_view_display.node.discussion.view_mode_featured' - - 'config:core.entity_view_display.node.discussion.view_mode_tile' - - 'config:core.entity_view_display.node.discussion.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.document.carousel' - - 'config:core.entity_view_display.node.document.default' - - 'config:core.entity_view_display.node.document.digest_message' - - 'config:core.entity_view_display.node.document.highlighted' - - 'config:core.entity_view_display.node.document.moderation' - - 'config:core.entity_view_display.node.document.view_mode_featured' - - 'config:core.entity_view_display.node.document.view_mode_tile' - - 'config:core.entity_view_display.node.document.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.event.carousel' - - 'config:core.entity_view_display.node.event.default' - - 'config:core.entity_view_display.node.event.digest_message' - - 'config:core.entity_view_display.node.event.explore_item' - - 'config:core.entity_view_display.node.event.highlighted' - - 'config:core.entity_view_display.node.event.highlighted_event' - - 'config:core.entity_view_display.node.event.moderation' - - 'config:core.entity_view_display.node.event.view_mode_featured' - - 'config:core.entity_view_display.node.event.view_mode_tile' - - 'config:core.entity_view_display.node.event.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.glossary.default' - - 'config:core.entity_view_display.node.glossary.view_mode_tile' - - 'config:core.entity_view_display.node.news.carousel' - - 'config:core.entity_view_display.node.news.default' - - 'config:core.entity_view_display.node.news.digest_message' - - 'config:core.entity_view_display.node.news.explore_item' - - 'config:core.entity_view_display.node.news.highlighted' - - 'config:core.entity_view_display.node.news.moderation' - - 'config:core.entity_view_display.node.news.view_mode_featured' - - 'config:core.entity_view_display.node.news.view_mode_tile' - - 'config:core.entity_view_display.node.news.view_mode_tile_horizontal' - - 'config:core.entity_view_display.node.video.default' - - 'config:core.entity_view_display.node.video.view_mode_featured' - - 'config:core.entity_view_display.node.video.view_mode_tile' - 'config:entityqueue.entity_queue.spotlight' - - entity_field_info - - views_data diff --git a/config/sync/views.view.members_overview.yml b/config/sync/views.view.members_overview.yml index 21d2bf5029..92051b7cc5 100644 --- a/config/sync/views.view.members_overview.yml +++ b/config/sync/views.view.members_overview.yml @@ -653,11 +653,5 @@ display: - url - url.query_args tags: - - 'config:core.entity_view_display.user.user.compact' - - 'config:core.entity_view_display.user.user.default' - - 'config:core.entity_view_display.user.user.group_header' - - 'config:core.entity_view_display.user.user.inline' - - 'config:core.entity_view_display.user.user.view_mode_featured' - - 'config:core.entity_view_display.user.user.view_mode_tile' - 'config:field.storage.user.field_user_family_name' - 'config:field.storage.user.field_user_first_name' diff --git a/web/modules/custom/joinup_tiles/templates/joinup-tiles.html.twig b/web/modules/custom/joinup_tiles/templates/joinup-tiles.html.twig index 7e084a550e..1fe14c1f14 100644 --- a/web/modules/custom/joinup_tiles/templates/joinup-tiles.html.twig +++ b/web/modules/custom/joinup_tiles/templates/joinup-tiles.html.twig @@ -30,7 +30,6 @@ 'listing__item--tile', 'mdl-cell', row.content['#view_mode'] == 'view_mode_tile' ? 'mdl-cell--4-col mdl-cell--3-col-wide', - row.content['#view_mode'] == 'view_mode_featured' ? 'mdl-cell--12-col mdl-cell--9-col-wide', ] %} <div{{ row.attributes.addClass(row_classes) }}> diff --git a/web/themes/ventuno/templates/content/node--glossary--view-mode-tile.html.twig b/web/themes/ventuno/templates/content/node--glossary--view-mode-tile.html.twig index 86aa1a7d8a..d668dc9c47 100644 --- a/web/themes/ventuno/templates/content/node--glossary--view-mode-tile.html.twig +++ b/web/themes/ventuno/templates/content/node--glossary--view-mode-tile.html.twig @@ -70,10 +70,11 @@ * in different view modes. */ #} -{% set view_mode_featured = view_mode is same as 'view_mode_featured' %} {% set image %} <a href="{{ url }}" class="d-block"> - <svg class="bi img-fluid{{ view_mode_featured ? ' text-primary' : ' text-secondary' }}"><use xlink:href="{{ bcl_icon_path }}#type"></use></svg> + <svg class="bi img-fluid text-secondary"> + <use xlink:href="{{ bcl_icon_path }}#type"></use> + </svg> </a> {% endset %} {{ pattern('tile', { -- GitLab From 6c62eec49b31db59ed6c95dc5da4d59c42923b5a Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 29 Aug 2024 08:24:01 +0200 Subject: [PATCH 007/149] ISAICP-8691: Add test --- .../paragraphs/entity_reference.feature | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/features/paragraphs/entity_reference.feature diff --git a/tests/features/paragraphs/entity_reference.feature b/tests/features/paragraphs/entity_reference.feature new file mode 100644 index 0000000000..e7bc809dec --- /dev/null +++ b/tests/features/paragraphs/entity_reference.feature @@ -0,0 +1,33 @@ +@api @group-h +Feature: + As a site builder of the site + I need to be able to use "entity_reference" paragraphs for content. + + Background: + Given the following collection: + | title | Paragraphs collection | + | state | published | + + @javascript + Scenario: Entity reference displays related content. + Given custom_page content: + | title | collection | state | + | Entity reference page | Paragraphs collection | published | + | Related content | Paragraphs collection | published | + And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Entity reference page" title: + | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} | + + When I am logged in as a moderator + And I go to the edit form of the "Entity reference page" "custom page" + And I click "Choose component" + And a modal should open + And I click "Entity reference" + When I type "Related conte" in the "Content" autocomplete field + And I wait until the page contains the text "Related content" + And I pick "Related content" from the autocomplete suggestions + When I press "Save" in the "Modal buttons" region + And I press "Update" + + When I am an anonymous user + And I visit the "Entity reference page" custom page + Then I should see the "Related content" tile -- GitLab From 863a9a76a54c2f5ff740413ee0ad8be097500414 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 10:13:41 +0200 Subject: [PATCH 008/149] ISAICP-9041: Move the location of disable-config-readonly. --- .gitignore | 2 - .opts.yml | 12 ++-- resources/runner/config_readonly.yml | 6 +- resources/runner/drupal.yml | 2 +- tests/src/Traits/ConfigReadOnlyTrait.php | 2 +- .../custom/joinup_core/drush.services.yml | 8 ++- .../joinup_core/joinup_core.services.yml | 6 +- .../PrivateFileKillSwitchCommands.php | 47 ++++++++++++++ .../joinup_core/src/FileConfigReadOnly.php | 22 ++----- .../joinup_core/src/KillSwitchInterface.php | 39 +++++++++++ .../joinup_core/src/PrivateFileKillSwitch.php | 64 +++++++++++++++++++ 11 files changed, 178 insertions(+), 32 deletions(-) create mode 100644 web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php create mode 100644 web/modules/custom/joinup_core/src/KillSwitchInterface.php create mode 100644 web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php diff --git a/.gitignore b/.gitignore index ce96440ad6..ba5cdabf0c 100644 --- a/.gitignore +++ b/.gitignore @@ -43,8 +43,6 @@ /.vscode/ /.devcontainer/ -# Ignore the config_readonly killswitch. -/disable-config-readonly # Ignore the cookie consent killswitch. /disable-cookie-consent # Ignore the EU OSS Catalogue killswitch. diff --git a/.opts.yml b/.opts.yml index fbfe802f17..2171010883 100644 --- a/.opts.yml +++ b/.opts.yml @@ -5,23 +5,23 @@ # See \EcEuropa\Toolkit\TaskRunner\Commands\CloneCommands::runDeploy(). upgrade_commands: default: - - touch disable-config-readonly + - ./vendor/bin/drush joinup-core:kill-switch-create disable-config-readonly - ./vendor/bin/drush deploy --yes - ./vendor/bin/drush search-api:reset-tracker --yes - ./vendor/bin/drush joinup:node-access-rebuild - ./vendor/bin/drush joinup:search-api-tasks - ./vendor/bin/drush twigc --yes - - rm disable-config-readonly + - ./vendor/bin/drush joinup-core:kill-switch-remove disable-config-readonly - ./vendor/bin/drush joinup:unpublish-alert --category - ./scripts/check_status_report.php append: production: - touch disable-eu-oss-catalogue acceptance: - - touch disable-config-readonly + - ./vendor/bin/drush joinup-core:kill-switch-create disable-config-readonly - ./vendor/bin/drush joinup:acc - ./vendor/bin/drush cache:rebuild - - rm disable-config-readonly + - ./vendor/bin/drush joinup-core:kill-switch-remove disable-config-readonly # Remove this line when deploying to POC. - touch disable-eu-oss-catalogue - ./vendor/bin/drush eu-oss:fetch developers_italia @@ -29,10 +29,10 @@ upgrade_commands: - ./vendor/bin/drush queue:run eu_oss_catalogue - ./vendor/bin/drush queue:run joinup_oss_catalogue_imagecache_warmer ephemeral: - - touch disable-config-readonly + - ./vendor/bin/drush joinup-core:kill-switch-create disable-config-readonly - ./vendor/bin/drush joinup:acc - ./vendor/bin/drush cache:rebuild - - rm disable-config-readonly + - ./vendor/bin/drush joinup-core:kill-switch-remove disable-config-readonly - ./vendor/bin/drush eu-oss:fetch developers_italia - ./vendor/bin/drush eu-oss:fetch hosting_platform:open_code - ./vendor/bin/drush queue:run eu_oss_catalogue diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml index da4e29a358..0e0ed9729f 100644 --- a/resources/runner/config_readonly.yml +++ b/resources/runner/config_readonly.yml @@ -9,8 +9,10 @@ commands: # Config readonly kill-switch. config-readonly:enable: - task: exec - command: (test "${config_readonly}" = "1" && rm -f ${joinup.dir}/disable-config-readonly) || true + command: (test "${config_readonly}" = "1" && rm -f ${joinup.files_private_dir}/file-switcher/disable-config-readonly) || true config-readonly:disable: + - task: mkdir + dir: ${joinup.files_private_dir}/file-switcher - task: touch - file: ${joinup.dir}/disable-config-readonly + file: ${joinup.files_private_dir}/file-switcher/disable-config-readonly diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml index 9c85e40aee..2fa6c819ab 100644 --- a/resources/runner/drupal.yml +++ b/resources/runner/drupal.yml @@ -242,7 +242,7 @@ drupal: ]; // Location of the site configuration files. $settings['config_sync_directory'] = '../config/sync'; - $settings['config_readonly'] = !file_exists(getcwd() . '/../disable-config-readonly'); + $settings['config_readonly'] = !file_exists($settings['file_private_path'] . '/file-switcher/disable-config-readonly'); Testing configuration alters: | // The video from the home page interacts with Selenium tests. $config['page_manager.page_variant.homepage-layout_builder-0']['variant_settings']['sections'][4]['components']['6ab0ceea-4541-4153-8b64-227e02369d30']['configuration']['text'] = 'Some joinup video'; diff --git a/tests/src/Traits/ConfigReadOnlyTrait.php b/tests/src/Traits/ConfigReadOnlyTrait.php index 54e258b40d..f852a4c297 100644 --- a/tests/src/Traits/ConfigReadOnlyTrait.php +++ b/tests/src/Traits/ConfigReadOnlyTrait.php @@ -74,7 +74,7 @@ protected static function checkConfigReadOnlyKillSwitch(): void { /** @var \Drupal\Core\DrupalKernelInterface $kernel */ $kernel = \Drupal::service('kernel'); $site_path = $kernel->getSitePath(); - $needle = "\$settings['config_readonly'] = !file_exists(getcwd() . '/../disable-config-readonly');"; + $needle = "\$settings['config_readonly'] = !file_exists(\$settings['file_private_path'] . '/file-switcher/disable-config-readonly');"; $settings_php = file_get_contents("{$site_path}/settings.php"); if (strpos($settings_php, $needle) === FALSE) { throw new \Exception("The following line is missing from web/sites/default/settings.php\n$needle"); diff --git a/web/modules/custom/joinup_core/drush.services.yml b/web/modules/custom/joinup_core/drush.services.yml index cc9c1391d4..4a58b6cd24 100644 --- a/web/modules/custom/joinup_core/drush.services.yml +++ b/web/modules/custom/joinup_core/drush.services.yml @@ -1,6 +1,12 @@ services: joinup_core.sanitize.commands: class: Drupal\joinup_core\Commands\JoinupDataSanitizationCommands - arguments: ['@database', '@entity_field.manager', '@entity_type.manager', '@keyvalue', '@plugin.manager.field.field_type'] + arguments: [ '@database', '@entity_field.manager', '@entity_type.manager', '@keyvalue', '@plugin.manager.field.field_type' ] + tags: + - { name: drush.command } + + joinup_core.private_file_kill_switch.commands: + class: Drupal\joinup_core\Commands\PrivateFileKillSwitchCommands + arguments: [ '@joinup_core.private_file_kill_switch' ] tags: - { name: drush.command } diff --git a/web/modules/custom/joinup_core/joinup_core.services.yml b/web/modules/custom/joinup_core/joinup_core.services.yml index 9ed58a6e57..f029f09341 100644 --- a/web/modules/custom/joinup_core/joinup_core.services.yml +++ b/web/modules/custom/joinup_core/joinup_core.services.yml @@ -42,9 +42,13 @@ services: tags: - { name: event_subscriber } + joinup_core.private_file_kill_switch: + class: Drupal\joinup_core\PrivateFileKillSwitch + arguments: [ '@file_system' ] + joinup_core.file_config_read_only: class: Drupal\joinup_core\FileConfigReadOnly - arguments: [ '@file_system' ] + arguments: [ '@joinup_core.private_file_kill_switch' ] # Prevent errors in twigc by implementing the missing get_dummy_text function, # which is referenced in BCL component templates. diff --git a/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php b/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php new file mode 100644 index 0000000000..5027d4fb10 --- /dev/null +++ b/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php @@ -0,0 +1,47 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\joinup_core\Commands; + +use Drupal\joinup_core\KillSwitchInterface; +use Drush\Attributes as CLI; +use Drush\Commands\DrushCommands; +use Drush\Drupal\Commands\sql\SanitizeCommands; + +/** + * Private file kill switch commands. + * + * @see \Drush\Drupal\Commands\sql\SanitizeCommands::sanitize() + */ +class PrivateFileKillSwitchCommands extends DrushCommands { + + public function __construct(protected KillSwitchInterface $killSwitch) { + parent::__construct(); + } + + /** + * Enable switch. + */ + #[CLI\Command(name: 'joinup-core:kill-switch-remove')] + #[CLI\Argument(name: 'type', description: 'The switch type')] + public function killSwitchRemove(string $type): string { + $this->killSwitch->remove($type); + return dt('Removed @type file', [ + '@type' => $type, + ]); + } + + /** + * Disable switch. + */ + #[CLI\Command(name: 'joinup-core:kill-switch-create')] + #[CLI\Argument(name: 'type', description: 'The switch type')] + public function killSwitchCreate(string $type): string { + $this->killSwitch->create($type); + return dt('Created @type file', [ + '@type' => $type, + ]); + } + +} diff --git a/web/modules/custom/joinup_core/src/FileConfigReadOnly.php b/web/modules/custom/joinup_core/src/FileConfigReadOnly.php index 7ff9241f8d..446375e7da 100644 --- a/web/modules/custom/joinup_core/src/FileConfigReadOnly.php +++ b/web/modules/custom/joinup_core/src/FileConfigReadOnly.php @@ -4,8 +4,6 @@ namespace Drupal\joinup_core; -use Drupal\Core\File\FileSystemInterface; - /** * Represents a file-based implementation of the ConfigReadOnlyInterface. */ @@ -18,39 +16,27 @@ class FileConfigReadOnly implements ConfigReadOnlyInterface { */ protected const string FILE_NAME = 'disable-config-readonly'; - public function __construct(protected FileSystemInterface $fileSystem) {} + public function __construct(protected KillSwitchInterface $killSwitch) {} /** * {@inheritdoc} */ public function isReadOnlyEnabled(): bool { - return !file_exists($this->pathToReadOnlyFile()); + return !$this->killSwitch->exists(self::FILE_NAME); } /** * {@inheritdoc} */ public function enableReadOnly(): void { - if (!$this->isReadOnlyEnabled()) { - $this->fileSystem->unlink($this->pathToReadOnlyFile()); - } + $this->killSwitch->remove(self::FILE_NAME); } /** * {@inheritdoc} */ public function disableReadOnly(): void { - touch($this->pathToReadOnlyFile()); - } - - /** - * Returns the file path to disable the config readonly flag. - * - * @return string - * The file path - */ - protected function pathToReadOnlyFile(): string { - return DRUPAL_ROOT . '/../' . self::FILE_NAME; + $this->killSwitch->create(self::FILE_NAME); } } diff --git a/web/modules/custom/joinup_core/src/KillSwitchInterface.php b/web/modules/custom/joinup_core/src/KillSwitchInterface.php new file mode 100644 index 0000000000..b899489a7f --- /dev/null +++ b/web/modules/custom/joinup_core/src/KillSwitchInterface.php @@ -0,0 +1,39 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\joinup_core; + +/** + * Kill switch. + */ +interface KillSwitchInterface { + + /** + * Checks if the switch exists. + * + * @param string $type + * Type. + * + * @return bool + * Returns true if the switch exists, false otherwise. + */ + public function exists(string $type): bool; + + /** + * Create switch. + * + * @param string $type + * Type. + */ + public function create(string $type): void; + + /** + * Remove switch. + * + * @param string $type + * Type. + */ + public function remove(string $type): void; + +} diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php new file mode 100644 index 0000000000..f7cac7f53a --- /dev/null +++ b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php @@ -0,0 +1,64 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\joinup_core; + +use Drupal\Core\File\FileExists; +use Drupal\Core\File\FileSystemInterface; + +/** + * Private file kill switch. + */ +class PrivateFileKillSwitch implements KillSwitchInterface { + + const string DIRECTORY = 'private://file-switcher'; + + public function __construct(protected FileSystemInterface $fileSystem) {} + + /** + * {@inheritdoc} + */ + public function remove(string $type): void { + if ($this->exists($type)) { + $file = $this->getFilePath($type); + $this->fileSystem->unlink($file); + } + } + + /** + * {@inheritdoc} + */ + public function create(string $type): void { + $file = $this->getFilePath($type); + $directory = dirname($file); + $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY); + $this->fileSystem->saveData('', $this->getFilePath($type), FileExists::Replace); + } + + /** + * {@inheritdoc} + */ + public function exists(string $type): bool { + $realPath = $this->fileSystem->realpath($this->getFilePath($type)); + + if ($realPath && file_exists($realPath)) { + return TRUE; + } + + return FALSE; + } + + /** + * Gets the file path. + * + * @param string $type + * Type. + * + * @return string + */ + protected function getFilePath(string $type): string { + return self::DIRECTORY . DIRECTORY_SEPARATOR . basename($type); + } + +} -- GitLab From 2fbf4cd5a365b66d05791d2dfe72b77cddfc5bf1 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 10:16:43 +0200 Subject: [PATCH 009/149] ISAICP-9041: Improve code. --- .../joinup_core/src/Commands/PrivateFileKillSwitchCommands.php | 3 --- web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php b/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php index 5027d4fb10..09c8d834f0 100644 --- a/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php +++ b/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php @@ -7,12 +7,9 @@ use Drupal\joinup_core\KillSwitchInterface; use Drush\Attributes as CLI; use Drush\Commands\DrushCommands; -use Drush\Drupal\Commands\sql\SanitizeCommands; /** * Private file kill switch commands. - * - * @see \Drush\Drupal\Commands\sql\SanitizeCommands::sanitize() */ class PrivateFileKillSwitchCommands extends DrushCommands { diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php index f7cac7f53a..f14987cc5c 100644 --- a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php +++ b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php @@ -56,6 +56,7 @@ public function exists(string $type): bool { * Type. * * @return string + * The file path. */ protected function getFilePath(string $type): string { return self::DIRECTORY . DIRECTORY_SEPARATOR . basename($type); -- GitLab From 28fa83212d97799e1020a082bb3b995d3f7157dd Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 10:47:34 +0200 Subject: [PATCH 010/149] ISAICP-9041: Change disable-eu-oss-catalogue. --- .gitignore | 2 -- .opts.yml | 4 ++-- resources/runner/drupal.yml | 2 +- tests/src/Context/JoinupOSSSolutionContext.php | 9 ++++++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ba5cdabf0c..f5e9d58a87 100644 --- a/.gitignore +++ b/.gitignore @@ -45,8 +45,6 @@ # Ignore the cookie consent killswitch. /disable-cookie-consent -# Ignore the EU OSS Catalogue killswitch. -/disable-eu-oss-catalogue # Ignore temporary and auto-generated files. /tmp/ diff --git a/.opts.yml b/.opts.yml index 2171010883..dccc5d56f5 100644 --- a/.opts.yml +++ b/.opts.yml @@ -16,14 +16,14 @@ upgrade_commands: - ./scripts/check_status_report.php append: production: - - touch disable-eu-oss-catalogue + - ./vendor/bin/drush joinup-core:kill-switch-create disable-eu-oss-catalogue acceptance: - ./vendor/bin/drush joinup-core:kill-switch-create disable-config-readonly - ./vendor/bin/drush joinup:acc - ./vendor/bin/drush cache:rebuild - ./vendor/bin/drush joinup-core:kill-switch-remove disable-config-readonly # Remove this line when deploying to POC. - - touch disable-eu-oss-catalogue + - ./vendor/bin/drush joinup-core:kill-switch-create disable-eu-oss-catalogue - ./vendor/bin/drush eu-oss:fetch developers_italia - ./vendor/bin/drush eu-oss:fetch hosting_platform:open_code - ./vendor/bin/drush queue:run eu_oss_catalogue diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml index 2fa6c819ab..c0a532aa5c 100644 --- a/resources/runner/drupal.yml +++ b/resources/runner/drupal.yml @@ -377,7 +377,7 @@ drupal: $settings['reverse_proxy'] = (bool) getenv('DRUPAL_REVERSE_PROXY_ENABLE'); $settings['reverse_proxy_addresses'] = array_filter(explode(',', (string) getenv('DRUPAL_REVERSE_PROXY_ADDRESSES'))); EU OSS Catalogue: | - $settings['eu_oss_catalogue']['enabled'] = !file_exists(getcwd() . '/../disable-eu-oss-catalogue'); + $settings['eu_oss_catalogue']['enabled'] = !file_exists($settings['file_private_path'] . '/file-switcher/disable-eu-oss-catalogue'); $settings['eu_oss_catalogue']['platform_github']['access_token'] = getenv('JOINUP_GITHUB_TOKEN'); Stage file proxy: | $config['stage_file_proxy.settings']['hotlink'] = TRUE; diff --git a/tests/src/Context/JoinupOSSSolutionContext.php b/tests/src/Context/JoinupOSSSolutionContext.php index 04b7a22877..8fba355cf0 100644 --- a/tests/src/Context/JoinupOSSSolutionContext.php +++ b/tests/src/Context/JoinupOSSSolutionContext.php @@ -62,12 +62,15 @@ public static function disableOssCron(): void { */ public function toggleEuOssCatalogue(string $toggle): void { assert(in_array($toggle, ['enable', 'disable'], TRUE)); - $file = DRUPAL_ROOT . '/../disable-eu-oss-catalogue'; + + /** @var \Drupal\joinup_core\KillSwitchInterface $killSwitch */ + $killSwitch = \Drupal::service('joinup_core.private_file_kill_switch'); + $type = 'disable-eu-oss-catalogue'; if ($toggle === 'enable') { - unlink($file); + $killSwitch->remove($type); } else { - touch($file); + $killSwitch->create($type); } \Drupal::getContainer()->get('cache.page')->deleteAll(); } -- GitLab From c1723f0d9ba156df13d4e1f37d7c77f7444a236b Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 11:31:52 +0200 Subject: [PATCH 011/149] ISAICP-9041: Make sure that permissions are set correctly. --- web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php index f14987cc5c..8238ab6be7 100644 --- a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php +++ b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php @@ -32,7 +32,7 @@ public function remove(string $type): void { public function create(string $type): void { $file = $this->getFilePath($type); $directory = dirname($file); - $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY); + $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS); $this->fileSystem->saveData('', $this->getFilePath($type), FileExists::Replace); } -- GitLab From 64a3de92acd35c863257abb3bd846d056c8d622f Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 11:39:18 +0200 Subject: [PATCH 012/149] ISAICP-9041: Reexport default settings. --- config/sync/autologout.role.interoperability_validator.yml | 3 +++ config/sync/autologout.settings.yml | 1 + 2 files changed, 4 insertions(+) create mode 100644 config/sync/autologout.role.interoperability_validator.yml diff --git a/config/sync/autologout.role.interoperability_validator.yml b/config/sync/autologout.role.interoperability_validator.yml new file mode 100644 index 0000000000..ecaef3e71e --- /dev/null +++ b/config/sync/autologout.role.interoperability_validator.yml @@ -0,0 +1,3 @@ +enabled: true +timeout: 0 +url: '' diff --git a/config/sync/autologout.settings.yml b/config/sync/autologout.settings.yml index 4e90f415f5..c6ddbb5f35 100644 --- a/config/sync/autologout.settings.yml +++ b/config/sync/autologout.settings.yml @@ -10,6 +10,7 @@ no_individual_logout_threshold: false role_logout: true role_logout_max: false redirect_url: /user/login +include_destination: false no_dialog: true message: 'Your session is about to expire. Do you want to reset it?' inactivity_message: 'You have been logged out due to inactivity.' -- GitLab From b79fbbee18756b09430af49501b3d2a985b3775a Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 11:50:01 +0200 Subject: [PATCH 013/149] ISAICP-9041: Update patch. --- composer.json | 2 +- composer.lock | 2 +- .../{3372010.diff => 3372010-29.patch} | 74 +++++++++++++++---- 3 files changed, 61 insertions(+), 17 deletions(-) rename resources/patch/php/drupal/autologout/{3372010.diff => 3372010-29.patch} (71%) diff --git a/composer.json b/composer.json index b7b97e7471..5e92505a58 100644 --- a/composer.json +++ b/composer.json @@ -289,7 +289,7 @@ "Uncaught TypeError: $(...).once is not a function @see https://www.drupal.org/project/addtocal/issues/3372354": "resources/patch/php/drupal/addtocal/3372354.patch" }, "drupal/autologout": { - "Warning: Undefined array key @see https://www.drupal.org/project/autologout/issues/3372010": "resources/patch/php/drupal/autologout/3372010.diff", + "Warning: Undefined array key @see https://www.drupal.org/project/autologout/issues/3372010": "resources/patch/php/drupal/autologout/3372010-29.patch", "Users with no roles are logged out @see https://www.drupal.org/project/autologout/issues/3443711": "resources/patch/php/drupal/autologout/3443711.diff" }, "drupal/cas_mock_server": { diff --git a/composer.lock b/composer.lock index 5342d707cb..ff2e3275a1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "611aa7faada4705d01ba368086f6006d", + "content-hash": "5982e10de7b576e1df9647ea0f3d1c90", "packages": [ { "name": "asm89/stack-cors", diff --git a/resources/patch/php/drupal/autologout/3372010.diff b/resources/patch/php/drupal/autologout/3372010-29.patch similarity index 71% rename from resources/patch/php/drupal/autologout/3372010.diff rename to resources/patch/php/drupal/autologout/3372010-29.patch index 5c78d0f96d..613337d0ee 100644 --- a/resources/patch/php/drupal/autologout/3372010.diff +++ b/resources/patch/php/drupal/autologout/3372010-29.patch @@ -1,10 +1,10 @@ diff --git a/src/EventSubscriber/AutologoutSubscriber.php b/src/EventSubscriber/AutologoutSubscriber.php -index c40f33e797579f8ed2efa5e2b065864766e14eb7..46daa9f2e7e8c3881480cdf7b2043c3c957fe93f 100644 +index c40f33e79..7ea8044f1 100644 --- a/src/EventSubscriber/AutologoutSubscriber.php +++ b/src/EventSubscriber/AutologoutSubscriber.php -@@ -118,46 +118,21 @@ class AutologoutSubscriber implements EventSubscriberInterface { +@@ -118,46 +118,22 @@ public function onRequest(RequestEvent $event) { } - + // If user is not anonymous. - if ($uid != 0) { - $session = $this->requestStack->getCurrentRequest()->getSession(); @@ -52,22 +52,60 @@ index c40f33e797579f8ed2efa5e2b065864766e14eb7..46daa9f2e7e8c3881480cdf7b2043c3c + // If http referer url has 'destination' and session is not set, + // then only redirect to user page if uid doesn't match. + if (empty($auto_redirect) && ($destination = $this->getDestination())) { -+ $match = preg_match('#^destination=(/[a-z]+)?/user/([0-9]+)$#', $destination, $matches); ++ $match = preg_match('#^destination=(/[a-z])?/user/([0-9])$#', $destination, $matches); + + if ($match && $matches[2] != $uid) { + $session->set('auto_redirect', 1); -+ $login_url = Url::fromRoute('user.page', [], ['absolute' => TRUE])->toString(); ++ $login_url = Url::fromRoute('user.page', [], ['absolute' => TRUE]) ++ ->toString(); + + // Redirect user to user page. + $response = new RedirectResponse($login_url); + $event->setResponse($response); } } - -@@ -206,4 +181,23 @@ class AutologoutSubscriber implements EventSubscriberInterface { + +@@ -170,11 +146,15 @@ public function onRequest(RequestEvent $event) { + // javascript but will keep the login alive whilst that page is opened. + $refresh_only = $autologout_manager->refreshOnly(); + $timeout = $autologout_manager->getUserTimeout(); +- $timeout_padding = $this->config->get('autologout.settings')->get('padding'); +- $is_altlogout = strpos($event->getRequest()->getRequestUri(), '/autologout_alt_logout') !== FALSE; ++ $timeout_padding = $this->config->get('autologout.settings') ++ ->get('padding'); ++ $is_altlogout = strpos($event->getRequest() ++ ->getRequestUri(), '/autologout_alt_logout') !== FALSE; + + // We need a backup plan if JS is disabled. +- $session = $this->requestStack->getCurrentRequest()->getSession()->get('autologout_last'); ++ $session = $this->requestStack->getCurrentRequest() ++ ->getSession() ++ ->get('autologout_last'); + if (!$is_altlogout && !$refresh_only && isset($session)) { + // If time since last access is > timeout + padding, log them out. + $diff = $now - $session; +@@ -189,11 +169,15 @@ public function onRequest(RequestEvent $event) { + $autologout_manager->inactivityMessage(); + } + else { +- $this->requestStack->getCurrentRequest()->getSession()->set('autologout_last', $now); ++ $this->requestStack->getCurrentRequest() ++ ->getSession() ++ ->set('autologout_last', $now); + } + } + else { +- $this->requestStack->getCurrentRequest()->getSession()->set('autologout_last', $now); ++ $this->requestStack->getCurrentRequest() ++ ->getSession() ++ ->set('autologout_last', $now); + } + } + +@@ -206,4 +190,23 @@ public static function getSubscribedEvents(): array { return $events; } - + + /** + * Get destination from referer. + * @@ -90,10 +128,10 @@ index c40f33e797579f8ed2efa5e2b065864766e14eb7..46daa9f2e7e8c3881480cdf7b2043c3c } diff --git a/tests/src/FunctionalJavascript/UserDestinationLogoutTest.php b/tests/src/FunctionalJavascript/UserDestinationLogoutTest.php new file mode 100644 -index 0000000000000000000000000000000000000000..44c0219116ed1b31f95e8b5988717453a7f058b2 +index 000000000..9edd30700 --- /dev/null +++ b/tests/src/FunctionalJavascript/UserDestinationLogoutTest.php -@@ -0,0 +1,97 @@ +@@ -0,0 +1,103 @@ +<?php + +namespace Drupal\Tests\autologout\FunctionalJavascript; @@ -109,6 +147,7 @@ index 0000000000000000000000000000000000000000..44c0219116ed1b31f95e8b5988717453 + * @group Autologout + */ +class UserDestinationLogoutTest extends WebDriverTestBase { ++ + /** + * Modules to enable. + * @@ -152,12 +191,14 @@ index 0000000000000000000000000000000000000000..44c0219116ed1b31f95e8b5988717453 + protected function setUp(): void { + parent::setUp(); + -+ $this->baseUrl = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString(); ++ $this->baseUrl = Url::fromRoute('<front>', [], ['absolute' => TRUE]) ++ ->toString(); + + $this->privilegedUser = $this->drupalCreateUser(); + $this->testUser = $this->drupalCreateUser(); + -+ $this->moduleConfig = $this->container->get('config.factory')->getEditable('autologout.settings'); ++ $this->moduleConfig = $this->container->get('config.factory') ++ ->getEditable('autologout.settings'); + + // For testing purposes set the timeout to 5 seconds. + $this->moduleConfig->set('timeout', 5)->set('padding', 2)->save(); @@ -176,18 +217,21 @@ index 0000000000000000000000000000000000000000..44c0219116ed1b31f95e8b5988717453 + self::assertTrue($this->drupalUserIsLoggedIn($this->privilegedUser)); + $this->drupalGet('user/' . $this->privilegedUser->id()); + // Used later because of the way that the url is built. -+ $user_uri = Url::fromRoute('entity.user.canonical', ['user' => $this->privilegedUser->id()])->toString(); ++ $user_uri = Url::fromRoute('entity.user.canonical', ['user' => $this->privilegedUser->id()]) ++ ->toString(); + // Wait for timeout. + $this->getSession()->wait(10000); + // Check that destination is set after logout and privilegedUser user + // is logged out. + $this->assertSession()->addressEquals($this->getUrl()); -+ $this->assertStringContainsString('/user/login?destination=' . $user_uri, $this->getSession()->getCurrentUrl()); ++ $this->assertStringContainsString('/user/login?destination=' . $user_uri, $this->getSession() ++ ->getCurrentUrl()); + self::assertFalse($this->drupalUserIsLoggedIn($this->privilegedUser)); + + // Login testUser and check that user was redirected to its own profile. + $this->drupalLogin($this->testUser); -+ $this->assertSession()->addressEquals($this->baseUrl . '/user/' . $this->testUser->id()); ++ $this->assertSession() ++ ->addressEquals($this->baseUrl . '/user/' . $this->testUser->id()); + } + +} -- GitLab From d2ffccbc54dbd01ea5e7dd65a915560c09cfd3b0 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 12:23:45 +0200 Subject: [PATCH 014/149] ISAICP-9041: Use build in methods. --- .../custom/joinup_core/src/PrivateFileKillSwitch.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php index 8238ab6be7..eb2d9a7c82 100644 --- a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php +++ b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php @@ -4,6 +4,7 @@ namespace Drupal\joinup_core; +use Drupal\Core\File\Exception\FileWriteException; use Drupal\Core\File\FileExists; use Drupal\Core\File\FileSystemInterface; @@ -31,9 +32,11 @@ public function remove(string $type): void { */ public function create(string $type): void { $file = $this->getFilePath($type); - $directory = dirname($file); - $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS); - $this->fileSystem->saveData('', $this->getFilePath($type), FileExists::Replace); + $directory = $this->fileSystem->dirname($file); + if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { + throw new FileWriteException("Could not create or write to directory '$directory'"); + } + $this->fileSystem->saveData('', $file, FileExists::Replace); } /** -- GitLab From f26f9aeb6330c6c97dd277f03c363079fcb97f32 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 12:57:20 +0200 Subject: [PATCH 015/149] ISAICP-9041: Use real path. --- .../custom/joinup_core/src/PrivateFileKillSwitch.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php index eb2d9a7c82..b1c83a6772 100644 --- a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php +++ b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php @@ -31,12 +31,12 @@ public function remove(string $type): void { * {@inheritdoc} */ public function create(string $type): void { - $file = $this->getFilePath($type); - $directory = $this->fileSystem->dirname($file); + $realPath = $this->fileSystem->realpath($this->getFilePath($type)); + $directory = $this->fileSystem->dirname($realPath); if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { throw new FileWriteException("Could not create or write to directory '$directory'"); } - $this->fileSystem->saveData('', $file, FileExists::Replace); + $this->fileSystem->saveData('', $realPath, FileExists::Replace); } /** -- GitLab From 40a9dac25f2de94458786eccd91ed00248045f47 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 12:59:13 +0200 Subject: [PATCH 016/149] ISAICP-9041: Use real path. --- web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php index b1c83a6772..e818417783 100644 --- a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php +++ b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php @@ -22,8 +22,8 @@ public function __construct(protected FileSystemInterface $fileSystem) {} */ public function remove(string $type): void { if ($this->exists($type)) { - $file = $this->getFilePath($type); - $this->fileSystem->unlink($file); + $realPath = $this->fileSystem->realpath($this->getFilePath($type)); + $this->fileSystem->unlink($realPath); } } -- GitLab From 1cb803ea200811dd47e534caff838df5e284fa88 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 14:09:35 +0200 Subject: [PATCH 017/149] ISAICP-9041: Update options. --- resources/runner/config_readonly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml index 0e0ed9729f..5afee75bce 100644 --- a/resources/runner/config_readonly.yml +++ b/resources/runner/config_readonly.yml @@ -12,7 +12,7 @@ commands: command: (test "${config_readonly}" = "1" && rm -f ${joinup.files_private_dir}/file-switcher/disable-config-readonly) || true config-readonly:disable: - - task: mkdir - dir: ${joinup.files_private_dir}/file-switcher + - task: exec + command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= - task: touch file: ${joinup.files_private_dir}/file-switcher/disable-config-readonly -- GitLab From 12eacb78c53a3ca02574801f655a574b88bea479 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 14:52:08 +0200 Subject: [PATCH 018/149] ISAICP-9041: Dont use drush command. --- .opts.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.opts.yml b/.opts.yml index dccc5d56f5..189ddb70ba 100644 --- a/.opts.yml +++ b/.opts.yml @@ -5,13 +5,13 @@ # See \EcEuropa\Toolkit\TaskRunner\Commands\CloneCommands::runDeploy(). upgrade_commands: default: - - ./vendor/bin/drush joinup-core:kill-switch-create disable-config-readonly + - ./vendor/bin/run config-readonly:disable - ./vendor/bin/drush deploy --yes - ./vendor/bin/drush search-api:reset-tracker --yes - ./vendor/bin/drush joinup:node-access-rebuild - ./vendor/bin/drush joinup:search-api-tasks - ./vendor/bin/drush twigc --yes - - ./vendor/bin/drush joinup-core:kill-switch-remove disable-config-readonly + - ./vendor/bin/run config-readonly:enable - ./vendor/bin/drush joinup:unpublish-alert --category - ./scripts/check_status_report.php append: -- GitLab From 0ece4abaaf9aaeeeded6cdec431d1b37bf73f2e9 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 15:08:01 +0200 Subject: [PATCH 019/149] ISAICP-9041: Don't use drush directly. --- .opts.yml | 12 ++++++------ resources/runner/config_readonly.yml | 6 ++++++ resources/runner/eu_oss_catalogue.yml | 7 +++++++ 3 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 resources/runner/eu_oss_catalogue.yml diff --git a/.opts.yml b/.opts.yml index 189ddb70ba..aa3dd11a0e 100644 --- a/.opts.yml +++ b/.opts.yml @@ -16,23 +16,23 @@ upgrade_commands: - ./scripts/check_status_report.php append: production: - - ./vendor/bin/drush joinup-core:kill-switch-create disable-eu-oss-catalogue + - ./vendor/bin/run config-readonly:disable acceptance: - - ./vendor/bin/drush joinup-core:kill-switch-create disable-config-readonly + - ./vendor/bin/run config-readonly:disable - ./vendor/bin/drush joinup:acc - ./vendor/bin/drush cache:rebuild - - ./vendor/bin/drush joinup-core:kill-switch-remove disable-config-readonly + - ./vendor/bin/run config-readonly:enable # Remove this line when deploying to POC. - - ./vendor/bin/drush joinup-core:kill-switch-create disable-eu-oss-catalogue + - ./vendor/bin/run eu-oss-catalogue:disable - ./vendor/bin/drush eu-oss:fetch developers_italia - ./vendor/bin/drush eu-oss:fetch hosting_platform:open_code - ./vendor/bin/drush queue:run eu_oss_catalogue - ./vendor/bin/drush queue:run joinup_oss_catalogue_imagecache_warmer ephemeral: - - ./vendor/bin/drush joinup-core:kill-switch-create disable-config-readonly + - ./vendor/bin/run config-readonly:disable - ./vendor/bin/drush joinup:acc - ./vendor/bin/drush cache:rebuild - - ./vendor/bin/drush joinup-core:kill-switch-remove disable-config-readonly + - ./vendor/bin/run config-readonly:enable - ./vendor/bin/drush eu-oss:fetch developers_italia - ./vendor/bin/drush eu-oss:fetch hosting_platform:open_code - ./vendor/bin/drush queue:run eu_oss_catalogue diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml index 5afee75bce..a3e00fc290 100644 --- a/resources/runner/config_readonly.yml +++ b/resources/runner/config_readonly.yml @@ -16,3 +16,9 @@ commands: command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= - task: touch file: ${joinup.files_private_dir}/file-switcher/disable-config-readonly + + eu-oss-catalogue:disable: + - task: exec + command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= + - task: touch + file: ${joinup.files_private_dir}/file-switcher/disable-eu-oss-catalogue diff --git a/resources/runner/eu_oss_catalogue.yml b/resources/runner/eu_oss_catalogue.yml new file mode 100644 index 0000000000..f27e4650c6 --- /dev/null +++ b/resources/runner/eu_oss_catalogue.yml @@ -0,0 +1,7 @@ +commands: + + eu-oss-catalogue:disable: + - task: exec + command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= + - task: touch + file: ${joinup.files_private_dir}/file-switcher/disable-eu-oss-catalogue -- GitLab From 124e96b2af35a4e20ca3bb145c45124bf72060ee Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 15:09:01 +0200 Subject: [PATCH 020/149] ISAICP-9041: Don't duplicate. --- resources/runner/config_readonly.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml index a3e00fc290..5afee75bce 100644 --- a/resources/runner/config_readonly.yml +++ b/resources/runner/config_readonly.yml @@ -16,9 +16,3 @@ commands: command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= - task: touch file: ${joinup.files_private_dir}/file-switcher/disable-config-readonly - - eu-oss-catalogue:disable: - - task: exec - command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= - - task: touch - file: ${joinup.files_private_dir}/file-switcher/disable-eu-oss-catalogue -- GitLab From 4bcebc6f103b80009789e4014b75550282f488c5 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 15:20:42 +0200 Subject: [PATCH 021/149] ISAICP-9041: Remove not used drush commands. --- resources/runner/eu_oss_catalogue.yml | 4 ++ .../custom/joinup_core/drush.services.yml | 6 --- .../PrivateFileKillSwitchCommands.php | 44 ------------------- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php diff --git a/resources/runner/eu_oss_catalogue.yml b/resources/runner/eu_oss_catalogue.yml index f27e4650c6..ec02e2ea9c 100644 --- a/resources/runner/eu_oss_catalogue.yml +++ b/resources/runner/eu_oss_catalogue.yml @@ -1,5 +1,9 @@ commands: + eu-oss-catalogue:enable: + - task: exec + command: rm -f ${joinup.files_private_dir}/file-switcher/disable-eu-oss-catalogue + eu-oss-catalogue:disable: - task: exec command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= diff --git a/web/modules/custom/joinup_core/drush.services.yml b/web/modules/custom/joinup_core/drush.services.yml index 4a58b6cd24..13d4271222 100644 --- a/web/modules/custom/joinup_core/drush.services.yml +++ b/web/modules/custom/joinup_core/drush.services.yml @@ -4,9 +4,3 @@ services: arguments: [ '@database', '@entity_field.manager', '@entity_type.manager', '@keyvalue', '@plugin.manager.field.field_type' ] tags: - { name: drush.command } - - joinup_core.private_file_kill_switch.commands: - class: Drupal\joinup_core\Commands\PrivateFileKillSwitchCommands - arguments: [ '@joinup_core.private_file_kill_switch' ] - tags: - - { name: drush.command } diff --git a/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php b/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php deleted file mode 100644 index 09c8d834f0..0000000000 --- a/web/modules/custom/joinup_core/src/Commands/PrivateFileKillSwitchCommands.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\joinup_core\Commands; - -use Drupal\joinup_core\KillSwitchInterface; -use Drush\Attributes as CLI; -use Drush\Commands\DrushCommands; - -/** - * Private file kill switch commands. - */ -class PrivateFileKillSwitchCommands extends DrushCommands { - - public function __construct(protected KillSwitchInterface $killSwitch) { - parent::__construct(); - } - - /** - * Enable switch. - */ - #[CLI\Command(name: 'joinup-core:kill-switch-remove')] - #[CLI\Argument(name: 'type', description: 'The switch type')] - public function killSwitchRemove(string $type): string { - $this->killSwitch->remove($type); - return dt('Removed @type file', [ - '@type' => $type, - ]); - } - - /** - * Disable switch. - */ - #[CLI\Command(name: 'joinup-core:kill-switch-create')] - #[CLI\Argument(name: 'type', description: 'The switch type')] - public function killSwitchCreate(string $type): string { - $this->killSwitch->create($type); - return dt('Created @type file', [ - '@type' => $type, - ]); - } - -} -- GitLab From efc70173788e730cb07f77ef5455975f1236aa2c Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 30 Aug 2024 15:57:13 +0200 Subject: [PATCH 022/149] ISAICP-9041: Update logout settings. --- config/sync/autologout.settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sync/autologout.settings.yml b/config/sync/autologout.settings.yml index c6ddbb5f35..fee594052b 100644 --- a/config/sync/autologout.settings.yml +++ b/config/sync/autologout.settings.yml @@ -8,7 +8,7 @@ padding: 20 logout_regardless_of_activity: false no_individual_logout_threshold: false role_logout: true -role_logout_max: false +role_logout_max: true redirect_url: /user/login include_destination: false no_dialog: true -- GitLab From b346c0155e8927c0c487ef9c2056618e2e16f0ab Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 2 Sep 2024 08:04:52 +0200 Subject: [PATCH 023/149] ISAICP-9041: Disable OSs instead of config read only. --- .opts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.opts.yml b/.opts.yml index aa3dd11a0e..5339b9e774 100644 --- a/.opts.yml +++ b/.opts.yml @@ -16,7 +16,7 @@ upgrade_commands: - ./scripts/check_status_report.php append: production: - - ./vendor/bin/run config-readonly:disable + - ./vendor/bin/run eu-oss-catalogue:disable acceptance: - ./vendor/bin/run config-readonly:disable - ./vendor/bin/drush joinup:acc -- GitLab From 677ee8193dc8fa2b247ee16eb6bddab6de7e705f Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 2 Sep 2024 08:08:48 +0200 Subject: [PATCH 024/149] ISAICP-9041: Rename directory. --- resources/runner/config_readonly.yml | 6 +++--- resources/runner/drupal.yml | 4 ++-- resources/runner/eu_oss_catalogue.yml | 6 +++--- tests/src/Traits/ConfigReadOnlyTrait.php | 2 +- .../custom/joinup_core/src/PrivateFileKillSwitch.php | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml index 5afee75bce..4b043854e2 100644 --- a/resources/runner/config_readonly.yml +++ b/resources/runner/config_readonly.yml @@ -9,10 +9,10 @@ commands: # Config readonly kill-switch. config-readonly:enable: - task: exec - command: (test "${config_readonly}" = "1" && rm -f ${joinup.files_private_dir}/file-switcher/disable-config-readonly) || true + command: (test "${config_readonly}" = "1" && rm -f ${joinup.files_private_dir}/kill-switch/disable-config-readonly) || true config-readonly:disable: - task: exec - command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= + command: mkdir ${joinup.files_private_dir}/kill-switch -p -m ug=rwx,o= - task: touch - file: ${joinup.files_private_dir}/file-switcher/disable-config-readonly + file: ${joinup.files_private_dir}/kill-switch/disable-config-readonly diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml index 5dffb58c5c..511c45b338 100644 --- a/resources/runner/drupal.yml +++ b/resources/runner/drupal.yml @@ -245,7 +245,7 @@ drupal: ]; // Location of the site configuration files. $settings['config_sync_directory'] = '../config/sync'; - $settings['config_readonly'] = !file_exists($settings['file_private_path'] . '/file-switcher/disable-config-readonly'); + $settings['config_readonly'] = !file_exists($settings['file_private_path'] . '/kill-switch/disable-config-readonly'); Testing configuration alters: | // The video from the home page interacts with Selenium tests. $config['page_manager.page_variant.homepage-layout_builder-0']['variant_settings']['sections'][4]['components']['6ab0ceea-4541-4153-8b64-227e02369d30']['configuration']['text'] = 'Some joinup video'; @@ -380,7 +380,7 @@ drupal: $settings['reverse_proxy'] = (bool) getenv('DRUPAL_REVERSE_PROXY_ENABLE'); $settings['reverse_proxy_addresses'] = array_filter(explode(',', (string) getenv('DRUPAL_REVERSE_PROXY_ADDRESSES'))); EU OSS Catalogue: | - $settings['eu_oss_catalogue']['enabled'] = !file_exists($settings['file_private_path'] . '/file-switcher/disable-eu-oss-catalogue'); + $settings['eu_oss_catalogue']['enabled'] = !file_exists($settings['file_private_path'] . '/kill-switch/disable-eu-oss-catalogue'); $settings['eu_oss_catalogue']['platform_github']['access_token'] = getenv('JOINUP_GITHUB_TOKEN'); Stage file proxy: | $config['stage_file_proxy.settings']['hotlink'] = TRUE; diff --git a/resources/runner/eu_oss_catalogue.yml b/resources/runner/eu_oss_catalogue.yml index ec02e2ea9c..f3873f962a 100644 --- a/resources/runner/eu_oss_catalogue.yml +++ b/resources/runner/eu_oss_catalogue.yml @@ -2,10 +2,10 @@ commands: eu-oss-catalogue:enable: - task: exec - command: rm -f ${joinup.files_private_dir}/file-switcher/disable-eu-oss-catalogue + command: rm -f ${joinup.files_private_dir}/kill-switch/disable-eu-oss-catalogue eu-oss-catalogue:disable: - task: exec - command: mkdir ${joinup.files_private_dir}/file-switcher -p -m ug=rwx,o= + command: mkdir ${joinup.files_private_dir}/kill-switch -p -m ug=rwx,o= - task: touch - file: ${joinup.files_private_dir}/file-switcher/disable-eu-oss-catalogue + file: ${joinup.files_private_dir}/kill-switch/disable-eu-oss-catalogue diff --git a/tests/src/Traits/ConfigReadOnlyTrait.php b/tests/src/Traits/ConfigReadOnlyTrait.php index f852a4c297..90231dfbf0 100644 --- a/tests/src/Traits/ConfigReadOnlyTrait.php +++ b/tests/src/Traits/ConfigReadOnlyTrait.php @@ -74,7 +74,7 @@ protected static function checkConfigReadOnlyKillSwitch(): void { /** @var \Drupal\Core\DrupalKernelInterface $kernel */ $kernel = \Drupal::service('kernel'); $site_path = $kernel->getSitePath(); - $needle = "\$settings['config_readonly'] = !file_exists(\$settings['file_private_path'] . '/file-switcher/disable-config-readonly');"; + $needle = "\$settings['config_readonly'] = !file_exists(\$settings['file_private_path'] . '/kill-switch/disable-config-readonly');"; $settings_php = file_get_contents("{$site_path}/settings.php"); if (strpos($settings_php, $needle) === FALSE) { throw new \Exception("The following line is missing from web/sites/default/settings.php\n$needle"); diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php index e818417783..756015aca8 100644 --- a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php +++ b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php @@ -13,7 +13,7 @@ */ class PrivateFileKillSwitch implements KillSwitchInterface { - const string DIRECTORY = 'private://file-switcher'; + const string DIRECTORY = 'private://kill-switch'; public function __construct(protected FileSystemInterface $fileSystem) {} -- GitLab From 9d5d92f93de08bdb385367307faec0476ca4d76c Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Mon, 2 Sep 2024 00:23:33 +0200 Subject: [PATCH 025/149] ISAICP-8479: When adding a OSS platform, settings should start always empty. --- .../eu_oss_catalogue/src/Form/HostingPlatformConfigForm.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/src/Form/HostingPlatformConfigForm.php b/web/modules/custom/eu_oss_catalogue/src/Form/HostingPlatformConfigForm.php index f8e33e57a6..46ba6435dc 100644 --- a/web/modules/custom/eu_oss_catalogue/src/Form/HostingPlatformConfigForm.php +++ b/web/modules/custom/eu_oss_catalogue/src/Form/HostingPlatformConfigForm.php @@ -158,7 +158,9 @@ protected function askPluginToAct(string $method, ?string $platformId, array &$f // Pass also the entity as plugin configuration for plugins that might // need it. It's removed from configuration on form submit. 'hosting_platform' => $this->getEntity(), - ] + $this->getEntity()->getPlatformSettings()); + ] + + // Pass the settings if the platform already exists. + ($this->getEntity()->isNew() ? [] : $this->getEntity()->getPlatformSettings())); // This plugin doesn't support forms. if (!$plugin instanceof PluginFormInterface) { -- GitLab From d21389df0c1c7c4cd65eb6b9af6a8ef7c40b5a81 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 10:32:19 +0300 Subject: [PATCH 026/149] ISAICP-9041: Split part of MR scope to ISAICP-9052. --- composer.lock | 2 +- resources/runner/config_readonly.yml | 18 ----- resources/runner/drupal.yml | 4 -- resources/runner/eu_oss_catalogue.yml | 11 --- .../custom/joinup_core/drush.services.yml | 2 +- .../joinup_core/src/KillSwitchInterface.php | 39 ----------- .../joinup_core/src/PrivateFileKillSwitch.php | 68 ------------------- 7 files changed, 2 insertions(+), 142 deletions(-) delete mode 100644 resources/runner/config_readonly.yml delete mode 100644 resources/runner/eu_oss_catalogue.yml delete mode 100644 web/modules/custom/joinup_core/src/KillSwitchInterface.php delete mode 100644 web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php diff --git a/composer.lock b/composer.lock index ff2e3275a1..4aa2c53286 100644 --- a/composer.lock +++ b/composer.lock @@ -24917,7 +24917,7 @@ "version": "2.x-dev", "source": { "type": "git", - "url": "https://git.drupalcode.org/project/dtt/", + "url": "https://git.drupalcode.org/project/dtt.git", "reference": "5e3df23c93f4f3e4f34fd7677df10bc06616f4ce" }, "require": { diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml deleted file mode 100644 index 4b043854e2..0000000000 --- a/resources/runner/config_readonly.yml +++ /dev/null @@ -1,18 +0,0 @@ -# Config readonly settings and commands. - -# Set this config to `false` in your runner.yml to permanently disable the -# config read-only feature on your development environment. -config_readonly: true - -commands: - - # Config readonly kill-switch. - config-readonly:enable: - - task: exec - command: (test "${config_readonly}" = "1" && rm -f ${joinup.files_private_dir}/kill-switch/disable-config-readonly) || true - - config-readonly:disable: - - task: exec - command: mkdir ${joinup.files_private_dir}/kill-switch -p -m ug=rwx,o= - - task: touch - file: ${joinup.files_private_dir}/kill-switch/disable-config-readonly diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml index 53a9cafe42..7a4a0c6473 100644 --- a/resources/runner/drupal.yml +++ b/resources/runner/drupal.yml @@ -380,11 +380,7 @@ drupal: $settings['reverse_proxy'] = (bool) getenv('DRUPAL_REVERSE_PROXY_ENABLE'); $settings['reverse_proxy_addresses'] = array_filter(explode(',', (string) getenv('DRUPAL_REVERSE_PROXY_ADDRESSES'))); EU OSS Catalogue: | -<<<<<<< HEAD - $settings['eu_oss_catalogue']['enabled'] = !file_exists($settings['file_private_path'] . '/kill-switch/disable-eu-oss-catalogue'); -======= $settings['eu_oss_catalogue']['enabled'] = !file_exists(getenv('DRUPAL_PRIVATE_FILE_SYSTEM') . '/killswitch/disable-eu-oss-catalogue'); ->>>>>>> origin/develop $settings['eu_oss_catalogue']['platform_github']['access_token'] = getenv('JOINUP_GITHUB_TOKEN'); Stage file proxy: | $config['stage_file_proxy.settings']['hotlink'] = TRUE; diff --git a/resources/runner/eu_oss_catalogue.yml b/resources/runner/eu_oss_catalogue.yml deleted file mode 100644 index f3873f962a..0000000000 --- a/resources/runner/eu_oss_catalogue.yml +++ /dev/null @@ -1,11 +0,0 @@ -commands: - - eu-oss-catalogue:enable: - - task: exec - command: rm -f ${joinup.files_private_dir}/kill-switch/disable-eu-oss-catalogue - - eu-oss-catalogue:disable: - - task: exec - command: mkdir ${joinup.files_private_dir}/kill-switch -p -m ug=rwx,o= - - task: touch - file: ${joinup.files_private_dir}/kill-switch/disable-eu-oss-catalogue diff --git a/web/modules/custom/joinup_core/drush.services.yml b/web/modules/custom/joinup_core/drush.services.yml index 13d4271222..cc9c1391d4 100644 --- a/web/modules/custom/joinup_core/drush.services.yml +++ b/web/modules/custom/joinup_core/drush.services.yml @@ -1,6 +1,6 @@ services: joinup_core.sanitize.commands: class: Drupal\joinup_core\Commands\JoinupDataSanitizationCommands - arguments: [ '@database', '@entity_field.manager', '@entity_type.manager', '@keyvalue', '@plugin.manager.field.field_type' ] + arguments: ['@database', '@entity_field.manager', '@entity_type.manager', '@keyvalue', '@plugin.manager.field.field_type'] tags: - { name: drush.command } diff --git a/web/modules/custom/joinup_core/src/KillSwitchInterface.php b/web/modules/custom/joinup_core/src/KillSwitchInterface.php deleted file mode 100644 index b899489a7f..0000000000 --- a/web/modules/custom/joinup_core/src/KillSwitchInterface.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\joinup_core; - -/** - * Kill switch. - */ -interface KillSwitchInterface { - - /** - * Checks if the switch exists. - * - * @param string $type - * Type. - * - * @return bool - * Returns true if the switch exists, false otherwise. - */ - public function exists(string $type): bool; - - /** - * Create switch. - * - * @param string $type - * Type. - */ - public function create(string $type): void; - - /** - * Remove switch. - * - * @param string $type - * Type. - */ - public function remove(string $type): void; - -} diff --git a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php b/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php deleted file mode 100644 index 756015aca8..0000000000 --- a/web/modules/custom/joinup_core/src/PrivateFileKillSwitch.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\joinup_core; - -use Drupal\Core\File\Exception\FileWriteException; -use Drupal\Core\File\FileExists; -use Drupal\Core\File\FileSystemInterface; - -/** - * Private file kill switch. - */ -class PrivateFileKillSwitch implements KillSwitchInterface { - - const string DIRECTORY = 'private://kill-switch'; - - public function __construct(protected FileSystemInterface $fileSystem) {} - - /** - * {@inheritdoc} - */ - public function remove(string $type): void { - if ($this->exists($type)) { - $realPath = $this->fileSystem->realpath($this->getFilePath($type)); - $this->fileSystem->unlink($realPath); - } - } - - /** - * {@inheritdoc} - */ - public function create(string $type): void { - $realPath = $this->fileSystem->realpath($this->getFilePath($type)); - $directory = $this->fileSystem->dirname($realPath); - if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { - throw new FileWriteException("Could not create or write to directory '$directory'"); - } - $this->fileSystem->saveData('', $realPath, FileExists::Replace); - } - - /** - * {@inheritdoc} - */ - public function exists(string $type): bool { - $realPath = $this->fileSystem->realpath($this->getFilePath($type)); - - if ($realPath && file_exists($realPath)) { - return TRUE; - } - - return FALSE; - } - - /** - * Gets the file path. - * - * @param string $type - * Type. - * - * @return string - * The file path. - */ - protected function getFilePath(string $type): string { - return self::DIRECTORY . DIRECTORY_SEPARATOR . basename($type); - } - -} -- GitLab From 9d5cd330fd0cd9269ecd2ef1f30828df65ff4e30 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Wed, 4 Sep 2024 19:54:25 +0300 Subject: [PATCH 027/149] ISAICP-9045: Remove applied updates. --- .../joinup_oss_catalogue.deploy.php | 136 ------------------ .../joinup_oss_catalogue.install | 32 ----- .../custom/joinup_core/joinup_core.install | 119 --------------- .../custom/joinup_log/joinup_log.install | 39 ----- 4 files changed, 326 deletions(-) delete mode 100644 web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.deploy.php delete mode 100644 web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install delete mode 100644 web/modules/custom/joinup_log/joinup_log.install diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.deploy.php b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.deploy.php deleted file mode 100644 index 265203b6ed..0000000000 --- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.deploy.php +++ /dev/null @@ -1,136 +0,0 @@ -<?php - -/** - * @file - * Deploy functions for Joinup OSS. - */ - -declare(strict_types=1); - -use Drupal\Core\Url; -use Drupal\joinup_oss_catalogue\OssCatalogueCollectionInterface; - -/** - * Update path alias for EU OSS catalogue. - */ -function joinup_oss_catalogue_deploy_111200(): void { - /** @var \Drupal\collection\Entity\CollectionInterface $collection */ - $collection = \Drupal::entityTypeManager()->getStorage('rdf_entity') - ->load(OssCatalogueCollectionInterface::COLLECTION_ENTITY_ID); - $collection - ?->set('path', ['alias' => '/eu-oss-catalogue', 'pathauto' => 0]) - ->save(); -} - -/** - * Update title of EU OSS catalogue collection. - */ -function joinup_oss_catalogue_deploy_111201(): void { - /** @var \Drupal\collection\Entity\CollectionInterface $collection */ - $collection = \Drupal::entityTypeManager()->getStorage('rdf_entity') - ->load(OssCatalogueCollectionInterface::COLLECTION_ENTITY_ID); - - $collection - ?->set('label', 'EU Open Source Solutions Catalogue') - ->save(); -} - -/** - * Import content for EU OpenSource Software Solutions Catalogue. - */ -function joinup_oss_catalogue_deploy_111202(): void { - /** @var \Drupal\Core\Extension\ModuleInstallerInterface $moduleInstaller */ - $moduleInstaller = \Drupal::service('module_installer'); - /** @var \Drupal\Core\Entity\EntityRepositoryInterface $entityRepository */ - $entityRepository = \Drupal::service('entity.repository'); - - // Delete faulty meta entity. - $entityRepository - ->loadEntityByUuid('meta_entity', 'ad9be48e-7116-44b3-8df2-db8cb9343268') - ?->delete(); - - // Import content. - $moduleInstaller->install(['default_content']); - /** @var \Drupal\default_content\ImporterInterface $importer */ - \Drupal::service('default_content.importer') - ->importContent('joinup_oss_catalogue', TRUE); - $moduleInstaller->uninstall(['default_content']); - - // Disable auto-created left-side menu link. - $landingPage = $entityRepository->loadEntityByUuid('node', '54acbd6f-47f0-4280-ad09-0a07c397318b'); - $linkPlugins = \Drupal::service('plugin.manager.menu.link') - ->loadLinksByRoute('entity.node.canonical', ['node' => $landingPage->id()], 'ogmenu-3728'); - /** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $linkPlugin */ - $linkPlugin = reset($linkPlugins); - $entityRepository - ->loadEntityByUuid('menu_link_content', $linkPlugin->getDerivativeId()) - ->setUnpublished() - ->save(); -} - -/** - * Rename menu items for EU OSS catalogue. - */ -function joinup_oss_catalogue_deploy_111203(): void { - $entityTypeManager = \Drupal::entityTypeManager(); - /** @var \Drupal\menu_link_content\MenuLinkContentStorageInterface $menuLinkContentStorage */ - $menuLinkContentStorage = $entityTypeManager->getStorage('menu_link_content'); - - $menuName = 'ogmenu-3728'; - // Collect the IDs of links to the custom page. - $ids = $menuLinkContentStorage->getQuery()->accessCheck(FALSE) - ->condition('bundle', 'menu_link_content') - ->condition('menu_name', $menuName) - ->execute(); - - $links = $menuLinkContentStorage->loadMultiple($ids); - foreach ($links as $link) { - $title = $link->getTitle(); - if ($title === 'About' || $title === 'Members') { - $link->setUnpublished()->save(); - } - elseif ($title === 'Overview') { - $link->set('title', 'Welcome')->save(); - } - } - $link = [ - 'uri' => Url::fromRoute('view.search_oss_catalogue.search')->toUriString(), - ]; - $menuLinkContentStorage->create([ - 'title' => t('Search'), - 'menu_name' => $menuName, - 'link' => $link, - 'weight' => -6, - ])->save(); -} - -/** - * Make sure that oss_archived has a default value. - */ -function joinup_oss_catalogue_deploy_111204(array &$sandbox): string { - $entityTypeManager = \Drupal::entityTypeManager(); - /** @var \Drupal\node\NodeStorage $nodeStorage */ - $nodeStorage = $entityTypeManager->getStorage('node'); - - if (empty($sandbox['ids'])) { - $results = $nodeStorage->getQuery()->accessCheck(FALSE) - ->condition('type', 'oss_solution') - ->notExists('oss_archived') - ->execute(); - - $sandbox['ids'] = array_values($results); - $sandbox['progress'] = 0; - $sandbox['count'] = count($sandbox['ids']); - } - - $ids = array_splice($sandbox['ids'], 0, 50); - foreach ($nodeStorage->loadMultiple($ids) as $solution) { - $solution->set('oss_archived', 0); - $solution->save(); - } - - $sandbox['progress'] += count($ids); - $sandbox['#finished'] = (int) empty($sandbox['ids']); - - return "Processed {$sandbox['progress']} out of {$sandbox['count']} solutions."; -} diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install deleted file mode 100644 index f811958465..0000000000 --- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -/** - * @file - * Install, update, and uninstall functions for the Joinup OSS module. - */ - -declare(strict_types=1); - -use Drupal\Core\Serialization\Yaml; - -/** - * Pre-creates OSS vocabularies. - */ -function joinup_oss_catalogue_update_111200(): void { - // Pre-create the new controlled vocabularies provided by eu_oss_catalogue - // module. Normally, these are imported as config but eu_oss_catalogue install - // goes first and its install process is also populating them with terms, so - // they should be available at that point. - $config_factory = \Drupal::configFactory(); - foreach ([ - 'category', - 'licence', - 'intended_audience_scope', - 'software_type', - ] as $vocab) { - $name = "taxonomy.vocabulary.oss_$vocab"; - $config_factory->getEditable($name) - ->setData(Yaml::decode(file_get_contents(DRUPAL_ROOT . "/../config/sync/$name.yml"))) - ->save(); - } -} diff --git a/web/modules/custom/joinup_core/joinup_core.install b/web/modules/custom/joinup_core/joinup_core.install index fabb9b35dc..823aea261c 100644 --- a/web/modules/custom/joinup_core/joinup_core.install +++ b/web/modules/custom/joinup_core/joinup_core.install @@ -7,11 +7,7 @@ declare(strict_types=1); -use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Site\Settings; -use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface; -use Drupal\node\Entity\Node; -use Drupal\paragraphs\Entity\Paragraph; use Drupal\user\Entity\User; /** @@ -96,118 +92,3 @@ function joinup_core_requirements($phase): array { return $requirements; } - -/** - * Convert videos into document. - */ -function joinup_core_update_111200(array &$sandbox): string { - if (!isset($sandbox['video_nids'])) { - // Collect all video nodes to migrate. - $video_nids = \Drupal::entityQuery('node') - ->accessCheck(FALSE) - ->condition('type', 'video') - ->execute(); - - $sandbox['max'] = count($video_nids); - $sandbox['count'] = 0; - $sandbox['video_nids'] = $video_nids; - } - - // Load video nodes. - $video_nids = array_slice($sandbox['video_nids'], $sandbox['count'], 20); - $entity_type_manager = \Drupal::entityTypeManager(); - $video_nodes = $entity_type_manager->getStorage('node')->loadMultiple($video_nids); - - /** @var \Drupal\redirect\RedirectRepository $redirect_repository */ - $redirect_repository = \Drupal::service('redirect.repository'); - - // Migrate each video. - foreach ($video_nodes as $video_node) { - // Find redirects to the video node to preserve after deletion. - /* @see redirect_entity_delete */ - $redirects = $redirect_repository->findByDestinationUri([ - "internal:/node/{$video_node->id()}", - "entity:node/{$video_node->id()}", - ]); - - // Prepare new document node. - $formatted_date = (new DrupalDateTime())->setTimestamp($video_node->getCreatedTime())->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT); - $created_time = $video_node->getCreatedTime(); - $document_node = Node::create([ - 'type' => 'document', - 'nid' => $video_node->id(), - 'title' => $video_node->getTitle(), - 'uid' => $video_node->getOwnerId(), - 'status' => $video_node->isPublished(), - 'created' => $created_time, - 'changed' => $video_node->getChangedTime(), - 'og_audience' => $video_node->get('og_audience')->target_id, - 'field_document_spatial_coverage' => $video_node->get('field_video_spatial_coverage')->target_id, - 'field_keywords' => $video_node->get('field_keywords')->getValue(), - 'field_document_publication_date' => $formatted_date, - 'published_at' => $created_time, - 'field_state' => 'published', - ]); - - $layout_paragraph = Paragraph::create(['type' => 'layout']); - $layout_paragraph->setBehaviorSettings('layout_paragraphs', [ - 'layout' => 'layout_onecol', - 'config' => ['label' => ''], - 'parent_uuid' => NULL, - 'region' => NULL, - ]); - - $body_paragraph = Paragraph::create([ - 'type' => 'text', - 'field_body' => [ - 'value' => $video_node->get('body')->value, - 'format' => 'text_html', - ], - ]); - $body_paragraph->setBehaviorSettings('layout_paragraphs', [ - 'parent_uuid' => $layout_paragraph->uuid(), - 'region' => 'content', - ]); - - $video_paragraph = Paragraph::create([ - 'type' => 'video', - 'paragraph_video_url' => $video_node->get('field_video')->getValue(), - ]); - $video_paragraph->setBehaviorSettings('layout_paragraphs', [ - 'parent_uuid' => $layout_paragraph->uuid(), - 'region' => 'content', - ]); - - $document_node->set('field_paragraphs_body', [ - ['entity' => $layout_paragraph], - ['entity' => $body_paragraph], - ['entity' => $video_paragraph], - ]); - - // Delete video node. - $video_node->delete(); - - // Save new document node. - // Create 2 revisions (1 published and 1 archived); un-archiving requires a - // previous published revision otherwise a fatal error occurs. - /* @see \Drupal\joinup_workflow\WorkflowHelper::unarchiveEntity */ - $document_node->setRevisionCreationTime($created_time); - $document_node->skip_notification = TRUE; - $document_node->save(); - - $document_node->set('field_state', 'archived'); - $document_node->setNewRevision(); - $document_node->skip_notification = TRUE; - $document_node->save(); - - // Restore redirects. - foreach ($redirects as $redirect) { - $redirect->createDuplicate()->save(); - } - - $sandbox['count']++; - } - - $sandbox['#finished'] = $sandbox['count'] === $sandbox['max']; - return "{$sandbox['count']} out of {$sandbox['max']} video nodes processed."; -} diff --git a/web/modules/custom/joinup_log/joinup_log.install b/web/modules/custom/joinup_log/joinup_log.install deleted file mode 100644 index 5066d9fb68..0000000000 --- a/web/modules/custom/joinup_log/joinup_log.install +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -/** - * @file - * Install and update hooks. - */ - -declare(strict_types=1); - -use Drupal\Core\Field\BaseFieldDefinition; -use Drupal\Core\StringTranslation\TranslatableMarkup; - -/** - * Add the `variables` field. - */ -function joinup_log_update_111200(): TranslatableMarkup { - $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); - - $field = BaseFieldDefinition::create('map') - ->setLabel(new TranslatableMarkup('Variables')) - ->setDefaultValue(serialize([])) - ->setDescription(new TranslatableMarkup('Serialized array of variables that match the message string and that is passed into the t() function.')); - $definition_update_manager->installFieldStorageDefinition('variables', 'joinup_log', 'joinup_log', $field); - - return t('The variables fields have been added to Joinup log.'); -} - -/** - * Set the `variables` field. - */ -function joinup_log_update_111201(): TranslatableMarkup { - $query = \Drupal::database()->update('joinup_log') - ->fields([ - 'variables' => serialize([]), - ]); - $query->execute(); - - return t('Updated Joinup log entities.'); -} -- GitLab From 2afafbeb2b8d243e3b81588c8c366c5f196a0695 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Wed, 4 Sep 2024 19:57:21 +0300 Subject: [PATCH 028/149] ISAICP-9045: Update Node dependencies. --- package-lock.json | 303 ++++++++++++++++++++++++---------------------- 1 file changed, 156 insertions(+), 147 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd3daa9f22..aa256b4117 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "hasInstallScript": true, "license": "EUPL-1.2", "dependencies": { - "jquery-jsonview": "^1.2.3", "@glidejs/glide": "^3.6.0", "dompurify": "^3.0.9", "jquery-colorbox": "^1.6.4", @@ -77,9 +76,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -116,12 +115,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "dependencies": { - "@babel/types": "^7.25.0", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -172,9 +171,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", - "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", @@ -182,7 +181,7 @@ "@babel/helper-optimise-call-expression": "^7.24.7", "@babel/helper-replace-supers": "^7.25.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.0", + "@babel/traverse": "^7.25.4", "semver": "^6.3.1" }, "engines": { @@ -392,13 +391,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "dependencies": { "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -420,12 +419,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.25.2" + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -559,12 +558,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -574,12 +573,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -746,15 +745,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", - "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-remap-async-to-generator": "^7.25.0", "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/traverse": "^7.25.0" + "@babel/traverse": "^7.25.4" }, "engines": { "node": ">=6.9.0" @@ -811,13 +810,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -844,16 +843,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", - "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-replace-supers": "^7.25.0", - "@babel/traverse": "^7.25.0", + "@babel/traverse": "^7.25.4", "globals": "^11.1.0" }, "engines": { @@ -1281,13 +1280,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1484,13 +1483,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1642,16 +1641,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1660,9 +1659,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.8", @@ -2583,6 +2582,12 @@ } } }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", @@ -2632,12 +2637,12 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.3.tgz", + "integrity": "sha512-njripolh85IA9SQGTAqbmnNZTdxv7X/4OYGPz8tgy5JDr8MP+uDBa921GpYEoDDnwm0Hmn5ZPeJgiiSTPoOzkQ==", "dev": true, "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@types/normalize-package-data": { @@ -3077,12 +3082,12 @@ } }, "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, - "dependencies": { - "deep-equal": "^2.0.5" + "engines": { + "node": ">= 0.4" } }, "node_modules/babel-eslint": { @@ -3586,9 +3591,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "version": "1.0.30001655", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", + "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", "dev": true, "funding": [ { @@ -4094,9 +4099,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.0.tgz", - "integrity": "sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", "dev": true, "dependencies": { "browserslist": "^4.23.3" @@ -4855,9 +4860,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.7.tgz", - "integrity": "sha512-6FTNWIWMxMy/ZY6799nBlPtF1DFDQ6VQJ7yyDP27SJNt5lwtQ5ufqVvHylb3fdQefvRcgA3fKcFMJi9OLwBRNw==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==", "dev": true }, "node_modules/emoji-regex": { @@ -5124,9 +5129,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -5281,9 +5286,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", + "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -5307,26 +5312,27 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", "tsconfig-paths": "^3.15.0" }, @@ -5406,17 +5412,17 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", + "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", "dev": true, "dependencies": { "aria-query": "~5.1.3", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "es-iterator-helpers": "^1.0.19", @@ -5432,7 +5438,7 @@ "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "node_modules/eslint-plugin-prettier": { @@ -5466,9 +5472,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.35.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", - "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", + "version": "7.35.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz", + "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==", "dev": true, "dependencies": { "array-includes": "^3.1.8", @@ -5990,9 +5996,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "dev": true, "funding": [ { @@ -6768,9 +6774,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, "dependencies": { "hasown": "^2.0.2" @@ -7811,9 +7817,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { "braces": "^3.0.3", @@ -8857,9 +8863,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -8919,9 +8925,9 @@ } }, "node_modules/postcss": { - "version": "8.4.41", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", - "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", "dev": true, "funding": [ { @@ -10223,9 +10229,9 @@ } }, "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "dev": true, "engines": { "node": ">=10" @@ -10792,9 +10798,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true }, "node_modules/sprintf-js": { @@ -11426,9 +11432,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", + "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", "dev": true, "dependencies": { "has-flag": "^4.0.0", @@ -11436,6 +11442,9 @@ }, "engines": { "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-hyperlinks/node_modules/has-flag": { @@ -11505,9 +11514,9 @@ } }, "node_modules/svg-sprite/node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true }, "node_modules/svg-sprite/node_modules/commander": { @@ -11973,9 +11982,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true }, "node_modules/type-check": { @@ -12120,9 +12129,9 @@ "dev": true }, "node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -12387,9 +12396,9 @@ } }, "node_modules/winston": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.1.tgz", - "integrity": "sha512-CJi4Il/msz8HkdDfXOMu+r5Au/oyEjFiOZzbX2d23hRLY0narGjqfE5lFlrT5hfYJhPtM8b85/GNFsxIML/RVA==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz", + "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==", "dev": true, "dependencies": { "@colors/colors": "^1.6.0", @@ -12446,9 +12455,9 @@ } }, "node_modules/winston/node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true }, "node_modules/winston/node_modules/readable-stream": { @@ -12731,9 +12740,9 @@ } }, "node_modules/yaml-eslint-parser/node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", "dev": true, "bin": { "yaml": "bin.mjs" -- GitLab From 41208102b716361ccbebb83711ec5fa60126c60b Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Wed, 4 Sep 2024 20:26:42 +0300 Subject: [PATCH 029/149] ISAICP-9045: Update PHP dependencies. --- composer.json | 20 +- composer.lock | 948 +++++++++--------- ...b7771e51d2a2852b75e7be90fc871b1bc895f.diff | 22 - .../php/drupal/default_content/2640734.diff | 666 +++++++++++- resources/patch/php/drupal/flag/3410265.diff | 13 - resources/patch/php/drupal/flag/3410363.diff | 13 - .../drupal/social_media_links/3319694.patch | 25 - .../drupal/social_media_links/3384469-7.patch | 27 - .../drupal/social_media_links/3397614.patch | 64 -- .../patch/{ => php}/gitonomy/gitlib/217.diff | 0 .../m4tthumphrey/php-gitlab-api/726.diff | 0 .../m4tthumphrey/php-gitlab-api/772.diff | 0 web/themes/iop/assets/js/glide.min.js | 6 +- web/themes/ventuno/assets/js/carousel.min.js | 6 +- .../ventuno/assets/js/explore-block.min.js | 6 +- 15 files changed, 1097 insertions(+), 719 deletions(-) delete mode 100644 resources/patch/php/bitbucket/client/fe8b7771e51d2a2852b75e7be90fc871b1bc895f.diff delete mode 100644 resources/patch/php/drupal/flag/3410265.diff delete mode 100644 resources/patch/php/drupal/flag/3410363.diff delete mode 100644 resources/patch/php/drupal/social_media_links/3319694.patch delete mode 100644 resources/patch/php/drupal/social_media_links/3384469-7.patch delete mode 100644 resources/patch/php/drupal/social_media_links/3397614.patch rename resources/patch/{ => php}/gitonomy/gitlib/217.diff (100%) rename resources/patch/php/{drupal => }/m4tthumphrey/php-gitlab-api/726.diff (100%) rename resources/patch/php/{drupal => }/m4tthumphrey/php-gitlab-api/772.diff (100%) diff --git a/composer.json b/composer.json index 5e92505a58..d3bca6053b 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "drupal/honeypot": "~2", "drupal/iframe": "^2", "drupal/image_library_widget": "^2.0", - "drupal/imagecache_external": "^3.0", + "drupal/imagecache_external": "3.0.1", "drupal/inline_entity_form": "^3.0", "drupal/jquery_ui_accordion": "^2.1", "drupal/json_field": "^1.0", @@ -279,9 +279,6 @@ "drupal/core": "-p2" }, "patches": { - "bitbucket/client": { - "Slashes in file path used in Src and Downloads API classes are url-encoded @see https://github.com/BitbucketPHP/Client/pull/83": "resources/patch/php/bitbucket/client/fe8b7771e51d2a2852b75e7be90fc871b1bc895f.diff" - }, "cfpinto/graphql": { "Enum argument https://github.com/cfpinto/graphql/issues/24": "resources/patch/php/cfpinto/graphql/25.diff" }, @@ -365,9 +362,7 @@ "drupal/flag": { "TypeError: Argument 1 passed to FlagCount::count() must implement interface @see https://www.drupal.org/project/flag/issues/3168014": "resources/patch/php/drupal/flag/3168014.diff", "AJAX link broken if flaggable entity id is string @see https://www.drupal.org/project/flag/issues/3359007": "resources/patch/php/drupal/flag/3359007-47.patch", - "Disclose flagging view mode in flag theming @see https://www.drupal.org/project/flag/issues/3049155": "resources/patch/php/drupal/flag/3049155-16.patch", - "[Drupal 10.2] Deprecated sequence type schema definition @see https://www.drupal.org/i/3410265": "resources/patch/php/drupal/flag/3410265.diff", - "[Drupal 10.2] Merge::key() with array is deprecated @see https://www.drupal.org/i/3410363": "resources/patch/php/drupal/flag/3410363.diff" + "Disclose flagging view mode in flag theming @see https://www.drupal.org/project/flag/issues/3049155": "resources/patch/php/drupal/flag/3049155-16.patch" }, "drupal/honeypot": { "Behat integration. @see https://www.drupal.org/project/honeypot/issues/3059040": "resources/patch/php/drupal/honeypot/3059040.patch", @@ -430,10 +425,7 @@ "URL don't include the base path @see https://www.drupal.org/project/search_api_spellcheck/issues/3280372": "resources/patch/php/drupal/search_api_spellcheck/3280372.patch" }, "drupal/social_media_links": { - "Missing config schema for field, widget and formatter @see https://www.drupal.org/node/2898680": "resources/patch/php/drupal/social_media_links/2898680.patch", - "Mastodon should not have a fixed URL prefix. @see https://www.drupal.org/project/social_media_links/issues/3319694": "resources/patch/php/drupal/social_media_links/3319694.patch", - "Theme suggestions for social_media_links_field. @see https://www.drupal.org/project/social_media_links/issues/3397614": "resources/patch/php/drupal/social_media_links/3397614.patch", - "Convert Twitter to X @see https://www.drupal.org/project/social_media_links/issues/3384469": "resources/patch/php/drupal/social_media_links/3384469-7.patch" + "Missing config schema for field, widget and formatter @see https://www.drupal.org/node/2898680": "resources/patch/php/drupal/social_media_links/2898680.patch" }, "drupal/sparql_entity_storage": { "Interface contract violation @see https://drupal.org/i/3379328": "resources/patch/php/drupal/sparql_entity_storage/3379328.patch", @@ -465,11 +457,11 @@ "Webform might create invalid link renderable arrays on submission list. @see https://www.drupal.org/project/webform/issues/3441600": "resources/patch/php/drupal/webform/3441600.patch" }, "gitonomy/gitlib": { - "Edge case: Empty message in the first commit @see https://github.com/gitonomy/gitlib/pull/217": "resources/patch/gitonomy/gitlib/217.diff" + "Edge case: Empty message in the first commit @see https://github.com/gitonomy/gitlib/pull/217": "resources/patch/php/gitonomy/gitlib/217.diff" }, "m4tthumphrey/php-gitlab-api": { - "GraphQL API @see https://github.com/GitLabPHP/Client/issues/766": "resources/patch/php/drupal/m4tthumphrey/php-gitlab-api/772.diff", - "Add support for prefixed URIs on base path @see https://github.com/GitLabPHP/Client/issues/726": "resources/patch/php/drupal/m4tthumphrey/php-gitlab-api/726.diff" + "GraphQL API @see https://github.com/GitLabPHP/Client/issues/766": "resources/patch/php/m4tthumphrey/php-gitlab-api/772.diff", + "Add support for prefixed URIs on base path @see https://github.com/GitLabPHP/Client/issues/726": "resources/patch/php/m4tthumphrey/php-gitlab-api/726.diff" }, "lullabot/mink-selenium2-driver": { "Add missing mouseover before clicking on radio/select elements - https://github.com/Lullabot/MinkSelenium2Driver/pull/14": "resources/patch/php/lullabot/mink-selenium2-driver/selenium2-mouseover-fixes.patch" diff --git a/composer.lock b/composer.lock index 4aa2c53286..3ba336768d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5982e10de7b576e1df9647ea0f3d1c90", + "content-hash": "7e56945cd869c86d68dd6f18a9cdf822", "packages": [ { "name": "asm89/stack-cors", @@ -64,24 +64,24 @@ }, { "name": "bitbucket/client", - "version": "v4.5.0", + "version": "v4.7.0", "source": { "type": "git", "url": "https://github.com/BitbucketPHP/Client.git", - "reference": "48b41180d582f26fab2c96ce9a8f2879eba44d12" + "reference": "ef3a4eb1963572d7745afb7d707f56cbdb328ee4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/BitbucketPHP/Client/zipball/48b41180d582f26fab2c96ce9a8f2879eba44d12", - "reference": "48b41180d582f26fab2c96ce9a8f2879eba44d12", + "url": "https://api.github.com/repos/BitbucketPHP/Client/zipball/ef3a4eb1963572d7745afb7d707f56cbdb328ee4", + "reference": "ef3a4eb1963572d7745afb7d707f56cbdb328ee4", "shasum": "" }, "require": { "ext-json": "*", "php": "^7.4.15 || ^8.0.2", - "php-http/cache-plugin": "^1.8", - "php-http/client-common": "^2.7", - "php-http/discovery": "^1.19", + "php-http/cache-plugin": "^1.8.1 || ^2.0", + "php-http/client-common": "^2.7.1", + "php-http/discovery": "^1.19.2", "php-http/httplug": "^2.4", "php-http/multipart-stream-builder": "^1.3", "psr/cache": "^1.0 || ^2.0 || ^3.0", @@ -131,7 +131,7 @@ ], "support": { "issues": "https://github.com/BitbucketPHP/Client/issues", - "source": "https://github.com/BitbucketPHP/Client/tree/v4.5.0" + "source": "https://github.com/BitbucketPHP/Client/tree/v4.7.0" }, "funding": [ { @@ -143,7 +143,7 @@ "type": "tidelift" } ], - "time": "2023-10-08T13:42:32+00:00" + "time": "2024-03-17T21:09:02+00:00" }, { "name": "caxy/php-htmldiff", @@ -1723,26 +1723,26 @@ }, { "name": "drupal/antibot", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://git.drupalcode.org/project/antibot.git", - "reference": "2.0.3" + "reference": "2.0.4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/antibot-2.0.3.zip", - "reference": "2.0.3", - "shasum": "b26b603299ee3067e0aa3875ff752815f21d2f0b" + "url": "https://ftp.drupal.org/files/projects/antibot-2.0.4.zip", + "reference": "2.0.4", + "shasum": "58b215291b250ea410194693cbac2da6f54a8530" }, "require": { - "drupal/core": "^8.8 || ^9 || ^10" + "drupal/core": "^8.8 || ^9 || ^10 || ^11" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.0.3", - "datestamp": "1708358087", + "version": "2.0.4", + "datestamp": "1723819813", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2862,30 +2862,30 @@ }, { "name": "drupal/default_content", - "version": "2.0.0-alpha2", + "version": "2.0.0-alpha3", "source": { "type": "git", "url": "https://git.drupalcode.org/project/default_content.git", - "reference": "2.0.0-alpha2" + "reference": "2.0.0-alpha3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/default_content-2.0.0-alpha2.zip", - "reference": "2.0.0-alpha2", - "shasum": "5c365ea21b0be63dc00ec2db50179291d6fb3d89" + "url": "https://ftp.drupal.org/files/projects/default_content-2.0.0-alpha3.zip", + "reference": "2.0.0-alpha3", + "shasum": "fdd90c70bd91896835f6ba5ec42c260c1a144a2b" }, "require": { - "drupal/core": "^9.1 || ^10" + "drupal/core": "^9.1 || ^10 || ^11" }, "require-dev": { - "drupal/hal": " ^9 || ^1 || ^2", + "drupal/hal": "^1 || ^2", "drupal/paragraphs": "^1" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.0.0-alpha2", - "datestamp": "1659466706", + "version": "2.0.0-alpha3", + "datestamp": "1724492420", "security-coverage": { "status": "not-covered", "message": "Alpha releases are not covered by Drupal security advisories." @@ -2893,7 +2893,7 @@ }, "drush": { "services": { - "drush.services.yml": "^9 || ^10 || ^11" + "drush.services.yml": "^9 || ^10 || ^11 || ^12" } } }, @@ -2911,7 +2911,7 @@ "homepage": "https://www.drupal.org/user/1852732" }, { - "name": "Berdir", + "name": "berdir", "homepage": "https://www.drupal.org/user/214652" }, { @@ -2927,7 +2927,7 @@ "homepage": "https://www.drupal.org/user/395439" }, { - "name": "Sam152", + "name": "sam152", "homepage": "https://www.drupal.org/user/1485048" } ], @@ -3324,17 +3324,17 @@ }, { "name": "drupal/email_contact", - "version": "2.0.6", + "version": "2.0.7", "source": { "type": "git", "url": "https://git.drupalcode.org/project/email_contact.git", - "reference": "2.0.6" + "reference": "2.0.7" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/email_contact-2.0.6.zip", - "reference": "2.0.6", - "shasum": "97a8390ddbc76ece888b41b69a6e4d52f4a4f6ae" + "url": "https://ftp.drupal.org/files/projects/email_contact-2.0.7.zip", + "reference": "2.0.7", + "shasum": "c686d65a0f3a2b0ac3fc0eac4b152b5513265c25" }, "require": { "drupal/core": "^8.8 || ^9 || ^10 || ^11" @@ -3342,8 +3342,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "2.0.6", - "datestamp": "1718275601", + "version": "2.0.7", + "datestamp": "1723995558", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4288,26 +4288,26 @@ }, { "name": "drupal/flag", - "version": "4.0.0-beta4", + "version": "4.0.0-beta5", "source": { "type": "git", "url": "https://git.drupalcode.org/project/flag.git", - "reference": "8.x-4.0-beta4" + "reference": "8.x-4.0-beta5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/flag-8.x-4.0-beta4.zip", - "reference": "8.x-4.0-beta4", - "shasum": "2779804f23685e1bb68a2a7b9517932dde3b1d4e" + "url": "https://ftp.drupal.org/files/projects/flag-8.x-4.0-beta5.zip", + "reference": "8.x-4.0-beta5", + "shasum": "da40eefe0f3a5603fff25f8f4626c462bb75cf7a" }, "require": { - "drupal/core": "^9.1 || ^10" + "drupal/core": "^9.1 || ^10 || ^11" }, "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-4.0-beta4", - "datestamp": "1670487892", + "version": "8.x-4.0-beta5", + "datestamp": "1724579446", "security-coverage": { "status": "not-covered", "message": "Beta releases are not covered by Drupal security advisories." @@ -4320,7 +4320,7 @@ ], "authors": [ { - "name": "Berdir", + "name": "berdir", "homepage": "https://www.drupal.org/user/214652" }, { @@ -4335,6 +4335,10 @@ "name": "joachim", "homepage": "https://www.drupal.org/user/107701" }, + { + "name": "mandclu", + "homepage": "https://www.drupal.org/user/52136" + }, { "name": "merlinofchaos", "homepage": "https://www.drupal.org/user/26979" @@ -4460,17 +4464,17 @@ }, { "name": "drupal/geofield", - "version": "1.60.0", + "version": "1.61.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/geofield.git", - "reference": "8.x-1.60" + "reference": "8.x-1.61" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/geofield-8.x-1.60.zip", - "reference": "8.x-1.60", - "shasum": "ffb1891148b343208e7a190c8cc606a339c74ee1" + "url": "https://ftp.drupal.org/files/projects/geofield-8.x-1.61.zip", + "reference": "8.x-1.61", + "shasum": "b204f101ee536597b9c293f66f75102d6ea2d268" }, "require": { "drupal/core": "^9 || ^10 || ^11", @@ -4483,8 +4487,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.60", - "datestamp": "1722078200", + "version": "8.x-1.61", + "datestamp": "1725441883", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4522,29 +4526,29 @@ }, { "name": "drupal/honeypot", - "version": "2.1.4", + "version": "2.2.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/honeypot.git", - "reference": "2.1.4" + "reference": "2.2.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/honeypot-2.1.4.zip", - "reference": "2.1.4", - "shasum": "adf76c3520c0e458177dbe6d638aa2d6ae40a95b" + "url": "https://ftp.drupal.org/files/projects/honeypot-2.2.0.zip", + "reference": "2.2.0", + "shasum": "56397c3779ebac1526cce9ecd39385017ee9a837" }, "require": { - "drupal/core": "^9.2 || ^10" + "drupal/core": "^10.3 || ^11" }, "require-dev": { - "drupal/rules": "^3.x-dev" + "drupal/rules": "^4.0" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.1.4", - "datestamp": "1723489062", + "version": "2.2.0", + "datestamp": "1723761042", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4636,6 +4640,10 @@ "homepage": "https://www.drupal.org/user/340152", "email": "drupal@neffets.de", "role": "Developer" + }, + { + "name": "smustgrave", + "homepage": "https://www.drupal.org/user/3252890" } ], "description": "Defines a simple iframe field type.", @@ -5100,27 +5108,27 @@ }, { "name": "drupal/layout_builder_component_attributes", - "version": "2.1.3", + "version": "2.2.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/layout_builder_component_attributes.git", - "reference": "2.1.3" + "reference": "2.2.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/layout_builder_component_attributes-2.1.3.zip", - "reference": "2.1.3", - "shasum": "7c02269105a2bc0485d474ecfefaa4bd1c5cabca" + "url": "https://ftp.drupal.org/files/projects/layout_builder_component_attributes-2.2.0.zip", + "reference": "2.2.0", + "shasum": "a43241bb6a56d927f75ac2fc901d1aebcd4cca01" }, "require": { - "drupal/core": "^9.0|^10.0", + "drupal/core": "^10.0|^11.0", "neilime/php-css-lint": "^2.0|^3.0" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.1.3", - "datestamp": "1695059373", + "version": "2.2.0", + "datestamp": "1724946488", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5133,7 +5141,7 @@ ], "authors": [ { - "name": "Chris Burge", + "name": "chris burge", "homepage": "https://www.drupal.org/user/1826152" } ], @@ -5192,20 +5200,20 @@ }, { "name": "drupal/layout_paragraphs", - "version": "2.0.8", + "version": "2.1.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/layout_paragraphs.git", - "reference": "2.0.8" + "reference": "2.1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/layout_paragraphs-2.0.8.zip", - "reference": "2.0.8", - "shasum": "a47e8cb60657c5aad1ad0b267d0c621c7e01a31c" + "url": "https://ftp.drupal.org/files/projects/layout_paragraphs-2.1.0.zip", + "reference": "2.1.0", + "shasum": "499d68d48f1a92d6620f9d3fd781122a95ed92bc" }, "require": { - "drupal/core": "^9.2 || ^10 || ^11", + "drupal/core": "^10 || ^11", "drupal/paragraphs": "^1.6" }, "require-dev": { @@ -5216,8 +5224,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "2.0.8", - "datestamp": "1722385148", + "version": "2.1.0", + "datestamp": "1724879054", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5393,27 +5401,27 @@ }, { "name": "drupal/markdown_easy", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://git.drupalcode.org/project/markdown_easy.git", - "reference": "1.0.0" + "reference": "1.0.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/markdown_easy-1.0.0.zip", - "reference": "1.0.0", - "shasum": "bb2d0d5be9abf8c3460b97ba0598c1cfd0986ee2" + "url": "https://ftp.drupal.org/files/projects/markdown_easy-1.0.1.zip", + "reference": "1.0.1", + "shasum": "ecd23d34e1dcda077125e41d8afa3846cef9e137" }, "require": { - "drupal/core": "^9 || ^10", + "drupal/core": "^9 || ^10 || ^11", "league/commonmark": "^2.4" }, "type": "drupal-module", "extra": { "drupal": { - "version": "1.0.0", - "datestamp": "1693674138", + "version": "1.0.1", + "datestamp": "1713470232", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5439,17 +5447,17 @@ }, { "name": "drupal/memcache", - "version": "2.6.0", + "version": "2.7.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/memcache.git", - "reference": "8.x-2.6" + "reference": "8.x-2.7" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/memcache-8.x-2.6.zip", - "reference": "8.x-2.6", - "shasum": "c58d66e426134c082490dca25b057c6ae0ea3d2a" + "url": "https://ftp.drupal.org/files/projects/memcache-8.x-2.7.zip", + "reference": "8.x-2.7", + "shasum": "d16c7641eb1367606c55e1657b5fa8ae07c59ecf" }, "require": { "drupal/core": "^9.5 || ^10 || ^11" @@ -5457,8 +5465,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-2.6", - "datestamp": "1720732159", + "version": "8.x-2.7", + "datestamp": "1723657818", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -6152,7 +6160,7 @@ "extra": { "drupal": { "version": "2.0.0-rc1", - "datestamp": "1709827834", + "datestamp": "1709827878", "security-coverage": { "status": "not-covered", "message": "RC releases are not covered by Drupal security advisories." @@ -6259,6 +6267,10 @@ "name": "pfrenssen", "homepage": "https://www.drupal.org/u/pfrenssen" }, + { + "name": "Dries", + "homepage": "https://www.drupal.org/user/1" + }, { "name": "dww", "homepage": "https://www.drupal.org/user/46549" @@ -7136,6 +7148,12 @@ "url": "https://git.drupalcode.org/project/rat.git", "reference": "28202b02262a39ac8dbbfd43696b67c0c8c46b71" }, + "dist": { + "type": "zip", + "url": "https://git.drupalcode.org/api/v4/projects/project%2Frat/repository/archive.zip?sha=28202b02262a39ac8dbbfd43696b67c0c8c46b71", + "reference": "28202b02262a39ac8dbbfd43696b67c0c8c46b71", + "shasum": "" + }, "require": { "php": "^7.4 || ^8.0" }, @@ -7159,7 +7177,10 @@ "email": "merlin@geeks4change.net" } ], - "time": "2023-07-19T20:22:22+00:00" + "support": { + "source": "https://git.drupalcode.org/project/rat/-/tree/1.0.0" + }, + "time": "2023-07-19T22:22:22+00:00" }, { "name": "drupal/rdf_entity", @@ -7235,28 +7256,29 @@ }, { "name": "drupal/rdf_sync", - "version": "1.0.0-alpha10", + "version": "1.0.0-alpha11", "source": { "type": "git", "url": "https://git.drupalcode.org/project/rdf_sync.git", - "reference": "1.0.0-alpha10" + "reference": "1.0.0-alpha11" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/rdf_sync-1.0.0-alpha10.zip", - "reference": "1.0.0-alpha10", - "shasum": "bfbd6d26c1850f4b0b2bc3800a90ec934c1866ac" + "url": "https://ftp.drupal.org/files/projects/rdf_sync-1.0.0-alpha11.zip", + "reference": "1.0.0-alpha11", + "shasum": "64071e0ad3df12cc13119b718a0d9ba708468d23" }, "require": { - "drupal/core": ">=10.2", + "drupal/core": "^10.2", + "ext-pdo": "*", "ml/json-ld": "^1.2", "sweetrdf/easyrdf": "^1.11" }, "type": "drupal-module", "extra": { "drupal": { - "version": "1.0.0-alpha10", - "datestamp": "1715064844", + "version": "1.0.0-alpha11", + "datestamp": "1725025834", "security-coverage": { "status": "not-covered", "message": "Alpha releases are not covered by Drupal security advisories." @@ -8145,27 +8167,27 @@ }, { "name": "drupal/simple_sitemap", - "version": "4.1.9", + "version": "4.2.1", "source": { "type": "git", "url": "https://git.drupalcode.org/project/simple_sitemap.git", - "reference": "4.1.9" + "reference": "4.2.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/simple_sitemap-4.1.9.zip", - "reference": "4.1.9", - "shasum": "d86d90408b334cd7470ea631e3be5acca2103377" + "url": "https://ftp.drupal.org/files/projects/simple_sitemap-4.2.1.zip", + "reference": "4.2.1", + "shasum": "d96b481571ca2fecdb305e87d2557f9338116864" }, "require": { - "drupal/core": "^9.3 || ^10", + "drupal/core": "^10.2 || ^11", "ext-xmlwriter": "*" }, "type": "drupal-module", "extra": { "drupal": { - "version": "4.1.9", - "datestamp": "1712441608", + "version": "4.2.1", + "datestamp": "1723802052", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -8189,7 +8211,7 @@ "role": "Maintainer" }, { - "name": "WalkingDexter", + "name": "walkingdexter", "homepage": "https://www.drupal.org/user/3251330" } ], @@ -8318,31 +8340,31 @@ }, { "name": "drupal/smart_trim", - "version": "2.1.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/smart_trim.git", - "reference": "2.1.1" + "reference": "2.2.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/smart_trim-2.1.1.zip", - "reference": "2.1.1", - "shasum": "5d1ca3c0a9990d6344249f3224353372c0b760c5" + "url": "https://ftp.drupal.org/files/projects/smart_trim-2.2.0.zip", + "reference": "2.2.0", + "shasum": "564737cf0895e1b8a38af575ab7ca23f55335d9a" }, "require": { - "drupal/core": "^8 || ^9 || ^10 || ^11", + "drupal/core": "^9.5 || ^10 || ^11", "drupal/token": "^1.0", - "php": ">=7.4.0" + "php": ">=8.1" }, "require-dev": { - "drupal/token_filter": "^2.0" + "drupal/token_filter": "^2.1 || ^2.2" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.1.1", - "datestamp": "1708875348", + "version": "2.2.0", + "datestamp": "1723847275", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -8379,26 +8401,26 @@ }, { "name": "drupal/social_media_links", - "version": "2.9.0", + "version": "2.10.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/social_media_links.git", - "reference": "8.x-2.9" + "reference": "8.x-2.10" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/social_media_links-8.x-2.9.zip", - "reference": "8.x-2.9", - "shasum": "d73ea6199b48e11e57fe8a2aeb2afbf3c295704a" + "url": "https://ftp.drupal.org/files/projects/social_media_links-8.x-2.10.zip", + "reference": "8.x-2.10", + "shasum": "dd329d44f88112d2fe83f54331502738c5f2810b" }, "require": { - "drupal/core": "^8 || ^9 || ^10" + "drupal/core": "^9.5 || ^10 || ^11" }, "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-2.9", - "datestamp": "1665768361", + "version": "8.x-2.10", + "datestamp": "1724736719", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -8419,6 +8441,10 @@ "name": "Christian Beier", "homepage": "https://www.drupal.org/u/cbeier", "role": "Maintainer" + }, + { + "name": "neslee canil pinto", + "homepage": "https://www.drupal.org/user/3580850" } ], "description": "The module provides a block that display links (icons) to your profiles on various social networking sites.", @@ -8863,20 +8889,20 @@ }, { "name": "drupal/ui_patterns", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/ui_patterns.git", - "reference": "8.x-1.8" + "reference": "8.x-1.9" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/ui_patterns-8.x-1.8.zip", - "reference": "8.x-1.8", - "shasum": "120d90db34296500a1ae8094cd0cc23983e951ab" + "url": "https://ftp.drupal.org/files/projects/ui_patterns-8.x-1.9.zip", + "reference": "8.x-1.9", + "shasum": "35eabe1f655df98f6f3cb68a62a98f8d41b52f0c" }, "require": { - "drupal/core": "^9 || ^10" + "drupal/core": "^9 || ^10 || ^11" }, "require-dev": { "drupal/ds": "^3.18", @@ -8885,8 +8911,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.8", - "datestamp": "1706780549", + "version": "8.x-1.9", + "datestamp": "1724936358", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -8911,15 +8937,15 @@ "homepage": "https://www.drupal.org/user/861002" }, { - "name": "DuaelFr", + "name": "duaelfr", "homepage": "https://www.drupal.org/user/931394" }, { - "name": "G4MBINI", + "name": "g4mbini", "homepage": "https://www.drupal.org/user/2533498" }, { - "name": "Grimreaper", + "name": "grimreaper", "homepage": "https://www.drupal.org/user/2388214" }, { @@ -9050,20 +9076,20 @@ }, { "name": "drupal/view_unpublished", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/view_unpublished.git", - "reference": "8.x-1.2" + "reference": "8.x-1.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/view_unpublished-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "14374dd56d841270207e21974c7b7cf8aa1804f7" + "url": "https://ftp.drupal.org/files/projects/view_unpublished-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "7dd4411c53866585ac6319d147ab11d214d55877" }, "require": { - "drupal/core": "^9.4 || ^10" + "drupal/core": "^9.4 || ^10 || ^11" }, "require-dev": { "drupal/coder": "^8.3.18", @@ -9072,8 +9098,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.2", - "datestamp": "1709383642", + "version": "8.x-1.3", + "datestamp": "1724503131", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -9348,7 +9374,7 @@ "homepage": "https://www.drupal.org/user/1557710" }, { - "name": "Steven Jones", + "name": "steven jones", "homepage": "https://www.drupal.org/user/99644" } ], @@ -10465,20 +10491,20 @@ }, { "name": "html2text/html2text", - "version": "4.3.1", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/mtibben/html2text.git", - "reference": "61ad68e934066a6f8df29a3d23a6460536d0855c" + "reference": "3b443cbe302b52eb5806a21a9dbd79524203970a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mtibben/html2text/zipball/61ad68e934066a6f8df29a3d23a6460536d0855c", - "reference": "61ad68e934066a6f8df29a3d23a6460536d0855c", + "url": "https://api.github.com/repos/mtibben/html2text/zipball/3b443cbe302b52eb5806a21a9dbd79524203970a", + "reference": "3b443cbe302b52eb5806a21a9dbd79524203970a", "shasum": "" }, "require-dev": { - "phpunit/phpunit": "~4" + "phpunit/phpunit": "~4|^9.0" }, "suggest": { "ext-mbstring": "For best performance", @@ -10487,10 +10513,7 @@ "type": "library", "autoload": { "psr-4": { - "Html2Text\\": [ - "src/", - "test/" - ] + "Html2Text\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -10500,9 +10523,9 @@ "description": "Converts HTML to formatted plain text", "support": { "issues": "https://github.com/mtibben/html2text/issues", - "source": "https://github.com/mtibben/html2text/tree/4.3.1" + "source": "https://github.com/mtibben/html2text/tree/4.3.2" }, - "time": "2020-04-16T23:44:31+00:00" + "time": "2024-08-20T02:43:29+00:00" }, { "name": "itamair/geophp", @@ -10589,22 +10612,22 @@ }, { "name": "knplabs/github-api", - "version": "v3.13.0", + "version": "v3.14.1", "source": { "type": "git", "url": "https://github.com/KnpLabs/php-github-api.git", - "reference": "47024f3483520c0fafdfc5c10d2a20d87b4c7ceb" + "reference": "71fec50e228737ec23c0b69801b85bf596fbdaca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/KnpLabs/php-github-api/zipball/47024f3483520c0fafdfc5c10d2a20d87b4c7ceb", - "reference": "47024f3483520c0fafdfc5c10d2a20d87b4c7ceb", + "url": "https://api.github.com/repos/KnpLabs/php-github-api/zipball/71fec50e228737ec23c0b69801b85bf596fbdaca", + "reference": "71fec50e228737ec23c0b69801b85bf596fbdaca", "shasum": "" }, "require": { "ext-json": "*", "php": "^7.2.5 || ^8.0", - "php-http/cache-plugin": "^1.7.1", + "php-http/cache-plugin": "^1.7.1|^2.0", "php-http/client-common": "^2.3", "php-http/discovery": "^1.12", "php-http/httplug": "^2.2", @@ -10632,7 +10655,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.12-dev" + "dev-master": "3.14-dev" } }, "autoload": { @@ -10665,7 +10688,7 @@ ], "support": { "issues": "https://github.com/KnpLabs/php-github-api/issues", - "source": "https://github.com/KnpLabs/php-github-api/tree/v3.13.0" + "source": "https://github.com/KnpLabs/php-github-api/tree/v3.14.1" }, "funding": [ { @@ -10673,7 +10696,7 @@ "type": "github" } ], - "time": "2023-11-19T21:08:19+00:00" + "time": "2024-03-24T18:21:15+00:00" }, { "name": "laminas/laminas-stdlib", @@ -10736,16 +10759,16 @@ }, { "name": "league/commonmark", - "version": "2.4.2", + "version": "2.5.3", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf" + "reference": "b650144166dfa7703e62a22e493b853b58d874b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0", + "reference": "b650144166dfa7703e62a22e493b853b58d874b0", "shasum": "" }, "require": { @@ -10758,8 +10781,8 @@ }, "require-dev": { "cebe/markdown": "^1.0", - "commonmark/cmark": "0.30.3", - "commonmark/commonmark.js": "0.30.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", "composer/package-versions-deprecated": "^1.8", "embed/embed": "^4.4", "erusev/parsedown": "^1.0", @@ -10781,7 +10804,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "2.6-dev" } }, "autoload": { @@ -10838,7 +10861,7 @@ "type": "tidelift" } ], - "time": "2024-02-02T11:59:32+00:00" + "time": "2024-08-16T11:46:16+00:00" }, { "name": "league/config", @@ -11094,23 +11117,23 @@ }, { "name": "m4tthumphrey/php-gitlab-api", - "version": "11.13.0", + "version": "11.14.0", "source": { "type": "git", "url": "https://github.com/GitLabPHP/Client.git", - "reference": "66742709f2de1e14acfd232358b4f0c1b51b43c8" + "reference": "6b805882e1478873cc89ee62d2decf74eee2d5f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GitLabPHP/Client/zipball/66742709f2de1e14acfd232358b4f0c1b51b43c8", - "reference": "66742709f2de1e14acfd232358b4f0c1b51b43c8", + "url": "https://api.github.com/repos/GitLabPHP/Client/zipball/6b805882e1478873cc89ee62d2decf74eee2d5f2", + "reference": "6b805882e1478873cc89ee62d2decf74eee2d5f2", "shasum": "" }, "require": { "ext-json": "*", "ext-xml": "*", "php": "^7.4.15 || ^8.0.2", - "php-http/cache-plugin": "^1.8.1", + "php-http/cache-plugin": "^1.8.1 || ^2.0", "php-http/client-common": "^2.7.1", "php-http/discovery": "^1.19.2", "php-http/httplug": "^2.4", @@ -11172,7 +11195,7 @@ ], "support": { "issues": "https://github.com/GitLabPHP/Client/issues", - "source": "https://github.com/GitLabPHP/Client/tree/11.13.0" + "source": "https://github.com/GitLabPHP/Client/tree/11.14.0" }, "funding": [ { @@ -11180,7 +11203,7 @@ "type": "github" } ], - "time": "2023-12-03T22:42:01+00:00" + "time": "2024-03-17T21:35:56+00:00" }, { "name": "maennchen/zipstream-php", @@ -11763,20 +11786,20 @@ }, { "name": "nette/utils", - "version": "v4.0.4", + "version": "v4.0.5", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218" + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218", - "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218", + "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", "shasum": "" }, "require": { - "php": ">=8.0 <8.4" + "php": "8.0 - 8.4" }, "conflict": { "nette/finder": "<3", @@ -11843,9 +11866,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.4" + "source": "https://github.com/nette/utils/tree/v4.0.5" }, - "time": "2024-01-17T16:50:36+00:00" + "time": "2024-08-07T15:39:19+00:00" }, { "name": "nikic/php-parser", @@ -12050,16 +12073,16 @@ }, { "name": "openeuropa/oe_bootstrap_theme", - "version": "1.11.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/openeuropa/oe_bootstrap_theme.git", - "reference": "9d0d51add8d0da7798d3b27e2716e3e2a95c8ac0" + "reference": "e4fb81f7032e5f5c1648dc03739e3c950bea9f61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/openeuropa/oe_bootstrap_theme/zipball/9d0d51add8d0da7798d3b27e2716e3e2a95c8ac0", - "reference": "9d0d51add8d0da7798d3b27e2716e3e2a95c8ac0", + "url": "https://api.github.com/repos/openeuropa/oe_bootstrap_theme/zipball/e4fb81f7032e5f5c1648dc03739e3c950bea9f61", + "reference": "e4fb81f7032e5f5c1648dc03739e3c950bea9f61", "shasum": "" }, "require": { @@ -12120,9 +12143,9 @@ "description": "OpenEuropa Bootstrap base theme.", "support": { "issues": "https://github.com/openeuropa/oe_bootstrap_theme/issues", - "source": "https://github.com/openeuropa/oe_bootstrap_theme/tree/1.11.0" + "source": "https://github.com/openeuropa/oe_bootstrap_theme/tree/1.12.0" }, - "time": "2024-07-17T14:05:42+00:00" + "time": "2024-08-16T12:57:49+00:00" }, { "name": "openeuropa/oe_dashboard_agent", @@ -12210,16 +12233,16 @@ }, { "name": "openeuropa/oe_webtools", - "version": "1.30.0", + "version": "1.31.0", "source": { "type": "git", "url": "https://github.com/openeuropa/oe_webtools.git", - "reference": "66c4ee68f5aa8aacf02a25521a9583f2dc37ee01" + "reference": "884a729cde1a34c9ba35199a923811f9e8a4ae5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/openeuropa/oe_webtools/zipball/66c4ee68f5aa8aacf02a25521a9583f2dc37ee01", - "reference": "66c4ee68f5aa8aacf02a25521a9583f2dc37ee01", + "url": "https://api.github.com/repos/openeuropa/oe_webtools/zipball/884a729cde1a34c9ba35199a923811f9e8a4ae5b", + "reference": "884a729cde1a34c9ba35199a923811f9e8a4ae5b", "shasum": "" }, "require": { @@ -12292,9 +12315,9 @@ "description": "OpenEuropa Webtools integration.", "support": { "issues": "https://github.com/openeuropa/oe_webtools/issues", - "source": "https://github.com/openeuropa/oe_webtools/tree/1.30.0" + "source": "https://github.com/openeuropa/oe_webtools/tree/1.31.0" }, - "time": "2024-05-28T14:58:52+00:00" + "time": "2024-08-29T13:02:07+00:00" }, { "name": "pear/archive_tar", @@ -12631,26 +12654,27 @@ }, { "name": "php-http/cache-plugin", - "version": "1.8.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/php-http/cache-plugin.git", - "reference": "b3e6c25d89ee5e4ac82115ed23b21ba87986d614" + "reference": "539b2d1ea0dc1c2f141c8155f888197d4ac5635b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/cache-plugin/zipball/b3e6c25d89ee5e4ac82115ed23b21ba87986d614", - "reference": "b3e6c25d89ee5e4ac82115ed23b21ba87986d614", + "url": "https://api.github.com/repos/php-http/cache-plugin/zipball/539b2d1ea0dc1c2f141c8155f888197d4ac5635b", + "reference": "539b2d1ea0dc1c2f141c8155f888197d4ac5635b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", "php-http/client-common": "^1.9 || ^2.0", - "php-http/message-factory": "^1.0", "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/http-factory-implementation": "^1.0", "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" }, "require-dev": { + "nyholm/psr7": "^1.6.1", "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" }, "type": "library", @@ -12679,9 +12703,9 @@ ], "support": { "issues": "https://github.com/php-http/cache-plugin/issues", - "source": "https://github.com/php-http/cache-plugin/tree/1.8.1" + "source": "https://github.com/php-http/cache-plugin/tree/2.0.0" }, - "time": "2023-11-21T08:52:56+00:00" + "time": "2024-02-19T17:02:14+00:00" }, { "name": "php-http/client-common", @@ -13019,73 +13043,18 @@ }, "time": "2024-03-07T13:22:09+00:00" }, - { - "name": "php-http/message-factory", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/message-factory.git", - "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/message-factory/zipball/4d8778e1c7d405cbb471574821c1ff5b68cc8f57", - "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Factory interfaces for PSR-7 HTTP Message", - "homepage": "http://php-http.org", - "keywords": [ - "factory", - "http", - "message", - "stream", - "uri" - ], - "support": { - "issues": "https://github.com/php-http/message-factory/issues", - "source": "https://github.com/php-http/message-factory/tree/1.1.0" - }, - "abandoned": "psr/http-factory", - "time": "2023-04-14T14:16:17+00:00" - }, { "name": "php-http/multipart-stream-builder", - "version": "1.3.0", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/php-http/multipart-stream-builder.git", - "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a" + "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/f5938fd135d9fa442cc297dc98481805acfe2b6a", - "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a", + "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/10086e6de6f53489cca5ecc45b6f468604d3460e", + "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e", "shasum": "" }, "require": { @@ -13126,9 +13095,9 @@ ], "support": { "issues": "https://github.com/php-http/multipart-stream-builder/issues", - "source": "https://github.com/php-http/multipart-stream-builder/tree/1.3.0" + "source": "https://github.com/php-http/multipart-stream-builder/tree/1.4.2" }, - "time": "2023-04-28T14:10:22+00:00" + "time": "2024-09-04T13:22:54+00:00" }, { "name": "php-http/promise", @@ -13548,16 +13517,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "79dff0b268932c640297f5208d6298f71855c03e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", + "reference": "79dff0b268932c640297f5208d6298f71855c03e", "shasum": "" }, "require": { @@ -13592,9 +13561,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.1" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-08-21T13:31:24+00:00" }, { "name": "psy/psysh", @@ -14100,16 +14069,16 @@ }, { "name": "symfony/cache", - "version": "v6.4.3", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "49f8cdee544a621a621cd21b6cda32a38926d310" + "reference": "36daef8fce88fe0b9a4f8cf4c342ced5c05616dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/49f8cdee544a621a621cd21b6cda32a38926d310", - "reference": "49f8cdee544a621a621cd21b6cda32a38926d310", + "url": "https://api.github.com/repos/symfony/cache/zipball/36daef8fce88fe0b9a4f8cf4c342ced5c05616dc", + "reference": "36daef8fce88fe0b9a4f8cf4c342ced5c05616dc", "shasum": "" }, "require": { @@ -14176,7 +14145,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.4.3" + "source": "https://github.com/symfony/cache/tree/v6.4.11" }, "funding": [ { @@ -14192,20 +14161,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-08-05T07:40:31+00:00" }, { "name": "symfony/cache-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "1d74b127da04ffa87aa940abe15446fa89653778" + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/1d74b127da04ffa87aa940abe15446fa89653778", - "reference": "1d74b127da04ffa87aa940abe15446fa89653778", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/df6a1a44c890faded49a5fca33c2d5c5fd3c2197", + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197", "shasum": "" }, "require": { @@ -14215,7 +14184,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -14252,7 +14221,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.0" }, "funding": [ { @@ -14268,20 +14237,20 @@ "type": "tidelift" } ], - "time": "2023-09-25T12:52:38+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/console", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "504974cbe43d05f83b201d6498c206f16fc0cdbc" + "reference": "42686880adaacdad1835ee8fc2a9ec5b7bd63998" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/504974cbe43d05f83b201d6498c206f16fc0cdbc", - "reference": "504974cbe43d05f83b201d6498c206f16fc0cdbc", + "url": "https://api.github.com/repos/symfony/console/zipball/42686880adaacdad1835ee8fc2a9ec5b7bd63998", + "reference": "42686880adaacdad1835ee8fc2a9ec5b7bd63998", "shasum": "" }, "require": { @@ -14346,7 +14315,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.10" + "source": "https://github.com/symfony/console/tree/v6.4.11" }, "funding": [ { @@ -14362,7 +14331,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:30:32+00:00" + "time": "2024-08-15T22:48:29+00:00" }, { "name": "symfony/css-selector", @@ -14431,16 +14400,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "5caf9c5f6085f13b27d70a236b776c07e4a1c3eb" + "reference": "e93c8368dc9915c2fe12018ff22fcbbdd32c9a9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5caf9c5f6085f13b27d70a236b776c07e4a1c3eb", - "reference": "5caf9c5f6085f13b27d70a236b776c07e4a1c3eb", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e93c8368dc9915c2fe12018ff22fcbbdd32c9a9e", + "reference": "e93c8368dc9915c2fe12018ff22fcbbdd32c9a9e", "shasum": "" }, "require": { @@ -14492,7 +14461,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.10" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.11" }, "funding": [ { @@ -14508,7 +14477,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T07:32:07+00:00" + "time": "2024-08-29T08:15:38+00:00" }, { "name": "symfony/deprecation-contracts", @@ -14876,16 +14845,16 @@ }, { "name": "symfony/finder", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "af29198d87112bebdd397bd7735fbd115997824c" + "reference": "d7eb6daf8cd7e9ac4976e9576b32042ef7253453" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/af29198d87112bebdd397bd7735fbd115997824c", - "reference": "af29198d87112bebdd397bd7735fbd115997824c", + "url": "https://api.github.com/repos/symfony/finder/zipball/d7eb6daf8cd7e9ac4976e9576b32042ef7253453", + "reference": "d7eb6daf8cd7e9ac4976e9576b32042ef7253453", "shasum": "" }, "require": { @@ -14920,7 +14889,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.10" + "source": "https://github.com/symfony/finder/tree/v6.4.11" }, "funding": [ { @@ -14936,20 +14905,20 @@ "type": "tidelift" } ], - "time": "2024-07-24T07:06:38+00:00" + "time": "2024-08-13T14:27:37+00:00" }, { "name": "symfony/http-client", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded" + "reference": "4c92046bb788648ff1098cc66da69aa7eac8cb65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded", - "reference": "b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded", + "url": "https://api.github.com/repos/symfony/http-client/zipball/4c92046bb788648ff1098cc66da69aa7eac8cb65", + "reference": "4c92046bb788648ff1098cc66da69aa7eac8cb65", "shasum": "" }, "require": { @@ -15013,7 +14982,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.10" + "source": "https://github.com/symfony/http-client/tree/v6.4.11" }, "funding": [ { @@ -15029,7 +14998,7 @@ "type": "tidelift" } ], - "time": "2024-07-15T09:26:24+00:00" + "time": "2024-08-26T06:30:21+00:00" }, { "name": "symfony/http-client-contracts", @@ -15188,16 +15157,16 @@ }, { "name": "symfony/http-kernel", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "147e0daf618d7575b5007055340d09aece5cf068" + "reference": "1ba6b89d781cb47448155cc70dd2e0f1b0584c79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/147e0daf618d7575b5007055340d09aece5cf068", - "reference": "147e0daf618d7575b5007055340d09aece5cf068", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1ba6b89d781cb47448155cc70dd2e0f1b0584c79", + "reference": "1ba6b89d781cb47448155cc70dd2e0f1b0584c79", "shasum": "" }, "require": { @@ -15282,7 +15251,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.10" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.11" }, "funding": [ { @@ -15298,7 +15267,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T14:52:04+00:00" + "time": "2024-08-30T16:57:20+00:00" }, { "name": "symfony/mailer", @@ -15382,16 +15351,16 @@ }, { "name": "symfony/mime", - "version": "v6.4.9", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "7d048964877324debdcb4e0549becfa064a20d43" + "reference": "dba5d5f6073baf7a3576b580cc4a208b4ca00553" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/7d048964877324debdcb4e0549becfa064a20d43", - "reference": "7d048964877324debdcb4e0549becfa064a20d43", + "url": "https://api.github.com/repos/symfony/mime/zipball/dba5d5f6073baf7a3576b580cc4a208b4ca00553", + "reference": "dba5d5f6073baf7a3576b580cc4a208b4ca00553", "shasum": "" }, "require": { @@ -15447,7 +15416,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.9" + "source": "https://github.com/symfony/mime/tree/v6.4.11" }, "funding": [ { @@ -15463,20 +15432,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T09:49:33+00:00" + "time": "2024-08-13T12:15:02+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.0.0", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "700ff4096e346f54cb628ea650767c8130f1001f" + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f", - "reference": "700ff4096e346f54cb628ea650767c8130f1001f", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55", "shasum": "" }, "require": { @@ -15514,7 +15483,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.0.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.1.1" }, "funding": [ { @@ -15530,7 +15499,7 @@ "type": "tidelift" } ], - "time": "2023-08-08T10:20:21+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/polyfill-ctype", @@ -16382,16 +16351,16 @@ }, { "name": "symfony/psr-http-message-bridge", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "89a24648d73e4eee30893b0da16abc454a65c53b" + "reference": "74835ba54eca99a38f374f7a6d932fa510124773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/89a24648d73e4eee30893b0da16abc454a65c53b", - "reference": "89a24648d73e4eee30893b0da16abc454a65c53b", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/74835ba54eca99a38f374f7a6d932fa510124773", + "reference": "74835ba54eca99a38f374f7a6d932fa510124773", "shasum": "" }, "require": { @@ -16445,7 +16414,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v6.4.10" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v6.4.11" }, "funding": [ { @@ -16461,20 +16430,20 @@ "type": "tidelift" } ], - "time": "2024-07-15T09:36:38+00:00" + "time": "2024-08-14T13:55:58+00:00" }, { "name": "symfony/routing", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "aad19fe10753ba842f0d653a8db819c4b3affa87" + "reference": "8ee0c24c1bf61c263a26f1b9b6d19e83b1121f2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/aad19fe10753ba842f0d653a8db819c4b3affa87", - "reference": "aad19fe10753ba842f0d653a8db819c4b3affa87", + "url": "https://api.github.com/repos/symfony/routing/zipball/8ee0c24c1bf61c263a26f1b9b6d19e83b1121f2a", + "reference": "8ee0c24c1bf61c263a26f1b9b6d19e83b1121f2a", "shasum": "" }, "require": { @@ -16528,7 +16497,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.10" + "source": "https://github.com/symfony/routing/tree/v6.4.11" }, "funding": [ { @@ -16544,20 +16513,20 @@ "type": "tidelift" } ], - "time": "2024-07-15T09:26:24+00:00" + "time": "2024-08-29T08:15:38+00:00" }, { "name": "symfony/serializer", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "9a67fcf320561e96f94d62bbe0e169ac534a5718" + "reference": "a75d03d7720417f8a654e73e8f02acdea8779cd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/9a67fcf320561e96f94d62bbe0e169ac534a5718", - "reference": "9a67fcf320561e96f94d62bbe0e169ac534a5718", + "url": "https://api.github.com/repos/symfony/serializer/zipball/a75d03d7720417f8a654e73e8f02acdea8779cd0", + "reference": "a75d03d7720417f8a654e73e8f02acdea8779cd0", "shasum": "" }, "require": { @@ -16626,7 +16595,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.4.10" + "source": "https://github.com/symfony/serializer/tree/v6.4.11" }, "funding": [ { @@ -16642,7 +16611,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T13:13:26+00:00" + "time": "2024-08-17T07:51:47+00:00" }, { "name": "symfony/service-contracts", @@ -16729,16 +16698,16 @@ }, { "name": "symfony/string", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ccf9b30251719567bfd46494138327522b9a9446" + "reference": "5bc3eb632cf9c8dbfd6529d89be9950d1518883b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ccf9b30251719567bfd46494138327522b9a9446", - "reference": "ccf9b30251719567bfd46494138327522b9a9446", + "url": "https://api.github.com/repos/symfony/string/zipball/5bc3eb632cf9c8dbfd6529d89be9950d1518883b", + "reference": "5bc3eb632cf9c8dbfd6529d89be9950d1518883b", "shasum": "" }, "require": { @@ -16795,7 +16764,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.10" + "source": "https://github.com/symfony/string/tree/v6.4.11" }, "funding": [ { @@ -16811,7 +16780,7 @@ "type": "tidelift" } ], - "time": "2024-07-22T10:21:14+00:00" + "time": "2024-08-12T09:55:28+00:00" }, { "name": "symfony/translation-contracts", @@ -16893,16 +16862,16 @@ }, { "name": "symfony/validator", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "bcf939a9d1acd7d2912e9474c0c3d7840a03cbcd" + "reference": "4ff41cf10af1de99ad92895411b55c9f309bc2d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/bcf939a9d1acd7d2912e9474c0c3d7840a03cbcd", - "reference": "bcf939a9d1acd7d2912e9474c0c3d7840a03cbcd", + "url": "https://api.github.com/repos/symfony/validator/zipball/4ff41cf10af1de99ad92895411b55c9f309bc2d8", + "reference": "4ff41cf10af1de99ad92895411b55c9f309bc2d8", "shasum": "" }, "require": { @@ -16970,7 +16939,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.4.10" + "source": "https://github.com/symfony/validator/tree/v6.4.11" }, "funding": [ { @@ -16986,20 +16955,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:30:32+00:00" + "time": "2024-08-30T15:57:55+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "a71cc3374f5fb9759da1961d28c452373b343dd4" + "reference": "ee14c8254a480913268b1e3b1cba8045ed122694" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a71cc3374f5fb9759da1961d28c452373b343dd4", - "reference": "a71cc3374f5fb9759da1961d28c452373b343dd4", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ee14c8254a480913268b1e3b1cba8045ed122694", + "reference": "ee14c8254a480913268b1e3b1cba8045ed122694", "shasum": "" }, "require": { @@ -17055,7 +17024,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.10" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.11" }, "funding": [ { @@ -17071,7 +17040,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:30:32+00:00" + "time": "2024-08-30T16:03:21+00:00" }, { "name": "symfony/var-exporter", @@ -17151,16 +17120,16 @@ }, { "name": "symfony/yaml", - "version": "v6.4.8", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "52903de178d542850f6f341ba92995d3d63e60c9" + "reference": "be37e7f13195e05ab84ca5269365591edd240335" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/52903de178d542850f6f341ba92995d3d63e60c9", - "reference": "52903de178d542850f6f341ba92995d3d63e60c9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/be37e7f13195e05ab84ca5269365591edd240335", + "reference": "be37e7f13195e05ab84ca5269365591edd240335", "shasum": "" }, "require": { @@ -17203,7 +17172,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.8" + "source": "https://github.com/symfony/yaml/tree/v6.4.11" }, "funding": [ { @@ -17219,7 +17188,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:49:08+00:00" + "time": "2024-08-12T09:55:28+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -17276,24 +17245,23 @@ }, { "name": "twig/twig", - "version": "v3.11.0", + "version": "v3.12.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d" + "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d", - "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea", + "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php80": "^1.22", "symfony/polyfill-php81": "^1.29" }, "require-dev": { @@ -17340,7 +17308,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.11.0" + "source": "https://github.com/twigphp/Twig/tree/v3.12.0" }, "funding": [ { @@ -17352,7 +17320,7 @@ "type": "tidelift" } ], - "time": "2024-08-08T16:15:16+00:00" + "time": "2024-08-29T09:51:12+00:00" }, { "name": "webflo/drupal-finder", @@ -17986,48 +17954,48 @@ }, { "name": "composer/composer", - "version": "2.7.7", + "version": "2.7.9", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "291942978f39435cf904d33739f98d7d4eca7b23" + "reference": "e30ccdd665828ae66eb1be78f056e39e1d5f55ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/291942978f39435cf904d33739f98d7d4eca7b23", - "reference": "291942978f39435cf904d33739f98d7d4eca7b23", + "url": "https://api.github.com/repos/composer/composer/zipball/e30ccdd665828ae66eb1be78f056e39e1d5f55ab", + "reference": "e30ccdd665828ae66eb1be78f056e39e1d5f55ab", "shasum": "" }, "require": { - "composer/ca-bundle": "^1.0", + "composer/ca-bundle": "^1.5", "composer/class-map-generator": "^1.3.3", "composer/metadata-minifier": "^1.0", - "composer/pcre": "^2.1 || ^3.1", + "composer/pcre": "^2.2 || ^3.2", "composer/semver": "^3.3", "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", - "justinrainbow/json-schema": "^5.2.11", + "justinrainbow/json-schema": "^5.3", "php": "^7.2.5 || ^8.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "react/promise": "^2.8 || ^3", + "react/promise": "^3.2", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", "seld/signal-handler": "^2.0", - "symfony/console": "^5.4.11 || ^6.0.11 || ^7", - "symfony/filesystem": "^5.4 || ^6.0 || ^7", - "symfony/finder": "^5.4 || ^6.0 || ^7", + "symfony/console": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/filesystem": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/finder": "^5.4.35 || ^6.3.12 || ^7.0.3", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", "symfony/polyfill-php81": "^1.24", - "symfony/process": "^5.4 || ^6.0 || ^7" + "symfony/process": "^5.4.35 || ^6.3.12 || ^7.0.3" }, "require-dev": { - "phpstan/phpstan": "^1.11.0", + "phpstan/phpstan": "^1.11.8", "phpstan/phpstan-deprecation-rules": "^1.2.0", "phpstan/phpstan-phpunit": "^1.4.0", "phpstan/phpstan-strict-rules": "^1.6.0", "phpstan/phpstan-symfony": "^1.4.0", - "symfony/phpunit-bridge": "^6.4.1 || ^7.0.1" + "symfony/phpunit-bridge": "^6.4.3 || ^7.0.1" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -18080,7 +18048,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.7.7" + "source": "https://github.com/composer/composer/tree/2.7.9" }, "funding": [ { @@ -18096,7 +18064,7 @@ "type": "tidelift" } ], - "time": "2024-06-10T20:11:12+00:00" + "time": "2024-09-04T12:43:28+00:00" }, { "name": "composer/metadata-minifier", @@ -18169,26 +18137,26 @@ }, { "name": "composer/pcre", - "version": "3.2.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90" + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/ea4ab6f9580a4fd221e0418f2c357cdd39102a90", - "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, "conflict": { - "phpstan/phpstan": "<1.11.8" + "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "phpstan/phpstan": "^1.11.8", + "phpstan/phpstan": "^1.11.10", "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "^8 || ^9" }, @@ -18228,7 +18196,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.2.0" + "source": "https://github.com/composer/pcre/tree/3.3.1" }, "funding": [ { @@ -18244,7 +18212,7 @@ "type": "tidelift" } ], - "time": "2024-07-25T09:36:02+00:00" + "time": "2024-08-27T18:44:43+00:00" }, { "name": "composer/spdx-licenses", @@ -19131,7 +19099,7 @@ "homepage": "https://www.drupal.org/user/2320090" }, { - "name": "Musa.thomas", + "name": "musa.thomas", "homepage": "https://www.drupal.org/user/1213824" }, { @@ -19391,26 +19359,26 @@ }, { "name": "drupal/config_update", - "version": "2.0.0-alpha3", + "version": "2.0.0-alpha4", "source": { "type": "git", "url": "https://git.drupalcode.org/project/config_update.git", - "reference": "2.0.0-alpha3" + "reference": "2.0.0-alpha4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/config_update-2.0.0-alpha3.zip", - "reference": "2.0.0-alpha3", - "shasum": "c35e81e8fb77efdff5ddca3a87116ea0c522a7e2" + "url": "https://ftp.drupal.org/files/projects/config_update-2.0.0-alpha4.zip", + "reference": "2.0.0-alpha4", + "shasum": "d8ea528b0b3e24918356bb72bef61408f650aa8e" }, "require": { - "drupal/core": "^9.4 || ^10" + "drupal/core": "^9.4 || ^10 || ^11" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.0.0-alpha3", - "datestamp": "1683807608", + "version": "2.0.0-alpha4", + "datestamp": "1724596931", "security-coverage": { "status": "not-covered", "message": "Alpha releases are not covered by Drupal security advisories." @@ -20131,16 +20099,16 @@ }, { "name": "ec-europa/toolkit", - "version": "10.13.0", + "version": "10.14.0", "source": { "type": "git", "url": "https://github.com/ec-europa/toolkit.git", - "reference": "689b63617d8cde392a65ffa6a446255452b7a3d8" + "reference": "75b891996632fed332d5379b435dac6d20ab639e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ec-europa/toolkit/zipball/689b63617d8cde392a65ffa6a446255452b7a3d8", - "reference": "689b63617d8cde392a65ffa6a446255452b7a3d8", + "url": "https://api.github.com/repos/ec-europa/toolkit/zipball/75b891996632fed332d5379b435dac6d20ab639e", + "reference": "75b891996632fed332d5379b435dac6d20ab639e", "shasum": "" }, "require": { @@ -20196,7 +20164,7 @@ "email": "DIGIT-NEXTEUROPA-QA@ec.europa.eu", "source": "https://github.com/ec-europa/toolkit" }, - "time": "2024-07-25T08:47:19+00:00" + "time": "2024-08-19T13:27:25+00:00" }, { "name": "ec-europa/toolkit-composer-plugin", @@ -20821,23 +20789,24 @@ }, { "name": "mikey179/vfsstream", - "version": "v1.6.11", + "version": "v1.6.12", "source": { "type": "git", "url": "https://github.com/bovigo/vfsStream.git", - "reference": "17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f" + "reference": "fe695ec993e0a55c3abdda10a9364eb31c6f1bf0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f", - "reference": "17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/fe695ec993e0a55c3abdda10a9364eb31c6f1bf0", + "reference": "fe695ec993e0a55c3abdda10a9364eb31c6f1bf0", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "^4.5|^5.0" + "phpunit/phpunit": "^7.5||^8.5||^9.6", + "yoast/phpunit-polyfills": "^2.0" }, "type": "library", "extra": { @@ -20868,7 +20837,7 @@ "source": "https://github.com/bovigo/vfsStream/tree/master", "wiki": "https://github.com/bovigo/vfsStream/wiki" }, - "time": "2022-02-23T02:02:42+00:00" + "time": "2024-08-29T18:43:31+00:00" }, { "name": "myclabs/deep-copy", @@ -21977,16 +21946,16 @@ }, { "name": "phpro/grumphp-shim", - "version": "v2.6.0", + "version": "v2.7.0", "source": { "type": "git", "url": "https://github.com/phpro/grumphp-shim.git", - "reference": "87693a723ef36acfec61e7ca6e98afe7be6666e6" + "reference": "bf98880dc29493e7e82fc06cceb2f5bf2f5d94ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpro/grumphp-shim/zipball/87693a723ef36acfec61e7ca6e98afe7be6666e6", - "reference": "87693a723ef36acfec61e7ca6e98afe7be6666e6", + "url": "https://api.github.com/repos/phpro/grumphp-shim/zipball/bf98880dc29493e7e82fc06cceb2f5bf2f5d94ee", + "reference": "bf98880dc29493e7e82fc06cceb2f5bf2f5d94ee", "shasum": "" }, "require": { @@ -22030,9 +21999,9 @@ "description": "GrumPHP Phar distribution", "support": { "issues": "https://github.com/phpro/grumphp-shim/issues", - "source": "https://github.com/phpro/grumphp-shim/tree/v2.6.0" + "source": "https://github.com/phpro/grumphp-shim/tree/v2.7.0" }, - "time": "2024-06-14T13:09:10+00:00" + "time": "2024-08-22T11:49:22+00:00" }, { "name": "phpspec/prophecy", @@ -22157,16 +22126,16 @@ }, { "name": "phpstan/extension-installer", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/phpstan/extension-installer.git", - "reference": "f6b87faf9fc7978eab2f7919a8760bc9f58f9203" + "reference": "46c8219b3fb0deb3fc08301e8f0797d321d17dcd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f6b87faf9fc7978eab2f7919a8760bc9f58f9203", - "reference": "f6b87faf9fc7978eab2f7919a8760bc9f58f9203", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/46c8219b3fb0deb3fc08301e8f0797d321d17dcd", + "reference": "46c8219b3fb0deb3fc08301e8f0797d321d17dcd", "shasum": "" }, "require": { @@ -22193,24 +22162,28 @@ "MIT" ], "description": "Composer plugin for automatic installation of PHPStan extensions", + "keywords": [ + "dev", + "static analysis" + ], "support": { "issues": "https://github.com/phpstan/extension-installer/issues", - "source": "https://github.com/phpstan/extension-installer/tree/1.4.1" + "source": "https://github.com/phpstan/extension-installer/tree/1.4.2" }, - "time": "2024-06-10T08:20:49+00:00" + "time": "2024-08-26T07:38:00+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f", + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f", "shasum": "" }, "require": { @@ -22242,22 +22215,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-08-29T09:54:52+00:00" }, { "name": "phpstan/phpstan", - "version": "1.11.10", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "640410b32995914bde3eed26fa89552f9c2c082f" + "reference": "d8ed7fffa66de1db0d2972267d8ed1d8fa0fe5a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/640410b32995914bde3eed26fa89552f9c2c082f", - "reference": "640410b32995914bde3eed26fa89552f9c2c082f", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d8ed7fffa66de1db0d2972267d8ed1d8fa0fe5a2", + "reference": "d8ed7fffa66de1db0d2972267d8ed1d8fa0fe5a2", "shasum": "" }, "require": { @@ -22302,7 +22275,7 @@ "type": "github" } ], - "time": "2024-08-08T09:02:50+00:00" + "time": "2024-09-03T19:55:22+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -22353,35 +22326,35 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.31", + "version": "9.2.32", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.6" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -22390,7 +22363,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "9.2.x-dev" } }, "autoload": { @@ -22419,7 +22392,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" }, "funding": [ { @@ -22427,7 +22400,7 @@ "type": "github" } ], - "time": "2024-03-02T06:37:42+00:00" + "time": "2024-08-22T04:23:01+00:00" }, { "name": "phpunit/php-file-iterator", @@ -22848,21 +22821,21 @@ }, { "name": "rector/rector", - "version": "1.2.3", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "2433e95410aef1b34b15d7f1b6a134365a4ddb39" + "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/2433e95410aef1b34b15d7f1b6a134365a4ddb39", - "reference": "2433e95410aef1b34b15d7f1b6a134365a4ddb39", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/42a4aa23b48b4cfc8ebfeac2b570364e27744381", + "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381", "shasum": "" }, "require": { "php": "^7.2|^8.0", - "phpstan/phpstan": "^1.11.9" + "phpstan/phpstan": "^1.11.11" }, "conflict": { "rector/rector-doctrine": "*", @@ -22895,7 +22868,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/1.2.3" + "source": "https://github.com/rectorphp/rector/tree/1.2.4" }, "funding": [ { @@ -22903,7 +22876,7 @@ "type": "github" } ], - "time": "2024-08-12T16:36:46+00:00" + "time": "2024-08-23T09:03:01+00:00" }, { "name": "sebastian/cli-parser", @@ -24390,16 +24363,16 @@ }, { "name": "symfony/phpunit-bridge", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "ad510515b11ba5291fdd59b25d70227bfac2d7ab" + "reference": "168f412dcd6caf3813a9cc0f286cd68f6a76f070" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/ad510515b11ba5291fdd59b25d70227bfac2d7ab", - "reference": "ad510515b11ba5291fdd59b25d70227bfac2d7ab", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/168f412dcd6caf3813a9cc0f286cd68f6a76f070", + "reference": "168f412dcd6caf3813a9cc0f286cd68f6a76f070", "shasum": "" }, "require": { @@ -24452,7 +24425,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.10" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.11" }, "funding": [ { @@ -24468,7 +24441,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:30:32+00:00" + "time": "2024-08-13T14:27:37+00:00" }, { "name": "symfony/polyfill-php73", @@ -24918,7 +24891,13 @@ "source": { "type": "git", "url": "https://git.drupalcode.org/project/dtt.git", - "reference": "5e3df23c93f4f3e4f34fd7677df10bc06616f4ce" + "reference": "eff79539951416dd3ef49cc355804a37aa70c280" + }, + "dist": { + "type": "zip", + "url": "https://git.drupalcode.org/api/v4/projects/project%2Fdtt/repository/archive.zip?sha=eff79539951416dd3ef49cc355804a37aa70c280", + "reference": "eff79539951416dd3ef49cc355804a37aa70c280", + "shasum": "" }, "require": { "php": ">=8.1" @@ -24962,7 +24941,10 @@ } ], "description": "Traits for testing Drupal sites that have user content (versus unpopulated sites).", - "time": "2024-08-10T19:01:22+00:00" + "support": { + "source": "https://git.drupalcode.org/project/dtt/-/tree/2.x" + }, + "time": "2024-08-24T15:19:02+00:00" }, { "name": "weitzman/logintrait", diff --git a/resources/patch/php/bitbucket/client/fe8b7771e51d2a2852b75e7be90fc871b1bc895f.diff b/resources/patch/php/bitbucket/client/fe8b7771e51d2a2852b75e7be90fc871b1bc895f.diff deleted file mode 100644 index 0369236c2e..0000000000 --- a/resources/patch/php/bitbucket/client/fe8b7771e51d2a2852b75e7be90fc871b1bc895f.diff +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/src/Api/Repositories/Workspaces/Src.php b/src/Api/Repositories/Workspaces/Src.php -index 88a4ef2..fb2f2fb 100644 ---- a/src/Api/Repositories/Workspaces/Src.php -+++ b/src/Api/Repositories/Workspaces/Src.php -@@ -94,7 +94,7 @@ public function createWithFiles(array $files, array $params = []) - */ - public function show(string $commit, string $filepath, array $params = []) - { -- $uri = $this->buildSrcUri($commit, $filepath); -+ $uri = $this->buildSrcUri($commit, ...\explode('/', $filepath)); - - if (!isset($params['format'])) { - $params['format'] = 'meta'; -@@ -114,7 +114,7 @@ public function show(string $commit, string $filepath, array $params = []) - */ - public function download(string $commit, string $filepath, array $params = []) - { -- $uri = $this->buildSrcUri($commit, $filepath); -+ $uri = $this->buildSrcUri($commit, ...\explode('/', $filepath)); - - return $this->getAsResponse($uri, $params, ['Accept' => '*/*'])->getBody(); - } diff --git a/resources/patch/php/drupal/default_content/2640734.diff b/resources/patch/php/drupal/default_content/2640734.diff index 27e2d6af0a..28318c1ee4 100644 --- a/resources/patch/php/drupal/default_content/2640734.diff +++ b/resources/patch/php/drupal/default_content/2640734.diff @@ -1,15 +1,3 @@ -diff --git a/composer.json b/composer.json -index 4c6b3fd8ab0b85013e14d31338baf8c1ab258289..cc81c83815313f5cf755fcf3c74342c644fce8ce 100644 ---- a/composer.json -+++ b/composer.json -@@ -9,6 +9,7 @@ - }, - "require-dev": { - "drupal/paragraphs": "^1", -+ "drush/drush": "^11", - "drupal/hal": " ^9 || ^1 || ^2" - }, - "extra": { diff --git a/drush.services.yml b/drush.services.yml index 441ae0c3a481128e5f264ae5ad579ba38e3e6144..a02bba6579a1fa3a0be15dfd2283405e2edd09f7 100644 --- a/drush.services.yml @@ -24,7 +12,7 @@ index 441ae0c3a481128e5f264ae5ad579ba38e3e6144..a02bba6579a1fa3a0be15dfd2283405e tags: - { name: drush.command } diff --git a/src/Commands/DefaultContentCommands.php b/src/Commands/DefaultContentCommands.php -index d9c6da4a52dd5543140cb8741d31063e7b371599..ef36be33c1efba157a97cbd14cdf33e437a22a35 100644 +index 19b858aa04dbaf4760dacf5c02dd4ffa65bda066..00146abf54c4f443011b9f8aa64a5b10c639c7fd 100644 --- a/src/Commands/DefaultContentCommands.php +++ b/src/Commands/DefaultContentCommands.php @@ -2,13 +2,13 @@ @@ -81,13 +69,13 @@ index d9c6da4a52dd5543140cb8741d31063e7b371599..ef36be33c1efba157a97cbd14cdf33e4 } /** -@@ -85,10 +106,71 @@ class DefaultContentCommands extends DrushCommands { +@@ -85,12 +106,75 @@ class DefaultContentCommands extends DrushCommands { * @aliases dcem */ public function contentExportModule($module) { + $this->checkExtensions([$module]); - $module_folder = \Drupal::moduleHandler() - ->getModule($module) + $module_folder = \Drupal::service('extension.list.module') + ->get($module) ->getPath() . '/content'; $this->defaultContentExporter->exportModuleContent($module, $module_folder); } @@ -98,7 +86,8 @@ index d9c6da4a52dd5543140cb8741d31063e7b371599..ef36be33c1efba157a97cbd14cdf33e4 + * @param string[] $extensions + * Space-delimited list of module which may contain also the active profile. + * -+ * @option update Updates existing entities with values from import ++ * @option update Overwrite existing entities with values from the default ++ * content. + * + * @usage drush default-content:import + * Imports default content from all installed modules, including the active @@ -106,14 +95,15 @@ index d9c6da4a52dd5543140cb8741d31063e7b371599..ef36be33c1efba157a97cbd14cdf33e4 + * @usage drush dcim my_module other_module custom_profile + * Imports default content from <info>my_module</info>, + * <info>other_module<info> modules and <info>custom_profile<info> active -+ * profile. -+ * @usage drush default-content:import my_module --no-update -+ * Imports only new default content from <info>my_module</info> module. ++ * profile. Does not overwrite content that was already imported before. ++ * @usage drush default-content:import my_module --update ++ * Imports all default content from <info>my_module</info> module, including ++ * content that has already been imported. + * + * @command default-content:import + * @aliases dcim + */ -+ public function import(array $extensions, array $options = ['update' => TRUE]): void { ++ public function import(array $extensions, array $options = ['update' => FALSE]): void { + $count = 0; + $import_from_extensions = []; + foreach ($this->checkExtensions($extensions) as $extension) { @@ -152,26 +142,34 @@ index d9c6da4a52dd5543140cb8741d31063e7b371599..ef36be33c1efba157a97cbd14cdf33e4 + return $extensions; + } + - } + /** + * Exports all the content and references defined in a module info file. + * +@@ -102,8 +186,8 @@ class DefaultContentCommands extends DrushCommands { + */ + public function contentExportModuleWithReferences($module) { + $module_folder = \Drupal::moduleHandler() +- ->getModule($module) +- ->getPath() . '/content'; ++ ->getModule($module) ++ ->getPath() . '/content'; + $this->defaultContentExporter->exportModuleContentWithReferences($module, $module_folder); + } + diff --git a/src/Importer.php b/src/Importer.php -index 27fedafb8c885a24235fbd8743f4b712a7babc30..7ca9986606bd00ed4e33fbd7336c4e28af35abf9 100644 +index 7115d7a8cd1c811b224527b583f0841308abaacc..7c99f2d15ecdd20c9f8a384f4c0d20be91138c5f 100644 --- a/src/Importer.php +++ b/src/Importer.php -@@ -149,11 +149,12 @@ class Importer implements ImporterInterface { +@@ -179,7 +179,7 @@ class Importer implements ImporterInterface { /** * {@inheritdoc} */ - public function importContent($module) { -+ public function importContent(string $module, bool $update_existing = FALSE) { ++ public function importContent($module, bool $update_existing = FALSE) { $created = []; - $folder = \Drupal::service('extension.list.module')->getPath($module) . "/content"; + $folder = $this->extensionList->getPath($module) . "/content"; - if (file_exists($folder)) { -+ /** @var \Drupal\user\UserInterface $root_user */ - $root_user = $this->entityTypeManager->getStorage('user')->load(1); - $this->accountSwitcher->switchTo($root_user); - $file_map = []; -@@ -251,10 +252,13 @@ class Importer implements ImporterInterface { +@@ -285,10 +285,13 @@ class Importer implements ImporterInterface { $entity = $this->serializer->deserialize($contents, $class, 'hal_json', ['request_method' => 'POST']); } else { @@ -188,7 +186,7 @@ index 27fedafb8c885a24235fbd8743f4b712a7babc30..7ca9986606bd00ed4e33fbd7336c4e28 if ($entity instanceof EntityOwnerInterface && empty($entity->getOwnerId())) { $entity->setOwner($root_user); diff --git a/src/ImporterInterface.php b/src/ImporterInterface.php -index 0d300a31a259081e6a2ee297834243b5182d69d6..abbeb90bc2ec6bc65772c383de71abda79360bac 100644 +index 0d300a31a259081e6a2ee297834243b5182d69d6..25fdcac7c8537b8be08f558edc5b042a34bce830 100644 --- a/src/ImporterInterface.php +++ b/src/ImporterInterface.php @@ -12,10 +12,13 @@ interface ImporterInterface { @@ -196,18 +194,18 @@ index 0d300a31a259081e6a2ee297834243b5182d69d6..abbeb90bc2ec6bc65772c383de71abda * @param string $module * The module to create the default content from. + * @param bool $update_existing -+ * Whether to update an already existing entity with the imported values. ++ * Whether to update already existing entities with the imported values. + * Defaults to FALSE. * * @return \Drupal\Core\Entity\EntityInterface[] * An array of created entities keyed by their UUIDs. */ - public function importContent($module); -+ public function importContent(string $module, bool $update_existing = FALSE); ++ public function importContent($module, bool $update_existing = FALSE); } diff --git a/src/Normalizer/ContentEntityNormalizer.php b/src/Normalizer/ContentEntityNormalizer.php -index 4d5a932f7678b25b2f137074c66b109068d3da05..1024b95b3e2b6f8d5cc39d416baef40a700ec3b3 100644 +index 4d5a932f7678b25b2f137074c66b109068d3da05..30f9d67a640f6fecc40fe9ae8b0e612cdb667243 100644 --- a/src/Normalizer/ContentEntityNormalizer.php +++ b/src/Normalizer/ContentEntityNormalizer.php @@ -150,7 +150,7 @@ class ContentEntityNormalizer implements ContentEntityNormalizerInterface { @@ -219,20 +217,27 @@ index 4d5a932f7678b25b2f137074c66b109068d3da05..1024b95b3e2b6f8d5cc39d416baef40a if (!isset($data['_meta']['entity_type'])) { throw new UnexpectedValueException('The entity type metadata must be specified.'); } -@@ -178,8 +178,21 @@ class ContentEntityNormalizer implements ContentEntityNormalizerInterface { +@@ -178,18 +178,40 @@ class ContentEntityNormalizer implements ContentEntityNormalizerInterface { $values[$entity_type->getKey('langcode')] = $data['_meta']['default_langcode']; } + // Load the entity by UUID and check if it exists. -+ $entity = $this->entityTypeManager->getStorage($entity_type->id())->loadByProperties(['uuid' => $values['uuid']]); ++ $existing = $this->entityTypeManager->getStorage($entity_type->id())->loadByProperties(['uuid' => $values['uuid']]); /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ - $entity = $this->entityTypeManager->getStorage($entity_type->id())->create($values); -+ if (!empty($entity)) { ++ if (!empty($existing)) { ++ $entity = reset($existing); + if (!$update_existing) { + // Do not override the existing entity. -+ return reset($entity); ++ return $entity; ++ } ++ elseif (method_exists($entity, 'setNeedsSave')) { ++ // Ensure ERR entity will be saved. ++ // @todo Use instanceof EntityNeedSaveInterface once ++ // https://www.drupal.org/project/entity_reference_revisions/issues/3336752 ++ // is fixed. ++ $entity->setNeedsSave(TRUE); + } -+ $entity = reset($entity); + } + else { + $entity = $this->entityTypeManager->getStorage($entity_type->id())->create($values); @@ -240,8 +245,44 @@ index 4d5a932f7678b25b2f137074c66b109068d3da05..1024b95b3e2b6f8d5cc39d416baef40a + } + foreach ($data['default'] as $field_name => $values) { - $this->setFieldValues($entity, $field_name, $values); +- $this->setFieldValues($entity, $field_name, $values); ++ $this->setFieldValues($entity, $field_name, $values, $update_existing); } + + if (!empty($data['translations'])) { + foreach ($data['translations'] as $langcode => $translation_data) { + if ($this->languageManager->getLanguage($langcode)) { +- $translation = $entity->addTranslation($langcode, $entity->toArray()); ++ $translation = $entity->hasTranslation($langcode) ++ ? $entity->getTranslation($langcode) ++ : $entity->addTranslation($langcode, $entity->toArray()); + foreach ($translation_data as $field_name => $values) { +- $this->setFieldValues($translation, $field_name, $values); ++ $this->setFieldValues($translation, $field_name, $values, $update_existing); + } + } + } +@@ -211,8 +233,10 @@ class ContentEntityNormalizer implements ContentEntityNormalizerInterface { + * The name of the field. + * @param array $values + * The normalized data for the field. ++ * @param bool $update_existing ++ * Whether to update already existing entities with the imported values. + */ +- protected function setFieldValues(ContentEntityInterface $entity, string $field_name, array $values) { ++ protected function setFieldValues(ContentEntityInterface $entity, string $field_name, array $values, bool $update_existing = FALSE) { + if (!$entity->hasField($field_name)) { + return; + } +@@ -246,7 +270,7 @@ class ContentEntityNormalizer implements ContentEntityNormalizerInterface { + + if ($property instanceof EntityReference) { + if (is_array($value)) { +- $target_entity = $this->denormalize($value); ++ $target_entity = $this->denormalize($value, $update_existing); + } + else { + $target_entity = $this->loadEntityDependency($value); diff --git a/src/Normalizer/ContentEntityNormalizerInterface.php b/src/Normalizer/ContentEntityNormalizerInterface.php index fa78b79545786772df49b110d6f72fa442c38aa9..1587248f3872226ddac1cdd90e0ecb1e995d9d31 100644 --- a/src/Normalizer/ContentEntityNormalizerInterface.php @@ -619,10 +660,10 @@ index 0000000000000000000000000000000000000000..fa77e97928a2d843e47dd0ce93055390 + - drupal:taxonomy diff --git a/tests/src/Functional/DefaultContentDrushTest.php b/tests/src/Functional/DefaultContentDrushTest.php new file mode 100644 -index 0000000000000000000000000000000000000000..c8cc54e68576d87e6909a8b0628d8fc60ee17d55 +index 0000000000000000000000000000000000000000..b07bcf7f7dedd5c164943e8f3134c3bce8398015 --- /dev/null +++ b/tests/src/Functional/DefaultContentDrushTest.php -@@ -0,0 +1,294 @@ +@@ -0,0 +1,292 @@ +<?php + +declare(strict_types = 1); @@ -746,11 +787,9 @@ index 0000000000000000000000000000000000000000..c8cc54e68576d87e6909a8b0628d8fc6 + // At this point, the content should still be in their original state. + $this->assertFieldValues($this->getOriginalFieldValues()); + -+ // Run the import with --no-update option. ++ // Run the import without allowing updates. + $args = $pass_module_list ? ['default_content_test_yaml_updated'] : []; -+ $this->drush('default-content:import', $args, [ -+ 'no-update' => NULL, -+ ]); ++ $this->drush('default-content:import', $args); + $this->assertStringContainsString('1 entity imported from default_content_test_yaml_updated', $this->getErrorOutputRaw()); + + // Check that entities were not updated. @@ -759,7 +798,7 @@ index 0000000000000000000000000000000000000000..c8cc54e68576d87e6909a8b0628d8fc6 + $this->assertSame('Additional node', \Drupal::service('entity.repository')->loadEntityByUuid('node', '7a8563a8-15c9-4f60-9ebc-630b9562672c')->label()); + + // Run again the import but allow updates. -+ $this->drush('default-content:import', $args); ++ $this->drush('default-content:import', $args, ['update' => NULL]); + $this->assertStringContainsString('6 entities imported from default_content_test_yaml_updated', $this->getErrorOutputRaw()); + + // Check that entities were updated. @@ -930,3 +969,532 @@ index cea7bddfc5dcf35290a15f1648ef7618337dda72..4ac9aa5cafa696ab60f924694d0f4e7c $term_id = $node->field_tags->target_id; $this->assertNotEmpty($term_id); } +diff --git a/tests/src/Kernel/DefaultContentImportExistingContentTest.php b/tests/src/Kernel/DefaultContentImportExistingContentTest.php +new file mode 100644 +index 0000000000000000000000000000000000000000..b0bd528f7ab0ad48b752c899336563cb90971083 +--- /dev/null ++++ b/tests/src/Kernel/DefaultContentImportExistingContentTest.php +@@ -0,0 +1,277 @@ ++<?php ++ ++declare(strict_types = 1); ++ ++namespace Drupal\Tests\default_content\Kernel; ++ ++use Drupal\file\Entity\File; ++use Drupal\file\FileInterface; ++use Drupal\KernelTests\KernelTestBase; ++use Drupal\taxonomy\Entity\Vocabulary; ++use Drupal\Tests\node\Traits\ContentTypeCreationTrait; ++use Drupal\Tests\node\Traits\NodeCreationTrait; ++use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait; ++use Drupal\Tests\user\Traits\UserCreationTrait; ++ ++/** ++ * Tests that we can control whether existing content is updated on import. ++ * ++ * @coversDefaultClass \Drupal\default_content\Importer ++ * @group default_content ++ */ ++class DefaultContentImportExistingContentTest extends KernelTestBase { ++ ++ use ContentTypeCreationTrait; ++ use NodeCreationTrait; ++ use TaxonomyTestTrait; ++ use UserCreationTrait; ++ ++ /** ++ * {@inheritdoc} ++ */ ++ protected static $modules = [ ++ 'default_content', ++ 'field', ++ 'file', ++ 'filter', ++ 'node', ++ 'system', ++ 'taxonomy', ++ 'text', ++ 'user', ++ ]; ++ ++ /** ++ * {@inheritdoc} ++ */ ++ protected function setUp(): void { ++ parent::setUp(); ++ ++ $this->installSchema('node', 'node_access'); ++ $this->installEntitySchema('file'); ++ $this->installEntitySchema('node'); ++ $this->installEntitySchema('taxonomy_term'); ++ $this->installEntitySchema('user'); ++ $this->installSchema('file', 'file_usage'); ++ $this->installConfig(['field', 'file', 'filter', 'node', 'system', 'taxonomy']); ++ ++ // Create the root user since this is used as the default owner for imported ++ // content. ++ $this->createUser([], 'root', FALSE, ['uid' => 1]); ++ ++ $this->createContentType(['type' => 'page']); ++ ++ // Create pre-existing content entities. This is used to check if the ++ // 'default_content:import' command successfully ignores or updates ++ // existing content. ++ $nodes_to_create = [ ++ [ ++ 'title' => 'Existing page', ++ 'type' => 'page', ++ 'body' => 'This is an existing page.', ++ 'uuid' => '65c412a3-b83f-4efb-8a05-5a6ecea10ad4', ++ ], ++ [ ++ 'title' => 'Existing page 2', ++ 'type' => 'page', ++ 'body' => 'This is another existing page.', ++ 'uuid' => '78c412a3-b83f-4efb-8a05-5a6ecea10aee', ++ ], ++ ]; ++ foreach ($nodes_to_create as $node_to_create) { ++ $this->createNode($node_to_create); ++ } ++ ++ $files_to_create = [ ++ [ ++ 'filename' => 'test-file.txt', ++ 'uri' => 'public://test-file.txt', ++ 'uuid' => '806afcf6-05bf-4178-92dd-ae9445285770', ++ ], ++ [ ++ 'filename' => 'test-file2.txt', ++ 'uri' => 'public://existing_file2.txt', ++ 'uuid' => '806afcf6-05bf-4178-92dd-ae9445285771', ++ ], ++ ]; ++ foreach ($files_to_create as $file_to_create) { ++ $this->createFile($file_to_create); ++ } ++ ++ $tags_vocabulary = Vocabulary::create(['vid' => 'tags', 'name' => 'Tags']); ++ $tags_vocabulary->save(); ++ ++ // Create a pre-existing taxonomy term. ++ $taxonomy_term_to_create = [ ++ 'name' => 'A tag', ++ 'vid' => $tags_vocabulary->id(), ++ 'description' => '', ++ 'uuid' => '550f86ad-aa11-4047-953f-636d42889f85', ++ ]; ++ $this->createTerm($tags_vocabulary, $taxonomy_term_to_create); ++ } ++ ++ /** ++ * Tests that existing content is only updated if $update_existing is TRUE. ++ * ++ * @covers ::importContent ++ * @dataProvider importingExistingContentDataProvider ++ */ ++ public function testImportingExistingContent(bool $update_existing): void { ++ $this->container->get('default_content.importer')->importContent('default_content_test_yaml', $update_existing); ++ ++ $expected_values = $update_existing ? $this->getUpdatedFieldValues() : $this->getOriginalFieldValues(); ++ $this->assertFieldValues($expected_values); ++ } ++ ++ /** ++ * Data provider for ::testImportingExistingContent(). ++ * ++ * @return array ++ * An array of test data for testing both states of the $update_existing ++ * parameter. ++ */ ++ public function importingExistingContentDataProvider(): array { ++ return [[TRUE], [FALSE]]; ++ } ++ ++ /** ++ * Asserts that a list of entities have expected field values. ++ * ++ * @param array $expected ++ * An associative array where the keys are entity type IDs and values are ++ * associative arrays keyed by entity UUIDs and having the expected labels ++ * as values. ++ */ ++ protected function assertFieldValues(array $expected): void { ++ $entity_type_manager = \Drupal::entityTypeManager(); ++ /** @var \Drupal\Core\Entity\EntityRepositoryInterface $repository */ ++ $repository = \Drupal::service('entity.repository'); ++ foreach ($expected as $entity_type_id => $uuids) { ++ // Need to get fresh copies of the entities. ++ $entity_type_manager->getStorage($entity_type_id)->resetCache(); ++ foreach ($uuids as $uuid => $fields) { ++ $entity = $repository->loadEntityByUuid($entity_type_id, $uuid); ++ foreach ($fields as $field_name => $expected_field_value) { ++ $this->assertSame($expected_field_value, $entity->get($field_name)->value, "Entity $entity_type_id:$uuid has the expected value for field $field_name."); ++ } ++ } ++ } ++ } ++ ++ /** ++ * Returns the original field values of entities to be imported. ++ * ++ * This returns a curated list of test field values of default content in the ++ * `default_content_test_yaml` module. ++ * ++ * @return string[][][] ++ * An associative array where the keys are entity type IDs and values are ++ * associative arrays keyed by entity UUIDs. The values are associative ++ * arrays keyed by field names and having the original field values as ++ * values. ++ */ ++ protected function getOriginalFieldValues(): array { ++ return [ ++ 'file' => [ ++ '806afcf6-05bf-4178-92dd-ae9445285770' => [ ++ 'filename' => 'test-file.txt', ++ 'uri' => 'public://test-file.txt', ++ ], ++ '806afcf6-05bf-4178-92dd-ae9445285771' => [ ++ 'filename' => 'test-file2.txt', ++ 'uri' => 'public://existing_file2.txt', ++ ], ++ ], ++ 'node' => [ ++ '65c412a3-b83f-4efb-8a05-5a6ecea10ad4' => [ ++ 'title' => 'Existing page', ++ 'body' => 'This is an existing page.', ++ ], ++ '78c412a3-b83f-4efb-8a05-5a6ecea10aee' => [ ++ 'title' => 'Existing page 2', ++ 'body' => 'This is another existing page.', ++ ], ++ ], ++ 'taxonomy_term' => [ ++ '550f86ad-aa11-4047-953f-636d42889f85' => [ ++ 'name' => 'A tag', ++ 'description' => NULL, ++ ], ++ ], ++ ]; ++ } ++ ++ /** ++ * Returns the updated field values of entities to be imported. ++ * ++ * This returns a curated list of test field values of default content in the ++ * `default_content_test_yaml_updated` module. ++ * ++ * @return string[][][] ++ * Same as ::getOriginalFieldValues() but with updated field values. ++ */ ++ protected function getUpdatedFieldValues(): array { ++ return [ ++ 'file' => [ ++ '806afcf6-05bf-4178-92dd-ae9445285770' => [ ++ 'filename' => 'test-file.txt', ++ // Since a file already exists at that location, the updated file has ++ // automatically been suffixed with '_0'. ++ 'uri' => 'public://test-file_0.txt', ++ ], ++ '806afcf6-05bf-4178-92dd-ae9445285771' => [ ++ 'filename' => 'test-file1.txt', ++ 'uri' => 'public://example/test-file1.txt', ++ ], ++ ], ++ 'node' => [ ++ '65c412a3-b83f-4efb-8a05-5a6ecea10ad4' => [ ++ 'title' => 'Imported node', ++ 'body' => 'Crikey it works!', ++ ], ++ '78c412a3-b83f-4efb-8a05-5a6ecea10aee' => [ ++ 'title' => 'Imported node with owned by user that does not exist', ++ 'body' => 'Crikey it works!', ++ ], ++ ], ++ 'taxonomy_term' => [ ++ '550f86ad-aa11-4047-953f-636d42889f85' => [ ++ 'name' => 'A tag', ++ 'description' => NULL, ++ ], ++ ], ++ ]; ++ } ++ ++ /** ++ * Creates and saves a test file. ++ * ++ * @param array $values ++ * An array of values to set, keyed by property name. ++ * ++ * @return \Drupal\file\FileInterface ++ * A file entity. ++ */ ++ protected function createFile(array $values): FileInterface { ++ // Add defaults for missing properties. ++ $values += [ ++ 'uid' => 1, ++ 'filename' => 'default_content_test_file.txt', ++ 'uri' => 'public://default_content_test_file.txt', ++ 'filemime' => 'text/plain', ++ 'created' => 1, ++ 'changed' => 1, ++ ]; ++ ++ $file = File::create($values); ++ $file->setPermanent(); ++ ++ file_put_contents($file->getFileUri(), 'hello world'); ++ ++ $file->save(); ++ ++ return $file; ++ } ++ ++} +diff --git a/tests/src/Kernel/MenuLinkContentNormalizerTest.php b/tests/src/Kernel/MenuLinkContentNormalizerTest.php +index 4b195703a3f7e8ae6197fe7161dbad8bee6b467b..4b0374f3671c330f744b834b9e8e50858d08476f 100644 +--- a/tests/src/Kernel/MenuLinkContentNormalizerTest.php ++++ b/tests/src/Kernel/MenuLinkContentNormalizerTest.php +@@ -45,6 +45,20 @@ class MenuLinkContentNormalizerTest extends KernelTestBase { + */ + protected $exporter; + ++ /** ++ * A node to reference in menu links. ++ * ++ * @var \Drupal\node\NodeInterface ++ */ ++ protected $referencedNode; ++ ++ /** ++ * A test menu link. ++ * ++ * @var \Drupal\menu_link_content\MenuLinkContentInterface ++ */ ++ protected $link; ++ + /** + * {@inheritdoc} + */ +@@ -62,31 +76,30 @@ class MenuLinkContentNormalizerTest extends KernelTestBase { + 'type' => 'page', + 'name' => 'page', + ])->save(); +- } +- +- /** +- * Tests menu_link_content entities. +- */ +- public function testMenuLinks() { + +- /** @var \Drupal\node\NodeInterface $referenced_node */ +- $referenced_node = Node::create([ ++ // Create a node to reference in menu links. ++ $this->referencedNode = Node::create([ + 'type' => 'page', + 'title' => 'Referenced node', + ]); +- $referenced_node->save(); ++ $this->referencedNode->save(); + +- /** @var \Drupal\menu_link_content\MenuLinkContentInterface $link */ +- $link = MenuLinkContent::create([ ++ // Create a test menu link that references the test node. ++ $this->link = MenuLinkContent::create([ + 'title' => 'Parent menu link', +- 'link' => 'entity:node/' . $referenced_node->id(), ++ 'link' => 'entity:node/' . $this->referencedNode->id(), + ]); +- $link->save(); ++ $this->link->save(); ++ } + ++ /** ++ * Tests menu_link_content entities. ++ */ ++ public function testMenuLinks() { + /** @var \Drupal\menu_link_content\MenuLinkContentInterface $child_link */ + $child_link = MenuLinkContent::create([ + 'title' => 'Child menu link', +- 'parent' => 'menu_link_content:' . $link->uuid(), ++ 'parent' => 'menu_link_content:' . $this->link->uuid(), + 'link' => [ + 'uri' => 'https://www.example.org', + 'options' => [ +@@ -101,17 +114,17 @@ class MenuLinkContentNormalizerTest extends KernelTestBase { + /** @var \Drupal\default_content\Normalizer\ContentEntityNormalizerInterface $normalizer */ + $normalizer = \Drupal::service('default_content.content_entity_normalizer'); + +- $normalized = $normalizer->normalize($link); ++ $normalized = $normalizer->normalize($this->link); + + $expected = [ + '_meta' => [ + 'version' => '1.0', + 'entity_type' => 'menu_link_content', +- 'uuid' => $link->uuid(), ++ 'uuid' => $this->link->uuid(), + 'bundle' => 'menu_link_content', + 'default_langcode' => 'en', + 'depends' => [ +- $referenced_node->uuid() => 'node', ++ $this->referencedNode->uuid() => 'node', + ], + ], + 'default' => [ +@@ -132,7 +145,7 @@ class MenuLinkContentNormalizerTest extends KernelTestBase { + ], + 'link' => [ + 0 => [ +- 'target_uuid' => $referenced_node->uuid(), ++ 'target_uuid' => $this->referencedNode->uuid(), + 'title' => '', + 'options' => [], + ], +@@ -177,7 +190,7 @@ class MenuLinkContentNormalizerTest extends KernelTestBase { + 'bundle' => 'menu_link_content', + 'default_langcode' => 'en', + 'depends' => [ +- $link->uuid() => 'menu_link_content', ++ $this->link->uuid() => 'menu_link_content', + ], + ], + 'default' => [ +@@ -242,19 +255,64 @@ class MenuLinkContentNormalizerTest extends KernelTestBase { + $this->assertEquals($expected_child, $normalized_child); + + // Delete the link and referenced node and recreate them. +- $normalized_node = $normalizer->normalize($referenced_node); ++ $normalized_node = $normalizer->normalize($this->referencedNode); + $child_link->delete(); +- $link->delete(); +- $referenced_node->delete(); ++ $this->link->delete(); ++ $this->referencedNode->delete(); + + $recreated_node = $normalizer->denormalize($normalized_node); + $recreated_node->save(); +- $this->assertNotEquals($referenced_node->id(), $recreated_node->id()); ++ $this->assertNotEquals($this->referencedNode->id(), $recreated_node->id()); + + $recreated_link = $normalizer->denormalize($normalized); +- $recreated_link->save(); +- + $this->assertEquals('entity:node/' . $recreated_node->id(), $recreated_link->get('link')->uri); ++ ++ // Since the original link has been deleted, this should be a new link. ++ $this->assertTrue($recreated_link->isNew()); ++ } ++ ++ /** ++ * Tests that we can control whether existing menu links are updated or not. ++ * ++ * @param bool $update_existing ++ * Whether to update existing menu links. ++ * ++ * @dataProvider updateExistingMenuLinkProvider ++ */ ++ public function testUpdatingExistingMenuLink($update_existing): void { ++ // Change the existing menu link to reference a different node. ++ $different_node = Node::create([ ++ 'type' => 'page', ++ 'title' => 'Different node', ++ ]); ++ $different_node->save(); ++ ++ $this->link->set('link', 'entity:node/' . $different_node->id()); ++ ++ /** @var \Drupal\default_content\Normalizer\ContentEntityNormalizerInterface $normalizer */ ++ $normalizer = \Drupal::service('default_content.content_entity_normalizer'); ++ $normalized_link = $normalizer->normalize($this->link); ++ $recreated_link = $normalizer->denormalize($normalized_link, $update_existing); ++ ++ // Regardless whether or not we are updating existing menu links, the link ++ // is not new since it already exists in the database. ++ $this->assertFalse($recreated_link->isNew()); ++ ++ // The node reference should only change if we allow updating existing menu ++ // links. ++ $expected_reference = $update_existing ? 'entity:node/' . $different_node->id() : 'entity:node/' . $this->referencedNode->id(); ++ $this->assertEquals($expected_reference, $recreated_link->get('link')->uri); ++ } ++ ++ /** ++ * Provides test data for ::testUpdatingExistingMenuLink(). ++ * ++ * @return array ++ * An array of test data for testing both states of the '$update_existing' ++ * parameter. ++ */ ++ public function updateExistingMenuLinkProvider() { ++ return [[TRUE], [FALSE]]; + } + + } +diff --git a/tests/src/Kernel/ParagraphNormalizerTest.php b/tests/src/Kernel/ParagraphNormalizerTest.php +index 22a729a95534a971c89a0b2b9dbefa24580e3b0b..e55766fb18277e3eff742f36d0f5e597756d4b3a 100644 +--- a/tests/src/Kernel/ParagraphNormalizerTest.php ++++ b/tests/src/Kernel/ParagraphNormalizerTest.php +@@ -361,4 +361,61 @@ class ParagraphNormalizerTest extends KernelTestBase { + $this->assertArrayNotHasKey('paragraph', $by_entity_type); + } + ++ /** ++ * Tests that we can control whether existing paragraphs are updated or not. ++ * ++ * @param bool $update_existing ++ * Whether to update existing paragraphs. ++ * ++ * @dataProvider updateExistingParagraphsProvider ++ */ ++ public function testUpdatingExistingParagraphs($update_existing): void { ++ // Create a pre-existing paragraph that references a node. ++ $referenced_node = Node::create([ ++ 'type' => 'page', ++ 'title' => 'Referenced node', ++ ]); ++ $referenced_node->save(); ++ ++ $paragraph = Paragraph::create([ ++ 'type' => 'paragraph_type', ++ 'field_node_reference' => $referenced_node, ++ ]); ++ $paragraph->save(); ++ ++ // Change the existing paragraph to reference a different node. ++ $different_node = Node::create([ ++ 'type' => 'page', ++ 'title' => 'Different node', ++ ]); ++ $different_node->save(); ++ ++ $paragraph->set('field_node_reference', $different_node); ++ ++ /** @var \Drupal\default_content\Normalizer\ContentEntityNormalizerInterface $normalizer */ ++ $normalizer = \Drupal::service('default_content.content_entity_normalizer'); ++ $normalized_paragraph = $normalizer->normalize($paragraph); ++ $recreated_paragraph = $normalizer->denormalize($normalized_paragraph, $update_existing); ++ ++ // Regardless whether or not we are updating existing paragraphs, the ++ // paragraph is not new since it already exists in the database. ++ $this->assertFalse($recreated_paragraph->isNew()); ++ ++ // The node reference should only change if we allow to update existing] ++ // paragraphs. ++ $expected_reference = $update_existing ? $different_node->id() : $referenced_node->id(); ++ $this->assertEquals($expected_reference, $recreated_paragraph->get('field_node_reference')->target_id); ++ } ++ ++ /** ++ * Provides test data for ::testUpdatingExistingParagraphs(). ++ * ++ * @return array ++ * An array of test data for testing both states of the '$update_existing' ++ * parameter. ++ */ ++ public function updateExistingParagraphsProvider() { ++ return [[TRUE], [FALSE]]; ++ } ++ + } diff --git a/resources/patch/php/drupal/flag/3410265.diff b/resources/patch/php/drupal/flag/3410265.diff deleted file mode 100644 index 2d57dcec72..0000000000 --- a/resources/patch/php/drupal/flag/3410265.diff +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/config/schema/flag.schema.yml b/config/schema/flag.schema.yml -index ca5845b1d8b3f33463c486bdf535e3cfbbf8923c..00b78fad9d0d1074b0f9590d6b6a8c37c7759f14 100644 ---- a/config/schema/flag.schema.yml -+++ b/config/schema/flag.schema.yml -@@ -15,7 +15,7 @@ flag.flag.*: - type: sequence - label: 'The entity bundles this flag applies to' - sequence: -- - type: string -+ type: string - entity_type: - type: string - label: 'Flaggable entity type' diff --git a/resources/patch/php/drupal/flag/3410363.diff b/resources/patch/php/drupal/flag/3410363.diff deleted file mode 100644 index 51ea8bd6da..0000000000 --- a/resources/patch/php/drupal/flag/3410363.diff +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/FlagCountManager.php b/src/FlagCountManager.php -index 08ce766c64d17429f73dc473d911489c1e82d74a..b726a7e0d8281310872affe581906c74fa2407a1 100644 ---- a/src/FlagCountManager.php -+++ b/src/FlagCountManager.php -@@ -197,7 +197,7 @@ class FlagCountManager implements FlagCountManagerInterface, EventSubscriberInte - $entity = $flagging->getFlaggable(); - - $this->connection->merge('flag_counts') -- ->key([ -+ ->keys([ - 'flag_id' => $flag->id(), - 'entity_id' => $entity->id(), - 'entity_type' => $entity->getEntityTypeId(), diff --git a/resources/patch/php/drupal/social_media_links/3319694.patch b/resources/patch/php/drupal/social_media_links/3319694.patch deleted file mode 100644 index 73586360a4..0000000000 --- a/resources/patch/php/drupal/social_media_links/3319694.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 8e8b467a592c45c961ed0dc5a04422a2e580a9ce Mon Sep 17 00:00:00 2001 -From: Adam Pietras <adam@crafter.net.pl> -Date: Wed, 8 Feb 2023 15:13:53 +0100 -Subject: [PATCH] 3319694 Set urlPrefix for Mastodon on https:// - ---- - src/Plugin/SocialMediaLinks/Platform/Mastodon.php | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/Plugin/SocialMediaLinks/Platform/Mastodon.php b/src/Plugin/SocialMediaLinks/Platform/Mastodon.php -index 3b0f559..f7344b5 100644 ---- a/src/Plugin/SocialMediaLinks/Platform/Mastodon.php -+++ b/src/Plugin/SocialMediaLinks/Platform/Mastodon.php -@@ -10,7 +10,7 @@ use Drupal\social_media_links\PlatformBase; - * @Platform( - * id = "mastodon", - * name = @Translation("Mastodon"), -- * urlPrefix = "https://fintoot.space/", -+ * urlPrefix = "https://", - * ) - */ - class Mastodon extends PlatformBase {} --- -GitLab - diff --git a/resources/patch/php/drupal/social_media_links/3384469-7.patch b/resources/patch/php/drupal/social_media_links/3384469-7.patch deleted file mode 100644 index 24bc51079c..0000000000 --- a/resources/patch/php/drupal/social_media_links/3384469-7.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/social_media_links.libraries.yml b/social_media_links.libraries.yml -index 6fe0eae..ff6ee13 100644 ---- a/social_media_links.libraries.yml -+++ b/social_media_links.libraries.yml -@@ -6,4 +6,4 @@ social_media_links.theme: - fontawesome.component: - css: - component: -- //cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css : { type: external } -+ //cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css : { type: external } -diff --git a/src/Plugin/SocialMediaLinks/Platform/Twitter.php b/src/Plugin/SocialMediaLinks/Platform/Twitter.php -index b462a64..dec83c3 100644 ---- a/src/Plugin/SocialMediaLinks/Platform/Twitter.php -+++ b/src/Plugin/SocialMediaLinks/Platform/Twitter.php -@@ -9,8 +9,10 @@ use Drupal\social_media_links\PlatformBase; - * - * @Platform( - * id = "twitter", -- * name = @Translation("Twitter"), -- * urlPrefix = "https://www.twitter.com/", -+ * name = @Translation("X"), -+ * iconName = "x-twitter", -+ * description = @Translation("Previously known as Twitter."), -+ * urlPrefix = "https://www.x.com/", - * ) - */ - class Twitter extends PlatformBase {} diff --git a/resources/patch/php/drupal/social_media_links/3397614.patch b/resources/patch/php/drupal/social_media_links/3397614.patch deleted file mode 100644 index ea9d98c5be..0000000000 --- a/resources/patch/php/drupal/social_media_links/3397614.patch +++ /dev/null @@ -1,64 +0,0 @@ -From d5da06344e31ee3a1d5d2149d16736dd9b8dac32 Mon Sep 17 00:00:00 2001 -From: Adrian Lorenc <adrian.lorenc@gmail.com> -Date: Mon, 30 Oct 2023 11:35:17 +0100 -Subject: [PATCH] 3397614: Theme suggestions for social_media_links_field - ---- - .../social_media_links_field.module | 30 +++++++++++++++++++ - .../SocialMediaLinksFieldDefaultFormatter.php | 3 ++ - 2 files changed, 33 insertions(+) - create mode 100644 modules/social_media_links_field/social_media_links_field.module - -diff --git a/modules/social_media_links_field/social_media_links_field.module b/modules/social_media_links_field/social_media_links_field.module -new file mode 100644 -index 0000000..b9c9a91 ---- /dev/null -+++ b/modules/social_media_links_field/social_media_links_field.module -@@ -0,0 +1,30 @@ -+<?php -+ -+/** -+ * @file -+ * Contains social_media_links_field.module. -+ */ -+ -+/** -+ * Implements hook_theme_registry_alter(). -+ */ -+function social_media_links_field_theme_registry_alter(&$theme_registry) { -+ $theme_registry['social_media_links_platforms']['variables']['entity_type'] = NULL; -+ $theme_registry['social_media_links_platforms']['variables']['entity_bundle'] = NULL; -+ $theme_registry['social_media_links_platforms']['variables']['field_name'] = NULL; -+} -+ -+/** -+ * Implements hook_theme_suggestions_HOOK_alter(). -+ */ -+function social_media_links_field_theme_suggestions_social_media_links_platforms_alter(array &$suggestions, array $variables) { -+ $suggestions = []; -+ if (isset($variables['field_name'])) { -+ $suggestions[] = 'social_media_links_platforms__' . $variables['field_name']; -+ $suggestions[] = 'social_media_links_platforms__' . $variables['entity_type'] . '__' . $variables['entity_bundle']; -+ $suggestions[] = 'social_media_links_platforms__' . $variables['entity_type'] . '__' . $variables['field_name']; -+ $suggestions[] = 'social_media_links_platforms__' . $variables['entity_type'] . '__' . $variables['field_name'] . '__' . $variables['entity_bundle']; -+ } -+ -+ return $suggestions; -+} -diff --git a/modules/social_media_links_field/src/Plugin/Field/FieldFormatter/SocialMediaLinksFieldDefaultFormatter.php b/modules/social_media_links_field/src/Plugin/Field/FieldFormatter/SocialMediaLinksFieldDefaultFormatter.php -index 52cbd83..2bb8388 100644 ---- a/modules/social_media_links_field/src/Plugin/Field/FieldFormatter/SocialMediaLinksFieldDefaultFormatter.php -+++ b/modules/social_media_links_field/src/Plugin/Field/FieldFormatter/SocialMediaLinksFieldDefaultFormatter.php -@@ -61,6 +61,9 @@ class SocialMediaLinksFieldDefaultFormatter extends FormatterBase { - '#attached' => [ - 'library' => ['social_media_links/social_media_links.theme'], - ], -+ '#field_name' => $items->getName(), -+ '#entity_type' => $items->getParent()->getEntity()->getEntityTypeId(), -+ '#entity_bundle' => $items->getParent()->getEntity()->bundle(), - ]; - - if ($iconset['instance']->getPath() === 'library' && (array) $library = $iconset['instance']->getLibrary()) { --- -GitLab - diff --git a/resources/patch/gitonomy/gitlib/217.diff b/resources/patch/php/gitonomy/gitlib/217.diff similarity index 100% rename from resources/patch/gitonomy/gitlib/217.diff rename to resources/patch/php/gitonomy/gitlib/217.diff diff --git a/resources/patch/php/drupal/m4tthumphrey/php-gitlab-api/726.diff b/resources/patch/php/m4tthumphrey/php-gitlab-api/726.diff similarity index 100% rename from resources/patch/php/drupal/m4tthumphrey/php-gitlab-api/726.diff rename to resources/patch/php/m4tthumphrey/php-gitlab-api/726.diff diff --git a/resources/patch/php/drupal/m4tthumphrey/php-gitlab-api/772.diff b/resources/patch/php/m4tthumphrey/php-gitlab-api/772.diff similarity index 100% rename from resources/patch/php/drupal/m4tthumphrey/php-gitlab-api/772.diff rename to resources/patch/php/m4tthumphrey/php-gitlab-api/772.diff diff --git a/web/themes/iop/assets/js/glide.min.js b/web/themes/iop/assets/js/glide.min.js index b680c58556..f5473d9d4b 100644 --- a/web/themes/iop/assets/js/glide.min.js +++ b/web/themes/iop/assets/js/glide.min.js @@ -1,7 +1,7 @@ !function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict"; /*! - * Glide.js v3.6.2 - * (c) 2013-2024 Jędrzej Chałubek (https://github.com/jedrzejchalubek/) + * Glide.js v3.6.0 + * (c) 2013-2022 Jędrzej Chałubek (https://github.com/jedrzejchalubek/) * Released under the MIT License. - */function t(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function e(e){for(var n=1;n<arguments.length;n++){var i=null!=arguments[n]?arguments[n]:{};n%2?t(Object(i),!0).forEach((function(t){s(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):t(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&r(t.prototype,e),n&&r(t,n),t}function s(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function u(t){return u=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},u(t)}function a(t,e){return a=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},a(t,e)}function c(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function l(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=u(t);if(e){var r=u(this).constructor;n=Reflect.construct(i,arguments,r)}else n=i.apply(this,arguments);return c(this,n)}}function f(){return f="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=u(t)););return t}(t,e);if(i){var r=Object.getOwnPropertyDescriptor(i,e);return r.get?r.get.call(arguments.length<3?t:n):r.value}},f.apply(this,arguments)}var d={type:"slider",startAt:0,perView:1,focusAt:0,gap:10,autoplay:!1,hoverpause:!0,keyboard:!0,bound:!1,swipeThreshold:80,dragThreshold:120,perSwipe:"",touchRatio:.5,touchAngle:45,animationDuration:400,rewind:!0,rewindDuration:800,animationTimingFunc:"cubic-bezier(.165, .840, .440, 1)",waitForTransition:!0,throttle:10,direction:"ltr",peek:0,cloningRatio:1,breakpoints:{},classes:{swipeable:"glide--swipeable",dragging:"glide--dragging",direction:{ltr:"glide--ltr",rtl:"glide--rtl"},type:{slider:"glide--slider",carousel:"glide--carousel"},slide:{clone:"glide__slide--clone",active:"glide__slide--active"},arrow:{disabled:"glide__arrow--disabled"},nav:{active:"glide__bullet--active"}}};function h(t){console.error("[Glide warn]: ".concat(t))}function v(t){return parseInt(t)}function p(t){return"string"==typeof t}function m(t){var e=n(t);return"function"===e||"object"===e&&!!t}function g(t){return"function"==typeof t}function y(t){return t.constructor===Array}function b(t,e,n){Object.defineProperty(t,e,n)}function w(t,n){var i=Object.assign({},t,n);if(n.hasOwnProperty("classes")){i.classes=Object.assign({},t.classes,n.classes);["direction","type","slide","arrow","nav"].forEach((function(r){n.classes.hasOwnProperty(r)&&(i.classes[r]=e(e({},t.classes[r]),n.classes[r]))}))}return n.hasOwnProperty("breakpoints")&&(i.breakpoints=Object.assign({},t.breakpoints,n.breakpoints)),i}var _=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,t),this.events=e,this.hop=e.hasOwnProperty}return o(t,[{key:"on",value:function(t,e){if(!y(t)){this.hop.call(this.events,t)||(this.events[t]=[]);var n=this.events[t].push(e)-1;return{remove:function(){delete this.events[t][n]}}}for(var i=0;i<t.length;i++)this.on(t[i],e)}},{key:"emit",value:function(t,e){if(y(t))for(var n=0;n<t.length;n++)this.emit(t[n],e);else this.hop.call(this.events,t)&&this.events[t].forEach((function(t){t(e||{})}))}}]),t}(),k=function(){function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};i(this,t),this._c={},this._t=[],this._e=new _,this.disabled=!1,this.selector=e,this.settings=w(d,n),this.index=this.settings.startAt}return o(t,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this._e.emit("mount.before"),m(t)?this._c=function(t,e,n){var i={};for(var r in e)g(e[r])?i[r]=e[r](t,i,n):h("Extension must be a function");for(var o in i)g(i[o].mount)&&i[o].mount();return i}(this,t,this._e):h("You need to provide a object on `mount()`"),this._e.emit("mount.after"),this}},{key:"mutate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return y(t)?this._t=t:h("You need to provide a array on `mutate()`"),this}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.settings=w(this.settings,t),t.hasOwnProperty("startAt")&&(this.index=t.startAt),this._e.emit("update"),this}},{key:"go",value:function(t){return this._c.Run.make(t),this}},{key:"move",value:function(t){return this._c.Transition.disable(),this._c.Move.make(t),this}},{key:"destroy",value:function(){return this._e.emit("destroy"),this}},{key:"play",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return t&&(this.settings.autoplay=t),this._e.emit("play"),this}},{key:"pause",value:function(){return this._e.emit("pause"),this}},{key:"disable",value:function(){return this.disabled=!0,this}},{key:"enable",value:function(){return this.disabled=!1,this}},{key:"on",value:function(t,e){return this._e.on(t,e),this}},{key:"isType",value:function(t){return this.settings.type===t}},{key:"settings",get:function(){return this._o},set:function(t){m(t)?this._o=t:h("Options must be an `object` instance.")}},{key:"index",get:function(){return this._i},set:function(t){this._i=v(t)}},{key:"type",get:function(){return this.settings.type}},{key:"disabled",get:function(){return this._d},set:function(t){this._d=!!t}}]),t}();function S(){return(new Date).getTime()}function O(t,e){var n,i,r,o,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},u=0,a=function(){u=!1===s.leading?0:S(),n=null,o=t.apply(i,r),n||(i=r=null)},c=function(){var c=S();u||!1!==s.leading||(u=c);var l=e-(c-u);return i=this,r=arguments,l<=0||l>e?(n&&(clearTimeout(n),n=null),u=c,o=t.apply(i,r),n||(i=r=null)):n||!1===s.trailing||(n=setTimeout(a,l)),o};return c.cancel=function(){clearTimeout(n),u=0,n=i=r=null},c}var T={ltr:["marginLeft","marginRight"],rtl:["marginRight","marginLeft"]};function x(t){if(t&&t.parentNode){for(var e=t.parentNode.firstChild,n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}return[]}function H(t){return Array.prototype.slice.call(t)}var j=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,t),this.listeners=e}return o(t,[{key:"on",value:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];p(t)&&(t=[t]);for(var r=0;r<t.length;r++)this.listeners[t[r]]=n,e.addEventListener(t[r],this.listeners[t[r]],i)}},{key:"off",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];p(t)&&(t=[t]);for(var i=0;i<t.length;i++)e.removeEventListener(t[i],this.listeners[t[i]],n)}},{key:"destroy",value:function(){delete this.listeners}}]),t}();var A=["ltr","rtl"],P={">":"<","<":">","=":"="};function R(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}function E(t,e){return{modify:function(t){var n=Math.floor(t/e.Sizes.slideWidth);return t+e.Gaps.value*n}}}function L(t,e){return{modify:function(t){return t+e.Clones.grow/2}}}function z(t,e){return{modify:function(n){if(t.settings.focusAt>=0){var i=e.Peek.value;return m(i)?n-i.before:n-i}return n}}}function C(t,e){return{modify:function(n){var i=e.Gaps.value,r=e.Sizes.width,o=t.settings.focusAt,s=e.Sizes.slideWidth;return"center"===o?n-(r/2-s/2):n-s*o-i*o}}}var M=!1;try{var D=Object.defineProperty({},"passive",{get:function(){M=!0}});window.addEventListener("testPassive",null,D),window.removeEventListener("testPassive",null,D)}catch(t){}var B=M,W=["touchstart","mousedown"],V=["touchmove","mousemove"],q=["touchend","touchcancel","mouseup","mouseleave"],G=["mousedown","mousemove","mouseup","mouseleave"];function F(t,e,n){var i=new j,r=0,o=0,s=0,u=!1,a=!!B&&{passive:!0},c={mount:function(){this.bindSwipeStart()},start:function(e){if(!u&&!t.disabled){this.disable();var i=this.touches(e);r=null,o=v(i.pageX),s=v(i.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),n.emit("swipe.start")}},move:function(i){if(!t.disabled){var u=t.settings,a=u.touchAngle,c=u.touchRatio,l=u.classes,f=this.touches(i),d=v(f.pageX)-o,h=v(f.pageY)-s,p=Math.abs(d<<2),m=Math.abs(h<<2),g=Math.sqrt(p+m),y=Math.sqrt(m);if(!(180*(r=Math.asin(y/g))/Math.PI<a))return!1;i.stopPropagation(),e.Move.make(d*parseFloat(c)),e.Html.root.classList.add(l.dragging),n.emit("swipe.move")}},end:function(i){if(!t.disabled){var s=t.settings,u=s.perSwipe,a=s.touchAngle,c=s.classes,l=this.touches(i),f=this.threshold(i),d=l.pageX-o,h=180*r/Math.PI;this.enable(),d>f&&h<a?e.Run.make(e.Direction.resolve("".concat(u,"<"))):d<-f&&h<a?e.Run.make(e.Direction.resolve("".concat(u,">"))):e.Move.make(),e.Html.root.classList.remove(c.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),n.emit("swipe.end")}},bindSwipeStart:function(){var n=this,r=t.settings,o=r.swipeThreshold,s=r.dragThreshold;o&&i.on(W[0],e.Html.wrapper,(function(t){n.start(t)}),a),s&&i.on(W[1],e.Html.wrapper,(function(t){n.start(t)}),a)},unbindSwipeStart:function(){i.off(W[0],e.Html.wrapper,a),i.off(W[1],e.Html.wrapper,a)},bindSwipeMove:function(){var n=this;i.on(V,e.Html.wrapper,O((function(t){n.move(t)}),t.settings.throttle),a)},unbindSwipeMove:function(){i.off(V,e.Html.wrapper,a)},bindSwipeEnd:function(){var t=this;i.on(q,e.Html.wrapper,(function(e){t.end(e)}))},unbindSwipeEnd:function(){i.off(q,e.Html.wrapper)},touches:function(t){return G.indexOf(t.type)>-1?t:t.touches[0]||t.changedTouches[0]},threshold:function(e){var n=t.settings;return G.indexOf(e.type)>-1?n.dragThreshold:n.swipeThreshold},enable:function(){return u=!1,e.Transition.enable(),this},disable:function(){return u=!0,e.Transition.disable(),this}};return n.on("build.after",(function(){e.Html.root.classList.add(t.settings.classes.swipeable)})),n.on("destroy",(function(){c.unbindSwipeStart(),c.unbindSwipeMove(),c.unbindSwipeEnd(),i.destroy()})),c}var I='[data-glide-el^="controls"]',N="".concat(I,' [data-glide-dir*="<"]'),Y="".concat(I,' [data-glide-dir*=">"]');function X(t,e,n){var i=new j,r=!!B&&{passive:!0},o={mount:function(){this._n=e.Html.root.querySelectorAll('[data-glide-el="controls[nav]"]'),this._c=e.Html.root.querySelectorAll(I),this._arrowControls={previous:e.Html.root.querySelectorAll(N),next:e.Html.root.querySelectorAll(Y)},this.addBindings()},setActive:function(){for(var t=0;t<this._n.length;t++)this.addClass(this._n[t].children)},removeActive:function(){for(var t=0;t<this._n.length;t++)this.removeClass(this._n[t].children)},addClass:function(e){var n=t.settings,i=e[t.index];i&&(i.classList.add(n.classes.nav.active),x(i).forEach((function(t){t.classList.remove(n.classes.nav.active)})))},removeClass:function(e){var n=e[t.index];null==n||n.classList.remove(t.settings.classes.nav.active)},setArrowState:function(){if(!t.settings.rewind){var n=o._arrowControls.next,i=o._arrowControls.previous;this.resetArrowState(n,i),0===t.index&&this.disableArrow(i),t.index===e.Run.length&&this.disableArrow(n)}},resetArrowState:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){H(t).forEach((function(t){t.classList.remove(e.classes.arrow.disabled)}))}))},disableArrow:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){H(t).forEach((function(t){t.classList.add(e.classes.arrow.disabled)}))}))},addBindings:function(){for(var t=0;t<this._c.length;t++)this.bind(this._c[t].children)},removeBindings:function(){for(var t=0;t<this._c.length;t++)this.unbind(this._c[t].children)},bind:function(t){for(var e=0;e<t.length;e++)i.on("click",t[e],this.click),i.on("touchstart",t[e],this.click,r)},unbind:function(t){for(var e=0;e<t.length;e++)i.off(["click","touchstart"],t[e])},click:function(t){B||"touchstart"!==t.type||t.preventDefault();var n=t.currentTarget.getAttribute("data-glide-dir");e.Run.make(e.Direction.resolve(n))}};return b(o,"items",{get:function(){return o._c}}),n.on(["mount.after","move.after"],(function(){o.setActive()})),n.on(["mount.after","run"],(function(){o.setArrowState()})),n.on("destroy",(function(){o.removeBindings(),o.removeActive(),i.destroy()})),o}function K(t,e,n){var i=new j,r={mount:function(){t.settings.keyboard&&this.bind()},bind:function(){i.on("keyup",document,this.press)},unbind:function(){i.off("keyup",document)},press:function(n){var i=t.settings.perSwipe;["ArrowRight","ArrowLeft"].includes(n.code)&&e.Run.make(e.Direction.resolve("".concat(i).concat({ArrowRight:">",ArrowLeft:"<"}[n.code])))}};return n.on(["destroy","update"],(function(){r.unbind()})),n.on("update",(function(){r.mount()})),n.on("destroy",(function(){i.destroy()})),r}function J(t){return m(t)?(e=t,Object.keys(e).sort().reduce((function(t,n){return t[n]=e[n],t[n],t}),{})):(h("Breakpoints option must be an object"),{});var e}function Q(t,e,n){var i=new j,r=t.settings,o=J(r.breakpoints),s=Object.assign({},r),u={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: ".concat(e,"px)")).matches)return t[e];return s}};return Object.assign(r,u.match(o)),i.on("resize",window,O((function(){t.settings=w(r,u.match(o))}),t.settings.throttle)),n.on("update",(function(){o=J(o),s=Object.assign({},r)})),n.on("destroy",(function(){i.off("resize",window)})),u}var U={Html:function(t,e,n){var i={mount:function(){this.root=t.selector,this.track=this.root.querySelector('[data-glide-el="track"]'),this.collectSlides()},collectSlides:function(){this.slides=H(this.wrapper.children).filter((function(e){return!e.classList.contains(t.settings.classes.slide.clone)}))}};return b(i,"root",{get:function(){return i._r},set:function(t){p(t)&&(t=document.querySelector(t)),null!==t?i._r=t:h("Root element must be a existing Html node")}}),b(i,"track",{get:function(){return i._t},set:function(t){i._t=t}}),b(i,"wrapper",{get:function(){return i.track.children[0]}}),n.on("update",(function(){i.collectSlides()})),i},Translate:function(t,e,n){var i={set:function(n){var i=function(t,e,n){var i=[E,L,z,C].concat(t._t,[R]);return{mutate:function(r){for(var o=0;o<i.length;o++){var s=i[o];g(s)&&g(s().modify)?r=s(t,e,n).modify(r):h("Transformer should be a function that returns an object with `modify()` method")}return r}}}(t,e).mutate(n),r="translate3d(".concat(-1*i,"px, 0px, 0px)");e.Html.wrapper.style.mozTransform=r,e.Html.wrapper.style.webkitTransform=r,e.Html.wrapper.style.transform=r},remove:function(){e.Html.wrapper.style.transform=""},getStartIndex:function(){var n=e.Sizes.length,i=t.index,r=t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?n+(i-r):(i+r)%n},getTravelDistance:function(){var n=e.Sizes.slideWidth*t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?-1*n:n}};return n.on("move",(function(r){if(!t.isType("carousel")||!e.Run.isOffset())return i.set(r.movement);e.Transition.after((function(){n.emit("translate.jump"),i.set(e.Sizes.slideWidth*t.index)}));var o=e.Sizes.slideWidth*e.Translate.getStartIndex();return i.set(o-e.Translate.getTravelDistance())})),n.on("destroy",(function(){i.remove()})),i},Transition:function(t,e,n){var i=!1,r={compose:function(e){var n=t.settings;return i?"".concat(e," 0ms ").concat(n.animationTimingFunc):"".concat(e," ").concat(this.duration,"ms ").concat(n.animationTimingFunc)},set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"transform";e.Html.wrapper.style.transition=this.compose(t)},remove:function(){e.Html.wrapper.style.transition=""},after:function(t){setTimeout((function(){t()}),this.duration)},enable:function(){i=!1,this.set()},disable:function(){i=!0,this.set()}};return b(r,"duration",{get:function(){var n=t.settings;return t.isType("slider")&&e.Run.offset?n.rewindDuration:n.animationDuration}}),n.on("move",(function(){r.set()})),n.on(["build.before","resize","translate.jump"],(function(){r.disable()})),n.on("run",(function(){r.enable()})),n.on("destroy",(function(){r.remove()})),r},Direction:function(t,e,n){var i={mount:function(){this.value=t.settings.direction},resolve:function(t){var e=t.slice(0,1);return this.is("rtl")?t.split(e).join(P[e]):t},is:function(t){return this.value===t},addClass:function(){e.Html.root.classList.add(t.settings.classes.direction[this.value])},removeClass:function(){e.Html.root.classList.remove(t.settings.classes.direction[this.value])}};return b(i,"value",{get:function(){return i._v},set:function(t){A.indexOf(t)>-1?i._v=t:h("Direction value must be `ltr` or `rtl`")}}),n.on(["destroy","update"],(function(){i.removeClass()})),n.on("update",(function(){i.mount()})),n.on(["build.before","update"],(function(){i.addClass()})),i},Peek:function(t,e,n){var i={mount:function(){this.value=t.settings.peek}};return b(i,"value",{get:function(){return i._v},set:function(t){m(t)?(t.before=v(t.before),t.after=v(t.after)):t=v(t),i._v=t}}),b(i,"reductor",{get:function(){var e=i.value,n=t.settings.perView;return m(e)?e.before/n+e.after/n:2*e/n}}),n.on(["resize","update"],(function(){i.mount()})),i},Sizes:function(t,e,n){var i={setupSlides:function(){for(var t="".concat(this.slideWidth,"px"),n=e.Html.slides,i=0;i<n.length;i++)n[i].style.width=t},setupWrapper:function(){e.Html.wrapper.style.width="".concat(this.wrapperSize,"px")},remove:function(){for(var t=e.Html.slides,n=0;n<t.length;n++)t[n].style.width="";e.Html.wrapper.style.width=""}};return b(i,"length",{get:function(){return e.Html.slides.length}}),b(i,"width",{get:function(){return e.Html.track.offsetWidth}}),b(i,"wrapperSize",{get:function(){return i.slideWidth*i.length+e.Gaps.grow+e.Clones.grow}}),b(i,"slideWidth",{get:function(){return i.width/t.settings.perView-e.Peek.reductor-e.Gaps.reductor}}),n.on(["build.before","resize","update"],(function(){i.setupSlides(),i.setupWrapper()})),n.on("destroy",(function(){i.remove()})),i},Gaps:function(t,e,n){var i={apply:function(t){for(var n=0,i=t.length;n<i;n++){var r=t[n].style,o=e.Direction.value;r[T[o][0]]=0!==n?"".concat(this.value/2,"px"):"",n!==t.length-1?r[T[o][1]]="".concat(this.value/2,"px"):r[T[o][1]]=""}},remove:function(t){for(var e=0,n=t.length;e<n;e++){var i=t[e].style;i.marginLeft="",i.marginRight=""}}};return b(i,"value",{get:function(){return v(t.settings.gap)}}),b(i,"grow",{get:function(){return i.value*e.Sizes.length}}),b(i,"reductor",{get:function(){var e=t.settings.perView;return i.value*(e-1)/e}}),n.on(["build.after","update"],O((function(){i.apply(e.Html.wrapper.children)}),30)),n.on("destroy",(function(){i.remove(e.Html.wrapper.children)})),i},Move:function(t,e,n){var i={mount:function(){this._o=0},make:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.offset=i,n.emit("move",{movement:this.value}),e.Transition.after((function(){n.emit("move.after",{movement:t.value})}))}};return b(i,"offset",{get:function(){return i._o},set:function(t){i._o=function(t){return void 0===t}(t)?0:v(t)}}),b(i,"translate",{get:function(){return e.Sizes.slideWidth*t.index}}),b(i,"value",{get:function(){var t=this.offset,n=this.translate;return e.Direction.is("rtl")?n+t:n-t}}),n.on(["build.before","run"],(function(){i.make()})),i},Clones:function(t,e,n){var i={mount:function(){this.items=[],t.isType("carousel")&&(this.items=this.collect())},collect:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=e.Html.slides,r=t.settings,o=r.perView,s=r.classes,u=r.cloningRatio;if(i.length>0)for(var a=o+ +!!t.settings.peek+Math.round(o/2),c=i.slice(0,a).reverse(),l=i.slice(-1*a),f=0;f<Math.max(u,Math.floor(o/i.length));f++){for(var d=0;d<c.length;d++){var h=c[d].cloneNode(!0);h.classList.add(s.slide.clone),n.push(h)}for(var v=0;v<l.length;v++){var p=l[v].cloneNode(!0);p.classList.add(s.slide.clone),n.unshift(p)}}return n},append:function(){for(var t=this.items,n=e.Html,i=n.wrapper,r=n.slides,o=Math.floor(t.length/2),s=t.slice(0,o).reverse(),u=t.slice(-1*o).reverse(),a="".concat(e.Sizes.slideWidth,"px"),c=0;c<u.length;c++)i.appendChild(u[c]);for(var l=0;l<s.length;l++)i.insertBefore(s[l],r[0]);for(var f=0;f<t.length;f++)t[f].style.width=a},remove:function(){for(var t=this.items,n=0;n<t.length;n++)e.Html.wrapper.removeChild(t[n])}};return b(i,"grow",{get:function(){return(e.Sizes.slideWidth+e.Gaps.value)*i.items.length}}),n.on("update",(function(){i.remove(),i.mount(),i.append()})),n.on("build.before",(function(){t.isType("carousel")&&i.append()})),n.on("destroy",(function(){i.remove()})),i},Resize:function(t,e,n){var i=new j,r={mount:function(){this.bind()},bind:function(){i.on("resize",window,O((function(){n.emit("resize")}),t.settings.throttle))},unbind:function(){i.off("resize",window)}};return n.on("destroy",(function(){r.unbind(),i.destroy()})),r},Build:function(t,e,n){var i={mount:function(){n.emit("build.before"),this.typeClass(),this.activeClass(),n.emit("build.after")},typeClass:function(){e.Html.root.classList.add(t.settings.classes.type[t.settings.type])},activeClass:function(){var n=t.settings.classes,i=e.Html.slides[t.index];i&&(i.classList.add(n.slide.active),x(i).forEach((function(t){t.classList.remove(n.slide.active)})))},removeClasses:function(){var n=t.settings.classes,i=n.type,r=n.slide;e.Html.root.classList.remove(i[t.settings.type]),e.Html.slides.forEach((function(t){t.classList.remove(r.active)}))}};return n.on(["destroy","update"],(function(){i.removeClasses()})),n.on(["resize","update"],(function(){i.mount()})),n.on("move.after",(function(){i.activeClass()})),i},Run:function(t,e,n){var i={mount:function(){this._o=!1},make:function(i){var r=this;t.disabled||(!t.settings.waitForTransition||t.disable(),this.move=i,n.emit("run.before",this.move),this.calculate(),n.emit("run",this.move),e.Transition.after((function(){r.isStart()&&n.emit("run.start",r.move),r.isEnd()&&n.emit("run.end",r.move),r.isOffset()&&(r._o=!1,n.emit("run.offset",r.move)),n.emit("run.after",r.move),t.enable()})))},calculate:function(){var e=this.move,n=this.length,r=e.steps,o=e.direction,s=1;if("="===o)return t.settings.bound&&v(r)>n?void(t.index=n):void(t.index=r);if(">"!==o||">"!==r)if("<"!==o||"<"!==r){if("|"===o&&(s=t.settings.perView||1),">"===o||"|"===o&&">"===r){var u=function(e){var n=t.index;if(t.isType("carousel"))return n+e;return n+(e-n%e)}(s);return u>n&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e<=r)return e;if(t.isType("carousel"))return e-(r+1);if(t.settings.rewind)return i.isBound()&&!i.isEnd()?r:0;if(i.isBound())return r;return Math.floor(r/n)*n}(u,s))}if("<"===o||"|"===o&&"<"===r){var a=function(e){var n=t.index;if(t.isType("carousel"))return n-e;var i=Math.ceil(n/e);return(i-1)*e}(s);return a<0&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e>=0)return e;if(t.isType("carousel"))return e+(r+1);if(t.settings.rewind)return i.isBound()&&i.isStart()?r:Math.floor(r/n)*n;return 0}(a,s))}h("Invalid direction pattern [".concat(o).concat(r,"] has been used"))}else t.index=0;else t.index=n},isStart:function(){return t.index<=0},isEnd:function(){return t.index>=this.length},isOffset:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return t?!!this._o&&("|>"===t?"|"===this.move.direction&&">"===this.move.steps:"|<"===t?"|"===this.move.direction&&"<"===this.move.steps:this.move.direction===t):this._o},isBound:function(){return t.isType("slider")&&"center"!==t.settings.focusAt&&t.settings.bound}};return b(i,"move",{get:function(){return this._m},set:function(t){var e=t.substr(1);this._m={direction:t.substr(0,1),steps:e?v(e)?v(e):e:0}}}),b(i,"length",{get:function(){var n=t.settings,i=e.Html.slides.length;return this.isBound()?i-1-(v(n.perView)-1)+v(n.focusAt):i-1}}),b(i,"offset",{get:function(){return this._o}}),i}},Z=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&a(t,e)}(n,t);var e=l(n);function n(){return i(this,n),e.apply(this,arguments)}return o(n,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return f(u(n.prototype),"mount",this).call(this,Object.assign({},U,t))}}]),n}(k);Drupal.behaviors.iopGlide={attach(){document.querySelectorAll(".glide").forEach((t=>{new Z(t,{type:"carousel",focusAt:"center",gap:56,perView:3,breakpoints:{1399:{gap:50},1199:{gap:44},991:{gap:36},767:{gap:16,perView:1}}}).mount({Breakpoints:Q,Controls:X,Keyboard:K,Swipe:F})}))}}})); + */function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function r(t){return r=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},r(t)}function o(t,e){return o=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},o(t,e)}function s(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function a(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=r(t);if(e){var o=r(this).constructor;n=Reflect.construct(i,arguments,o)}else n=i.apply(this,arguments);return s(this,n)}}function u(){return u="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=r(t)););return t}(t,e);if(i){var o=Object.getOwnPropertyDescriptor(i,e);return o.get?o.get.call(arguments.length<3?t:n):o.value}},u.apply(this,arguments)}var c={type:"slider",startAt:0,perView:1,focusAt:0,gap:10,autoplay:!1,hoverpause:!0,keyboard:!0,bound:!1,swipeThreshold:80,dragThreshold:120,perSwipe:"",touchRatio:.5,touchAngle:45,animationDuration:400,rewind:!0,rewindDuration:800,animationTimingFunc:"cubic-bezier(.165, .840, .440, 1)",waitForTransition:!0,throttle:10,direction:"ltr",peek:0,cloningRatio:1,breakpoints:{},classes:{swipeable:"glide--swipeable",dragging:"glide--dragging",direction:{ltr:"glide--ltr",rtl:"glide--rtl"},type:{slider:"glide--slider",carousel:"glide--carousel"},slide:{clone:"glide__slide--clone",active:"glide__slide--active"},arrow:{disabled:"glide__arrow--disabled"},nav:{active:"glide__bullet--active"}}};function l(t){console.error("[Glide warn]: ".concat(t))}function f(t){return parseInt(t)}function d(t){return"string"==typeof t}function h(e){var n=t(e);return"function"===n||"object"===n&&!!e}function v(t){return"function"==typeof t}function p(t){return t.constructor===Array}function m(t,e,n){Object.defineProperty(t,e,n)}function g(t,e){var n=Object.assign({},t,e);return e.hasOwnProperty("classes")&&(n.classes=Object.assign({},t.classes,e.classes),e.classes.hasOwnProperty("direction")&&(n.classes.direction=Object.assign({},t.classes.direction,e.classes.direction)),e.classes.hasOwnProperty("type")&&(n.classes.type=Object.assign({},t.classes.type,e.classes.type)),e.classes.hasOwnProperty("slide")&&(n.classes.slide=Object.assign({},t.classes.slide,e.classes.slide)),e.classes.hasOwnProperty("arrow")&&(n.classes.arrow=Object.assign({},t.classes.arrow,e.classes.arrow)),e.classes.hasOwnProperty("nav")&&(n.classes.nav=Object.assign({},t.classes.nav,e.classes.nav))),e.hasOwnProperty("breakpoints")&&(n.breakpoints=Object.assign({},t.breakpoints,e.breakpoints)),n}var y=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.events=n,this.hop=n.hasOwnProperty}return i(t,[{key:"on",value:function(t,e){if(!p(t)){this.hop.call(this.events,t)||(this.events[t]=[]);var n=this.events[t].push(e)-1;return{remove:function(){delete this.events[t][n]}}}for(var i=0;i<t.length;i++)this.on(t[i],e)}},{key:"emit",value:function(t,e){if(p(t))for(var n=0;n<t.length;n++)this.emit(t[n],e);else this.hop.call(this.events,t)&&this.events[t].forEach((function(t){t(e||{})}))}}]),t}(),w=function(){function t(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,t),this._c={},this._t=[],this._e=new y,this.disabled=!1,this.selector=n,this.settings=g(c,i),this.index=this.settings.startAt}return i(t,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this._e.emit("mount.before"),h(t)?this._c=function(t,e,n){var i={};for(var r in e)v(e[r])?i[r]=e[r](t,i,n):l("Extension must be a function");for(var o in i)v(i[o].mount)&&i[o].mount();return i}(this,t,this._e):l("You need to provide a object on `mount()`"),this._e.emit("mount.after"),this}},{key:"mutate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return p(t)?this._t=t:l("You need to provide a array on `mutate()`"),this}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.settings=g(this.settings,t),t.hasOwnProperty("startAt")&&(this.index=t.startAt),this._e.emit("update"),this}},{key:"go",value:function(t){return this._c.Run.make(t),this}},{key:"move",value:function(t){return this._c.Transition.disable(),this._c.Move.make(t),this}},{key:"destroy",value:function(){return this._e.emit("destroy"),this}},{key:"play",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return t&&(this.settings.autoplay=t),this._e.emit("play"),this}},{key:"pause",value:function(){return this._e.emit("pause"),this}},{key:"disable",value:function(){return this.disabled=!0,this}},{key:"enable",value:function(){return this.disabled=!1,this}},{key:"on",value:function(t,e){return this._e.on(t,e),this}},{key:"isType",value:function(t){return this.settings.type===t}},{key:"settings",get:function(){return this._o},set:function(t){h(t)?this._o=t:l("Options must be an `object` instance.")}},{key:"index",get:function(){return this._i},set:function(t){this._i=f(t)}},{key:"type",get:function(){return this.settings.type}},{key:"disabled",get:function(){return this._d},set:function(t){this._d=!!t}}]),t}();function b(){return(new Date).getTime()}function _(t,e,n){var i,r,o,s,a=0;n||(n={});var u=function(){a=!1===n.leading?0:b(),i=null,s=t.apply(r,o),i||(r=o=null)},c=function(){var c=b();a||!1!==n.leading||(a=c);var l=e-(c-a);return r=this,o=arguments,l<=0||l>e?(i&&(clearTimeout(i),i=null),a=c,s=t.apply(r,o),i||(r=o=null)):i||!1===n.trailing||(i=setTimeout(u,l)),s};return c.cancel=function(){clearTimeout(i),a=0,i=r=o=null},c}var k={ltr:["marginLeft","marginRight"],rtl:["marginRight","marginLeft"]};function S(t){if(t&&t.parentNode){for(var e=t.parentNode.firstChild,n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}return[]}function O(t){return!!(t&&t instanceof window.HTMLElement)}function T(t){return Array.prototype.slice.call(t)}var x='[data-glide-el="track"]';var H=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.listeners=n}return i(t,[{key:"on",value:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];d(t)&&(t=[t]);for(var r=0;r<t.length;r++)this.listeners[t[r]]=n,e.addEventListener(t[r],this.listeners[t[r]],i)}},{key:"off",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];d(t)&&(t=[t]);for(var i=0;i<t.length;i++)e.removeEventListener(t[i],this.listeners[t[i]],n)}},{key:"destroy",value:function(){delete this.listeners}}]),t}();var A=["ltr","rtl"],j={">":"<","<":">","=":"="};function R(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}function P(t,e){return{modify:function(t){var n=Math.floor(t/e.Sizes.slideWidth);return t+e.Gaps.value*n}}}function C(t,e){return{modify:function(t){return t+e.Clones.grow/2}}}function E(t,e){return{modify:function(n){if(t.settings.focusAt>=0){var i=e.Peek.value;return h(i)?n-i.before:n-i}return n}}}function L(t,e){return{modify:function(n){var i=e.Gaps.value,r=e.Sizes.width,o=t.settings.focusAt,s=e.Sizes.slideWidth;return"center"===o?n-(r/2-s/2):n-s*o-i*o}}}var M=!1;try{var z=Object.defineProperty({},"passive",{get:function(){M=!0}});window.addEventListener("testPassive",null,z),window.removeEventListener("testPassive",null,z)}catch(t){}var D=M,B=["touchstart","mousedown"],W=["touchmove","mousemove"],V=["touchend","touchcancel","mouseup","mouseleave"],q=["mousedown","mousemove","mouseup","mouseleave"];function G(t,e,n){var i=new H,r=0,o=0,s=0,a=!1,u=!!D&&{passive:!0},c={mount:function(){this.bindSwipeStart()},start:function(e){if(!a&&!t.disabled){this.disable();var i=this.touches(e);r=null,o=f(i.pageX),s=f(i.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),n.emit("swipe.start")}},move:function(i){if(!t.disabled){var a=t.settings,u=a.touchAngle,c=a.touchRatio,l=a.classes,d=this.touches(i),h=f(d.pageX)-o,v=f(d.pageY)-s,p=Math.abs(h<<2),m=Math.abs(v<<2),g=Math.sqrt(p+m),y=Math.sqrt(m);if(!(180*(r=Math.asin(y/g))/Math.PI<u))return!1;i.stopPropagation(),e.Move.make(h*parseFloat(c)),e.Html.root.classList.add(l.dragging),n.emit("swipe.move")}},end:function(i){if(!t.disabled){var s=t.settings,a=s.perSwipe,u=s.touchAngle,c=s.classes,l=this.touches(i),f=this.threshold(i),d=l.pageX-o,h=180*r/Math.PI;this.enable(),d>f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,"<"))):d<-f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,">"))):e.Move.make(),e.Html.root.classList.remove(c.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),n.emit("swipe.end")}},bindSwipeStart:function(){var n=this,r=t.settings,o=r.swipeThreshold,s=r.dragThreshold;o&&i.on(B[0],e.Html.wrapper,(function(t){n.start(t)}),u),s&&i.on(B[1],e.Html.wrapper,(function(t){n.start(t)}),u)},unbindSwipeStart:function(){i.off(B[0],e.Html.wrapper,u),i.off(B[1],e.Html.wrapper,u)},bindSwipeMove:function(){var n=this;i.on(W,e.Html.wrapper,_((function(t){n.move(t)}),t.settings.throttle),u)},unbindSwipeMove:function(){i.off(W,e.Html.wrapper,u)},bindSwipeEnd:function(){var t=this;i.on(V,e.Html.wrapper,(function(e){t.end(e)}))},unbindSwipeEnd:function(){i.off(V,e.Html.wrapper)},touches:function(t){return q.indexOf(t.type)>-1?t:t.touches[0]||t.changedTouches[0]},threshold:function(e){var n=t.settings;return q.indexOf(e.type)>-1?n.dragThreshold:n.swipeThreshold},enable:function(){return a=!1,e.Transition.enable(),this},disable:function(){return a=!0,e.Transition.disable(),this}};return n.on("build.after",(function(){e.Html.root.classList.add(t.settings.classes.swipeable)})),n.on("destroy",(function(){c.unbindSwipeStart(),c.unbindSwipeMove(),c.unbindSwipeEnd(),i.destroy()})),c}var F='[data-glide-el^="controls"]',I="".concat(F,' [data-glide-dir*="<"]'),N="".concat(F,' [data-glide-dir*=">"]');function Y(t,e,n){var i=new H,r=!!D&&{passive:!0},o={mount:function(){this._n=e.Html.root.querySelectorAll('[data-glide-el="controls[nav]"]'),this._c=e.Html.root.querySelectorAll(F),this._arrowControls={previous:e.Html.root.querySelectorAll(I),next:e.Html.root.querySelectorAll(N)},this.addBindings()},setActive:function(){for(var t=0;t<this._n.length;t++)this.addClass(this._n[t].children)},removeActive:function(){for(var t=0;t<this._n.length;t++)this.removeClass(this._n[t].children)},addClass:function(e){var n=t.settings,i=e[t.index];i&&i&&(i.classList.add(n.classes.nav.active),S(i).forEach((function(t){t.classList.remove(n.classes.nav.active)})))},removeClass:function(e){var n=e[t.index];n&&n.classList.remove(t.settings.classes.nav.active)},setArrowState:function(){if(!t.settings.rewind){var n=o._arrowControls.next,i=o._arrowControls.previous;this.resetArrowState(n,i),0===t.index&&this.disableArrow(i),t.index===e.Run.length&&this.disableArrow(n)}},resetArrowState:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){T(t).forEach((function(t){t.classList.remove(e.classes.arrow.disabled)}))}))},disableArrow:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){T(t).forEach((function(t){t.classList.add(e.classes.arrow.disabled)}))}))},addBindings:function(){for(var t=0;t<this._c.length;t++)this.bind(this._c[t].children)},removeBindings:function(){for(var t=0;t<this._c.length;t++)this.unbind(this._c[t].children)},bind:function(t){for(var e=0;e<t.length;e++)i.on("click",t[e],this.click),i.on("touchstart",t[e],this.click,r)},unbind:function(t){for(var e=0;e<t.length;e++)i.off(["click","touchstart"],t[e])},click:function(t){D||"touchstart"!==t.type||t.preventDefault();var n=t.currentTarget.getAttribute("data-glide-dir");e.Run.make(e.Direction.resolve(n))}};return m(o,"items",{get:function(){return o._c}}),n.on(["mount.after","move.after"],(function(){o.setActive()})),n.on(["mount.after","run"],(function(){o.setArrowState()})),n.on("destroy",(function(){o.removeBindings(),o.removeActive(),i.destroy()})),o}function X(t,e,n){var i=new H,r={mount:function(){t.settings.keyboard&&this.bind()},bind:function(){i.on("keyup",document,this.press)},unbind:function(){i.off("keyup",document)},press:function(n){var i=t.settings.perSwipe;"ArrowRight"===n.code&&e.Run.make(e.Direction.resolve("".concat(i,">"))),"ArrowLeft"===n.code&&e.Run.make(e.Direction.resolve("".concat(i,"<")))}};return n.on(["destroy","update"],(function(){r.unbind()})),n.on("update",(function(){r.mount()})),n.on("destroy",(function(){i.destroy()})),r}function K(t){return h(t)?(e=t,Object.keys(e).sort().reduce((function(t,n){return t[n]=e[n],t[n],t}),{})):(l("Breakpoints option must be an object"),{});var e}function J(t,e,n){var i=new H,r=t.settings,o=K(r.breakpoints),s=Object.assign({},r),a={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: ".concat(e,"px)")).matches)return t[e];return s}};return Object.assign(r,a.match(o)),i.on("resize",window,_((function(){t.settings=g(r,a.match(o))}),t.settings.throttle)),n.on("update",(function(){o=K(o),s=Object.assign({},r)})),n.on("destroy",(function(){i.off("resize",window)})),a}var Q={Html:function(t,e,n){var i={mount:function(){this.root=t.selector,this.track=this.root.querySelector(x),this.collectSlides()},collectSlides:function(){this.slides=T(this.wrapper.children).filter((function(e){return!e.classList.contains(t.settings.classes.slide.clone)}))}};return m(i,"root",{get:function(){return i._r},set:function(t){d(t)&&(t=document.querySelector(t)),O(t)?i._r=t:l("Root element must be a existing Html node")}}),m(i,"track",{get:function(){return i._t},set:function(t){O(t)?i._t=t:l("Could not find track element. Please use ".concat(x," attribute."))}}),m(i,"wrapper",{get:function(){return i.track.children[0]}}),n.on("update",(function(){i.collectSlides()})),i},Translate:function(t,e,n){var i={set:function(n){var i=function(t,e,n){var i=[P,C,E,L].concat(t._t,[R]);return{mutate:function(r){for(var o=0;o<i.length;o++){var s=i[o];v(s)&&v(s().modify)?r=s(t,e,n).modify(r):l("Transformer should be a function that returns an object with `modify()` method")}return r}}}(t,e).mutate(n),r="translate3d(".concat(-1*i,"px, 0px, 0px)");e.Html.wrapper.style.mozTransform=r,e.Html.wrapper.style.webkitTransform=r,e.Html.wrapper.style.transform=r},remove:function(){e.Html.wrapper.style.transform=""},getStartIndex:function(){var n=e.Sizes.length,i=t.index,r=t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?n+(i-r):(i+r)%n},getTravelDistance:function(){var n=e.Sizes.slideWidth*t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?-1*n:n}};return n.on("move",(function(r){if(!t.isType("carousel")||!e.Run.isOffset())return i.set(r.movement);e.Transition.after((function(){n.emit("translate.jump"),i.set(e.Sizes.slideWidth*t.index)}));var o=e.Sizes.slideWidth*e.Translate.getStartIndex();return i.set(o-e.Translate.getTravelDistance())})),n.on("destroy",(function(){i.remove()})),i},Transition:function(t,e,n){var i=!1,r={compose:function(e){var n=t.settings;return i?"".concat(e," 0ms ").concat(n.animationTimingFunc):"".concat(e," ").concat(this.duration,"ms ").concat(n.animationTimingFunc)},set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"transform";e.Html.wrapper.style.transition=this.compose(t)},remove:function(){e.Html.wrapper.style.transition=""},after:function(t){setTimeout((function(){t()}),this.duration)},enable:function(){i=!1,this.set()},disable:function(){i=!0,this.set()}};return m(r,"duration",{get:function(){var n=t.settings;return t.isType("slider")&&e.Run.offset?n.rewindDuration:n.animationDuration}}),n.on("move",(function(){r.set()})),n.on(["build.before","resize","translate.jump"],(function(){r.disable()})),n.on("run",(function(){r.enable()})),n.on("destroy",(function(){r.remove()})),r},Direction:function(t,e,n){var i={mount:function(){this.value=t.settings.direction},resolve:function(t){var e=t.slice(0,1);return this.is("rtl")?t.split(e).join(j[e]):t},is:function(t){return this.value===t},addClass:function(){e.Html.root.classList.add(t.settings.classes.direction[this.value])},removeClass:function(){e.Html.root.classList.remove(t.settings.classes.direction[this.value])}};return m(i,"value",{get:function(){return i._v},set:function(t){A.indexOf(t)>-1?i._v=t:l("Direction value must be `ltr` or `rtl`")}}),n.on(["destroy","update"],(function(){i.removeClass()})),n.on("update",(function(){i.mount()})),n.on(["build.before","update"],(function(){i.addClass()})),i},Peek:function(t,e,n){var i={mount:function(){this.value=t.settings.peek}};return m(i,"value",{get:function(){return i._v},set:function(t){h(t)?(t.before=f(t.before),t.after=f(t.after)):t=f(t),i._v=t}}),m(i,"reductor",{get:function(){var e=i.value,n=t.settings.perView;return h(e)?e.before/n+e.after/n:2*e/n}}),n.on(["resize","update"],(function(){i.mount()})),i},Sizes:function(t,e,n){var i={setupSlides:function(){for(var t="".concat(this.slideWidth,"px"),n=e.Html.slides,i=0;i<n.length;i++)n[i].style.width=t},setupWrapper:function(){e.Html.wrapper.style.width="".concat(this.wrapperSize,"px")},remove:function(){for(var t=e.Html.slides,n=0;n<t.length;n++)t[n].style.width="";e.Html.wrapper.style.width=""}};return m(i,"length",{get:function(){return e.Html.slides.length}}),m(i,"width",{get:function(){return e.Html.track.offsetWidth}}),m(i,"wrapperSize",{get:function(){return i.slideWidth*i.length+e.Gaps.grow+e.Clones.grow}}),m(i,"slideWidth",{get:function(){return i.width/t.settings.perView-e.Peek.reductor-e.Gaps.reductor}}),n.on(["build.before","resize","update"],(function(){i.setupSlides(),i.setupWrapper()})),n.on("destroy",(function(){i.remove()})),i},Gaps:function(t,e,n){var i={apply:function(t){for(var n=0,i=t.length;n<i;n++){var r=t[n].style,o=e.Direction.value;r[k[o][0]]=0!==n?"".concat(this.value/2,"px"):"",n!==t.length-1?r[k[o][1]]="".concat(this.value/2,"px"):r[k[o][1]]=""}},remove:function(t){for(var e=0,n=t.length;e<n;e++){var i=t[e].style;i.marginLeft="",i.marginRight=""}}};return m(i,"value",{get:function(){return f(t.settings.gap)}}),m(i,"grow",{get:function(){return i.value*e.Sizes.length}}),m(i,"reductor",{get:function(){var e=t.settings.perView;return i.value*(e-1)/e}}),n.on(["build.after","update"],_((function(){i.apply(e.Html.wrapper.children)}),30)),n.on("destroy",(function(){i.remove(e.Html.wrapper.children)})),i},Move:function(t,e,n){var i={mount:function(){this._o=0},make:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.offset=i,n.emit("move",{movement:this.value}),e.Transition.after((function(){n.emit("move.after",{movement:t.value})}))}};return m(i,"offset",{get:function(){return i._o},set:function(t){i._o=function(t){return void 0===t}(t)?0:f(t)}}),m(i,"translate",{get:function(){return e.Sizes.slideWidth*t.index}}),m(i,"value",{get:function(){var t=this.offset,n=this.translate;return e.Direction.is("rtl")?n+t:n-t}}),n.on(["build.before","run"],(function(){i.make()})),i},Clones:function(t,e,n){var i={mount:function(){this.items=[],t.isType("carousel")&&(this.items=this.collect())},collect:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=e.Html.slides,r=t.settings,o=r.perView,s=r.classes,a=r.cloningRatio;if(0!==i.length)for(var u=o+ +!!t.settings.peek+Math.round(o/2),c=i.slice(0,u).reverse(),l=i.slice(-1*u),f=0;f<Math.max(a,Math.floor(o/i.length));f++){for(var d=0;d<c.length;d++){var h=c[d].cloneNode(!0);h.classList.add(s.slide.clone),n.push(h)}for(var v=0;v<l.length;v++){var p=l[v].cloneNode(!0);p.classList.add(s.slide.clone),n.unshift(p)}}return n},append:function(){for(var t=this.items,n=e.Html,i=n.wrapper,r=n.slides,o=Math.floor(t.length/2),s=t.slice(0,o).reverse(),a=t.slice(-1*o).reverse(),u="".concat(e.Sizes.slideWidth,"px"),c=0;c<a.length;c++)i.appendChild(a[c]);for(var l=0;l<s.length;l++)i.insertBefore(s[l],r[0]);for(var f=0;f<t.length;f++)t[f].style.width=u},remove:function(){for(var t=this.items,n=0;n<t.length;n++)e.Html.wrapper.removeChild(t[n])}};return m(i,"grow",{get:function(){return(e.Sizes.slideWidth+e.Gaps.value)*i.items.length}}),n.on("update",(function(){i.remove(),i.mount(),i.append()})),n.on("build.before",(function(){t.isType("carousel")&&i.append()})),n.on("destroy",(function(){i.remove()})),i},Resize:function(t,e,n){var i=new H,r={mount:function(){this.bind()},bind:function(){i.on("resize",window,_((function(){n.emit("resize")}),t.settings.throttle))},unbind:function(){i.off("resize",window)}};return n.on("destroy",(function(){r.unbind(),i.destroy()})),r},Build:function(t,e,n){var i={mount:function(){n.emit("build.before"),this.typeClass(),this.activeClass(),n.emit("build.after")},typeClass:function(){e.Html.root.classList.add(t.settings.classes.type[t.settings.type])},activeClass:function(){var n=t.settings.classes,i=e.Html.slides[t.index];i&&(i.classList.add(n.slide.active),S(i).forEach((function(t){t.classList.remove(n.slide.active)})))},removeClasses:function(){var n=t.settings.classes,i=n.type,r=n.slide;e.Html.root.classList.remove(i[t.settings.type]),e.Html.slides.forEach((function(t){t.classList.remove(r.active)}))}};return n.on(["destroy","update"],(function(){i.removeClasses()})),n.on(["resize","update"],(function(){i.mount()})),n.on("move.after",(function(){i.activeClass()})),i},Run:function(t,e,n){var i={mount:function(){this._o=!1},make:function(i){var r=this;t.disabled||(!t.settings.waitForTransition||t.disable(),this.move=i,n.emit("run.before",this.move),this.calculate(),n.emit("run",this.move),e.Transition.after((function(){r.isStart()&&n.emit("run.start",r.move),r.isEnd()&&n.emit("run.end",r.move),r.isOffset()&&(r._o=!1,n.emit("run.offset",r.move)),n.emit("run.after",r.move),t.enable()})))},calculate:function(){var e=this.move,n=this.length,r=e.steps,o=e.direction,s=1;if("="===o)return t.settings.bound&&f(r)>n?void(t.index=n):void(t.index=r);if(">"!==o||">"!==r)if("<"!==o||"<"!==r){if("|"===o&&(s=t.settings.perView||1),">"===o||"|"===o&&">"===r){var a=function(e){var n=t.index;if(t.isType("carousel"))return n+e;return n+(e-n%e)}(s);return a>n&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e<=r)return e;if(t.isType("carousel"))return e-(r+1);if(t.settings.rewind)return i.isBound()&&!i.isEnd()?r:0;if(i.isBound())return r;return Math.floor(r/n)*n}(a,s))}if("<"===o||"|"===o&&"<"===r){var u=function(e){var n=t.index;if(t.isType("carousel"))return n-e;var i=Math.ceil(n/e);return(i-1)*e}(s);return u<0&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e>=0)return e;if(t.isType("carousel"))return e+(r+1);if(t.settings.rewind)return i.isBound()&&i.isStart()?r:Math.floor(r/n)*n;return 0}(u,s))}l("Invalid direction pattern [".concat(o).concat(r,"] has been used"))}else t.index=0;else t.index=n},isStart:function(){return t.index<=0},isEnd:function(){return t.index>=this.length},isOffset:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return t?!!this._o&&("|>"===t?"|"===this.move.direction&&">"===this.move.steps:"|<"===t?"|"===this.move.direction&&"<"===this.move.steps:this.move.direction===t):this._o},isBound:function(){return t.isType("slider")&&"center"!==t.settings.focusAt&&t.settings.bound}};return m(i,"move",{get:function(){return this._m},set:function(t){var e=t.substr(1);this._m={direction:t.substr(0,1),steps:e?f(e)?f(e):e:0}}}),m(i,"length",{get:function(){var n=t.settings,i=e.Html.slides.length;return this.isBound()?i-1-(f(n.perView)-1)+f(n.focusAt):i-1}}),m(i,"offset",{get:function(){return this._o}}),i}},U=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&o(t,e)}(s,t);var n=a(s);function s(){return e(this,s),n.apply(this,arguments)}return i(s,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return u(r(s.prototype),"mount",this).call(this,Object.assign({},Q,t))}}]),s}(w);Drupal.behaviors.iopGlide={attach(){document.querySelectorAll(".glide").forEach((t=>{new U(t,{type:"carousel",focusAt:"center",gap:56,perView:3,breakpoints:{1399:{gap:50},1199:{gap:44},991:{gap:36},767:{gap:16,perView:1}}}).mount({Breakpoints:J,Controls:Y,Keyboard:X,Swipe:G})}))}}})); //# sourceMappingURL=glide.min.js.map diff --git a/web/themes/ventuno/assets/js/carousel.min.js b/web/themes/ventuno/assets/js/carousel.min.js index 9e0ab6bfee..b9aaf7cf3d 100644 --- a/web/themes/ventuno/assets/js/carousel.min.js +++ b/web/themes/ventuno/assets/js/carousel.min.js @@ -1,7 +1,7 @@ !function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict"; /*! - * Glide.js v3.6.2 - * (c) 2013-2024 Jędrzej Chałubek (https://github.com/jedrzejchalubek/) + * Glide.js v3.6.0 + * (c) 2013-2022 Jędrzej Chałubek (https://github.com/jedrzejchalubek/) * Released under the MIT License. - */function t(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function e(e){for(var n=1;n<arguments.length;n++){var i=null!=arguments[n]?arguments[n]:{};n%2?t(Object(i),!0).forEach((function(t){s(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):t(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&r(t.prototype,e),n&&r(t,n),t}function s(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(t){return a=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},a(t)}function u(t,e){return u=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},u(t,e)}function c(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function l(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=a(t);if(e){var r=a(this).constructor;n=Reflect.construct(i,arguments,r)}else n=i.apply(this,arguments);return c(this,n)}}function f(){return f="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=a(t)););return t}(t,e);if(i){var r=Object.getOwnPropertyDescriptor(i,e);return r.get?r.get.call(arguments.length<3?t:n):r.value}},f.apply(this,arguments)}var d={type:"slider",startAt:0,perView:1,focusAt:0,gap:10,autoplay:!1,hoverpause:!0,keyboard:!0,bound:!1,swipeThreshold:80,dragThreshold:120,perSwipe:"",touchRatio:.5,touchAngle:45,animationDuration:400,rewind:!0,rewindDuration:800,animationTimingFunc:"cubic-bezier(.165, .840, .440, 1)",waitForTransition:!0,throttle:10,direction:"ltr",peek:0,cloningRatio:1,breakpoints:{},classes:{swipeable:"glide--swipeable",dragging:"glide--dragging",direction:{ltr:"glide--ltr",rtl:"glide--rtl"},type:{slider:"glide--slider",carousel:"glide--carousel"},slide:{clone:"glide__slide--clone",active:"glide__slide--active"},arrow:{disabled:"glide__arrow--disabled"},nav:{active:"glide__bullet--active"}}};function h(t){console.error("[Glide warn]: ".concat(t))}function v(t){return parseInt(t)}function p(t){return"string"==typeof t}function g(t){var e=n(t);return"function"===e||"object"===e&&!!t}function m(t){return"function"==typeof t}function b(t){return t.constructor===Array}function y(t,e,n){Object.defineProperty(t,e,n)}function w(t,n){var i=Object.assign({},t,n);if(n.hasOwnProperty("classes")){i.classes=Object.assign({},t.classes,n.classes);["direction","type","slide","arrow","nav"].forEach((function(r){n.classes.hasOwnProperty(r)&&(i.classes[r]=e(e({},t.classes[r]),n.classes[r]))}))}return n.hasOwnProperty("breakpoints")&&(i.breakpoints=Object.assign({},t.breakpoints,n.breakpoints)),i}var _=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,t),this.events=e,this.hop=e.hasOwnProperty}return o(t,[{key:"on",value:function(t,e){if(!b(t)){this.hop.call(this.events,t)||(this.events[t]=[]);var n=this.events[t].push(e)-1;return{remove:function(){delete this.events[t][n]}}}for(var i=0;i<t.length;i++)this.on(t[i],e)}},{key:"emit",value:function(t,e){if(b(t))for(var n=0;n<t.length;n++)this.emit(t[n],e);else this.hop.call(this.events,t)&&this.events[t].forEach((function(t){t(e||{})}))}}]),t}(),S=function(){function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};i(this,t),this._c={},this._t=[],this._e=new _,this.disabled=!1,this.selector=e,this.settings=w(d,n),this.index=this.settings.startAt}return o(t,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this._e.emit("mount.before"),g(t)?this._c=function(t,e,n){var i={};for(var r in e)m(e[r])?i[r]=e[r](t,i,n):h("Extension must be a function");for(var o in i)m(i[o].mount)&&i[o].mount();return i}(this,t,this._e):h("You need to provide a object on `mount()`"),this._e.emit("mount.after"),this}},{key:"mutate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return b(t)?this._t=t:h("You need to provide a array on `mutate()`"),this}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.settings=w(this.settings,t),t.hasOwnProperty("startAt")&&(this.index=t.startAt),this._e.emit("update"),this}},{key:"go",value:function(t){return this._c.Run.make(t),this}},{key:"move",value:function(t){return this._c.Transition.disable(),this._c.Move.make(t),this}},{key:"destroy",value:function(){return this._e.emit("destroy"),this}},{key:"play",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return t&&(this.settings.autoplay=t),this._e.emit("play"),this}},{key:"pause",value:function(){return this._e.emit("pause"),this}},{key:"disable",value:function(){return this.disabled=!0,this}},{key:"enable",value:function(){return this.disabled=!1,this}},{key:"on",value:function(t,e){return this._e.on(t,e),this}},{key:"isType",value:function(t){return this.settings.type===t}},{key:"settings",get:function(){return this._o},set:function(t){g(t)?this._o=t:h("Options must be an `object` instance.")}},{key:"index",get:function(){return this._i},set:function(t){this._i=v(t)}},{key:"type",get:function(){return this.settings.type}},{key:"disabled",get:function(){return this._d},set:function(t){this._d=!!t}}]),t}();function k(){return(new Date).getTime()}function O(t,e){var n,i,r,o,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=0,u=function(){a=!1===s.leading?0:k(),n=null,o=t.apply(i,r),n||(i=r=null)},c=function(){var c=k();a||!1!==s.leading||(a=c);var l=e-(c-a);return i=this,r=arguments,l<=0||l>e?(n&&(clearTimeout(n),n=null),a=c,o=t.apply(i,r),n||(i=r=null)):n||!1===s.trailing||(n=setTimeout(u,l)),o};return c.cancel=function(){clearTimeout(n),a=0,n=i=r=null},c}var T={ltr:["marginLeft","marginRight"],rtl:["marginRight","marginLeft"]};function x(t){if(t&&t.parentNode){for(var e=t.parentNode.firstChild,n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}return[]}function H(t){return Array.prototype.slice.call(t)}var j=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,t),this.listeners=e}return o(t,[{key:"on",value:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];p(t)&&(t=[t]);for(var r=0;r<t.length;r++)this.listeners[t[r]]=n,e.addEventListener(t[r],this.listeners[t[r]],i)}},{key:"off",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];p(t)&&(t=[t]);for(var i=0;i<t.length;i++)e.removeEventListener(t[i],this.listeners[t[i]],n)}},{key:"destroy",value:function(){delete this.listeners}}]),t}();var A=["ltr","rtl"],P={">":"<","<":">","=":"="};function z(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}function E(t,e){return{modify:function(t){var n=Math.floor(t/e.Sizes.slideWidth);return t+e.Gaps.value*n}}}function L(t,e){return{modify:function(t){return t+e.Clones.grow/2}}}function R(t,e){return{modify:function(n){if(t.settings.focusAt>=0){var i=e.Peek.value;return g(i)?n-i.before:n-i}return n}}}function C(t,e){return{modify:function(n){var i=e.Gaps.value,r=e.Sizes.width,o=t.settings.focusAt,s=e.Sizes.slideWidth;return"center"===o?n-(r/2-s/2):n-s*o-i*o}}}var M=!1;try{var D=Object.defineProperty({},"passive",{get:function(){M=!0}});window.addEventListener("testPassive",null,D),window.removeEventListener("testPassive",null,D)}catch(t){}var V=M,B=["touchstart","mousedown"],W=["touchmove","mousemove"],q=["touchend","touchcancel","mouseup","mouseleave"],G=["mousedown","mousemove","mouseup","mouseleave"];function F(t,e,n){var i=new j,r=0,o=0,s=0,a=!1,u=!!V&&{passive:!0},c={mount:function(){this.bindSwipeStart()},start:function(e){if(!a&&!t.disabled){this.disable();var i=this.touches(e);r=null,o=v(i.pageX),s=v(i.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),n.emit("swipe.start")}},move:function(i){if(!t.disabled){var a=t.settings,u=a.touchAngle,c=a.touchRatio,l=a.classes,f=this.touches(i),d=v(f.pageX)-o,h=v(f.pageY)-s,p=Math.abs(d<<2),g=Math.abs(h<<2),m=Math.sqrt(p+g),b=Math.sqrt(g);if(!(180*(r=Math.asin(b/m))/Math.PI<u))return!1;i.stopPropagation(),e.Move.make(d*parseFloat(c)),e.Html.root.classList.add(l.dragging),n.emit("swipe.move")}},end:function(i){if(!t.disabled){var s=t.settings,a=s.perSwipe,u=s.touchAngle,c=s.classes,l=this.touches(i),f=this.threshold(i),d=l.pageX-o,h=180*r/Math.PI;this.enable(),d>f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,"<"))):d<-f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,">"))):e.Move.make(),e.Html.root.classList.remove(c.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),n.emit("swipe.end")}},bindSwipeStart:function(){var n=this,r=t.settings,o=r.swipeThreshold,s=r.dragThreshold;o&&i.on(B[0],e.Html.wrapper,(function(t){n.start(t)}),u),s&&i.on(B[1],e.Html.wrapper,(function(t){n.start(t)}),u)},unbindSwipeStart:function(){i.off(B[0],e.Html.wrapper,u),i.off(B[1],e.Html.wrapper,u)},bindSwipeMove:function(){var n=this;i.on(W,e.Html.wrapper,O((function(t){n.move(t)}),t.settings.throttle),u)},unbindSwipeMove:function(){i.off(W,e.Html.wrapper,u)},bindSwipeEnd:function(){var t=this;i.on(q,e.Html.wrapper,(function(e){t.end(e)}))},unbindSwipeEnd:function(){i.off(q,e.Html.wrapper)},touches:function(t){return G.indexOf(t.type)>-1?t:t.touches[0]||t.changedTouches[0]},threshold:function(e){var n=t.settings;return G.indexOf(e.type)>-1?n.dragThreshold:n.swipeThreshold},enable:function(){return a=!1,e.Transition.enable(),this},disable:function(){return a=!0,e.Transition.disable(),this}};return n.on("build.after",(function(){e.Html.root.classList.add(t.settings.classes.swipeable)})),n.on("destroy",(function(){c.unbindSwipeStart(),c.unbindSwipeMove(),c.unbindSwipeEnd(),i.destroy()})),c}var I='[data-glide-el^="controls"]',N="".concat(I,' [data-glide-dir*="<"]'),Y="".concat(I,' [data-glide-dir*=">"]');function X(t,e,n){var i=new j,r=!!V&&{passive:!0},o={mount:function(){this._n=e.Html.root.querySelectorAll('[data-glide-el="controls[nav]"]'),this._c=e.Html.root.querySelectorAll(I),this._arrowControls={previous:e.Html.root.querySelectorAll(N),next:e.Html.root.querySelectorAll(Y)},this.addBindings()},setActive:function(){for(var t=0;t<this._n.length;t++)this.addClass(this._n[t].children)},removeActive:function(){for(var t=0;t<this._n.length;t++)this.removeClass(this._n[t].children)},addClass:function(e){var n=t.settings,i=e[t.index];i&&(i.classList.add(n.classes.nav.active),x(i).forEach((function(t){t.classList.remove(n.classes.nav.active)})))},removeClass:function(e){var n=e[t.index];null==n||n.classList.remove(t.settings.classes.nav.active)},setArrowState:function(){if(!t.settings.rewind){var n=o._arrowControls.next,i=o._arrowControls.previous;this.resetArrowState(n,i),0===t.index&&this.disableArrow(i),t.index===e.Run.length&&this.disableArrow(n)}},resetArrowState:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){H(t).forEach((function(t){t.classList.remove(e.classes.arrow.disabled)}))}))},disableArrow:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){H(t).forEach((function(t){t.classList.add(e.classes.arrow.disabled)}))}))},addBindings:function(){for(var t=0;t<this._c.length;t++)this.bind(this._c[t].children)},removeBindings:function(){for(var t=0;t<this._c.length;t++)this.unbind(this._c[t].children)},bind:function(t){for(var e=0;e<t.length;e++)i.on("click",t[e],this.click),i.on("touchstart",t[e],this.click,r)},unbind:function(t){for(var e=0;e<t.length;e++)i.off(["click","touchstart"],t[e])},click:function(t){V||"touchstart"!==t.type||t.preventDefault();var n=t.currentTarget.getAttribute("data-glide-dir");e.Run.make(e.Direction.resolve(n))}};return y(o,"items",{get:function(){return o._c}}),n.on(["mount.after","move.after"],(function(){o.setActive()})),n.on(["mount.after","run"],(function(){o.setArrowState()})),n.on("destroy",(function(){o.removeBindings(),o.removeActive(),i.destroy()})),o}function $(t){return g(t)?(e=t,Object.keys(e).sort().reduce((function(t,n){return t[n]=e[n],t[n],t}),{})):(h("Breakpoints option must be an object"),{});var e}function J(t,e,n){var i=new j,r=t.settings,o=$(r.breakpoints),s=Object.assign({},r),a={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: ".concat(e,"px)")).matches)return t[e];return s}};return Object.assign(r,a.match(o)),i.on("resize",window,O((function(){t.settings=w(r,a.match(o))}),t.settings.throttle)),n.on("update",(function(){o=$(o),s=Object.assign({},r)})),n.on("destroy",(function(){i.off("resize",window)})),a}var K={Html:function(t,e,n){var i={mount:function(){this.root=t.selector,this.track=this.root.querySelector('[data-glide-el="track"]'),this.collectSlides()},collectSlides:function(){this.slides=H(this.wrapper.children).filter((function(e){return!e.classList.contains(t.settings.classes.slide.clone)}))}};return y(i,"root",{get:function(){return i._r},set:function(t){p(t)&&(t=document.querySelector(t)),null!==t?i._r=t:h("Root element must be a existing Html node")}}),y(i,"track",{get:function(){return i._t},set:function(t){i._t=t}}),y(i,"wrapper",{get:function(){return i.track.children[0]}}),n.on("update",(function(){i.collectSlides()})),i},Translate:function(t,e,n){var i={set:function(n){var i=function(t,e,n){var i=[E,L,R,C].concat(t._t,[z]);return{mutate:function(r){for(var o=0;o<i.length;o++){var s=i[o];m(s)&&m(s().modify)?r=s(t,e,n).modify(r):h("Transformer should be a function that returns an object with `modify()` method")}return r}}}(t,e).mutate(n),r="translate3d(".concat(-1*i,"px, 0px, 0px)");e.Html.wrapper.style.mozTransform=r,e.Html.wrapper.style.webkitTransform=r,e.Html.wrapper.style.transform=r},remove:function(){e.Html.wrapper.style.transform=""},getStartIndex:function(){var n=e.Sizes.length,i=t.index,r=t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?n+(i-r):(i+r)%n},getTravelDistance:function(){var n=e.Sizes.slideWidth*t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?-1*n:n}};return n.on("move",(function(r){if(!t.isType("carousel")||!e.Run.isOffset())return i.set(r.movement);e.Transition.after((function(){n.emit("translate.jump"),i.set(e.Sizes.slideWidth*t.index)}));var o=e.Sizes.slideWidth*e.Translate.getStartIndex();return i.set(o-e.Translate.getTravelDistance())})),n.on("destroy",(function(){i.remove()})),i},Transition:function(t,e,n){var i=!1,r={compose:function(e){var n=t.settings;return i?"".concat(e," 0ms ").concat(n.animationTimingFunc):"".concat(e," ").concat(this.duration,"ms ").concat(n.animationTimingFunc)},set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"transform";e.Html.wrapper.style.transition=this.compose(t)},remove:function(){e.Html.wrapper.style.transition=""},after:function(t){setTimeout((function(){t()}),this.duration)},enable:function(){i=!1,this.set()},disable:function(){i=!0,this.set()}};return y(r,"duration",{get:function(){var n=t.settings;return t.isType("slider")&&e.Run.offset?n.rewindDuration:n.animationDuration}}),n.on("move",(function(){r.set()})),n.on(["build.before","resize","translate.jump"],(function(){r.disable()})),n.on("run",(function(){r.enable()})),n.on("destroy",(function(){r.remove()})),r},Direction:function(t,e,n){var i={mount:function(){this.value=t.settings.direction},resolve:function(t){var e=t.slice(0,1);return this.is("rtl")?t.split(e).join(P[e]):t},is:function(t){return this.value===t},addClass:function(){e.Html.root.classList.add(t.settings.classes.direction[this.value])},removeClass:function(){e.Html.root.classList.remove(t.settings.classes.direction[this.value])}};return y(i,"value",{get:function(){return i._v},set:function(t){A.indexOf(t)>-1?i._v=t:h("Direction value must be `ltr` or `rtl`")}}),n.on(["destroy","update"],(function(){i.removeClass()})),n.on("update",(function(){i.mount()})),n.on(["build.before","update"],(function(){i.addClass()})),i},Peek:function(t,e,n){var i={mount:function(){this.value=t.settings.peek}};return y(i,"value",{get:function(){return i._v},set:function(t){g(t)?(t.before=v(t.before),t.after=v(t.after)):t=v(t),i._v=t}}),y(i,"reductor",{get:function(){var e=i.value,n=t.settings.perView;return g(e)?e.before/n+e.after/n:2*e/n}}),n.on(["resize","update"],(function(){i.mount()})),i},Sizes:function(t,e,n){var i={setupSlides:function(){for(var t="".concat(this.slideWidth,"px"),n=e.Html.slides,i=0;i<n.length;i++)n[i].style.width=t},setupWrapper:function(){e.Html.wrapper.style.width="".concat(this.wrapperSize,"px")},remove:function(){for(var t=e.Html.slides,n=0;n<t.length;n++)t[n].style.width="";e.Html.wrapper.style.width=""}};return y(i,"length",{get:function(){return e.Html.slides.length}}),y(i,"width",{get:function(){return e.Html.track.offsetWidth}}),y(i,"wrapperSize",{get:function(){return i.slideWidth*i.length+e.Gaps.grow+e.Clones.grow}}),y(i,"slideWidth",{get:function(){return i.width/t.settings.perView-e.Peek.reductor-e.Gaps.reductor}}),n.on(["build.before","resize","update"],(function(){i.setupSlides(),i.setupWrapper()})),n.on("destroy",(function(){i.remove()})),i},Gaps:function(t,e,n){var i={apply:function(t){for(var n=0,i=t.length;n<i;n++){var r=t[n].style,o=e.Direction.value;r[T[o][0]]=0!==n?"".concat(this.value/2,"px"):"",n!==t.length-1?r[T[o][1]]="".concat(this.value/2,"px"):r[T[o][1]]=""}},remove:function(t){for(var e=0,n=t.length;e<n;e++){var i=t[e].style;i.marginLeft="",i.marginRight=""}}};return y(i,"value",{get:function(){return v(t.settings.gap)}}),y(i,"grow",{get:function(){return i.value*e.Sizes.length}}),y(i,"reductor",{get:function(){var e=t.settings.perView;return i.value*(e-1)/e}}),n.on(["build.after","update"],O((function(){i.apply(e.Html.wrapper.children)}),30)),n.on("destroy",(function(){i.remove(e.Html.wrapper.children)})),i},Move:function(t,e,n){var i={mount:function(){this._o=0},make:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.offset=i,n.emit("move",{movement:this.value}),e.Transition.after((function(){n.emit("move.after",{movement:t.value})}))}};return y(i,"offset",{get:function(){return i._o},set:function(t){i._o=function(t){return void 0===t}(t)?0:v(t)}}),y(i,"translate",{get:function(){return e.Sizes.slideWidth*t.index}}),y(i,"value",{get:function(){var t=this.offset,n=this.translate;return e.Direction.is("rtl")?n+t:n-t}}),n.on(["build.before","run"],(function(){i.make()})),i},Clones:function(t,e,n){var i={mount:function(){this.items=[],t.isType("carousel")&&(this.items=this.collect())},collect:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=e.Html.slides,r=t.settings,o=r.perView,s=r.classes,a=r.cloningRatio;if(i.length>0)for(var u=o+ +!!t.settings.peek+Math.round(o/2),c=i.slice(0,u).reverse(),l=i.slice(-1*u),f=0;f<Math.max(a,Math.floor(o/i.length));f++){for(var d=0;d<c.length;d++){var h=c[d].cloneNode(!0);h.classList.add(s.slide.clone),n.push(h)}for(var v=0;v<l.length;v++){var p=l[v].cloneNode(!0);p.classList.add(s.slide.clone),n.unshift(p)}}return n},append:function(){for(var t=this.items,n=e.Html,i=n.wrapper,r=n.slides,o=Math.floor(t.length/2),s=t.slice(0,o).reverse(),a=t.slice(-1*o).reverse(),u="".concat(e.Sizes.slideWidth,"px"),c=0;c<a.length;c++)i.appendChild(a[c]);for(var l=0;l<s.length;l++)i.insertBefore(s[l],r[0]);for(var f=0;f<t.length;f++)t[f].style.width=u},remove:function(){for(var t=this.items,n=0;n<t.length;n++)e.Html.wrapper.removeChild(t[n])}};return y(i,"grow",{get:function(){return(e.Sizes.slideWidth+e.Gaps.value)*i.items.length}}),n.on("update",(function(){i.remove(),i.mount(),i.append()})),n.on("build.before",(function(){t.isType("carousel")&&i.append()})),n.on("destroy",(function(){i.remove()})),i},Resize:function(t,e,n){var i=new j,r={mount:function(){this.bind()},bind:function(){i.on("resize",window,O((function(){n.emit("resize")}),t.settings.throttle))},unbind:function(){i.off("resize",window)}};return n.on("destroy",(function(){r.unbind(),i.destroy()})),r},Build:function(t,e,n){var i={mount:function(){n.emit("build.before"),this.typeClass(),this.activeClass(),n.emit("build.after")},typeClass:function(){e.Html.root.classList.add(t.settings.classes.type[t.settings.type])},activeClass:function(){var n=t.settings.classes,i=e.Html.slides[t.index];i&&(i.classList.add(n.slide.active),x(i).forEach((function(t){t.classList.remove(n.slide.active)})))},removeClasses:function(){var n=t.settings.classes,i=n.type,r=n.slide;e.Html.root.classList.remove(i[t.settings.type]),e.Html.slides.forEach((function(t){t.classList.remove(r.active)}))}};return n.on(["destroy","update"],(function(){i.removeClasses()})),n.on(["resize","update"],(function(){i.mount()})),n.on("move.after",(function(){i.activeClass()})),i},Run:function(t,e,n){var i={mount:function(){this._o=!1},make:function(i){var r=this;t.disabled||(!t.settings.waitForTransition||t.disable(),this.move=i,n.emit("run.before",this.move),this.calculate(),n.emit("run",this.move),e.Transition.after((function(){r.isStart()&&n.emit("run.start",r.move),r.isEnd()&&n.emit("run.end",r.move),r.isOffset()&&(r._o=!1,n.emit("run.offset",r.move)),n.emit("run.after",r.move),t.enable()})))},calculate:function(){var e=this.move,n=this.length,r=e.steps,o=e.direction,s=1;if("="===o)return t.settings.bound&&v(r)>n?void(t.index=n):void(t.index=r);if(">"!==o||">"!==r)if("<"!==o||"<"!==r){if("|"===o&&(s=t.settings.perView||1),">"===o||"|"===o&&">"===r){var a=function(e){var n=t.index;if(t.isType("carousel"))return n+e;return n+(e-n%e)}(s);return a>n&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e<=r)return e;if(t.isType("carousel"))return e-(r+1);if(t.settings.rewind)return i.isBound()&&!i.isEnd()?r:0;if(i.isBound())return r;return Math.floor(r/n)*n}(a,s))}if("<"===o||"|"===o&&"<"===r){var u=function(e){var n=t.index;if(t.isType("carousel"))return n-e;var i=Math.ceil(n/e);return(i-1)*e}(s);return u<0&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e>=0)return e;if(t.isType("carousel"))return e+(r+1);if(t.settings.rewind)return i.isBound()&&i.isStart()?r:Math.floor(r/n)*n;return 0}(u,s))}h("Invalid direction pattern [".concat(o).concat(r,"] has been used"))}else t.index=0;else t.index=n},isStart:function(){return t.index<=0},isEnd:function(){return t.index>=this.length},isOffset:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return t?!!this._o&&("|>"===t?"|"===this.move.direction&&">"===this.move.steps:"|<"===t?"|"===this.move.direction&&"<"===this.move.steps:this.move.direction===t):this._o},isBound:function(){return t.isType("slider")&&"center"!==t.settings.focusAt&&t.settings.bound}};return y(i,"move",{get:function(){return this._m},set:function(t){var e=t.substr(1);this._m={direction:t.substr(0,1),steps:e?v(e)?v(e):e:0}}}),y(i,"length",{get:function(){var n=t.settings,i=e.Html.slides.length;return this.isBound()?i-1-(v(n.perView)-1)+v(n.focusAt):i-1}}),y(i,"offset",{get:function(){return this._o}}),i}},Q=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&u(t,e)}(n,t);var e=l(n);function n(){return i(this,n),e.apply(this,arguments)}return o(n,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return f(a(n.prototype),"mount",this).call(this,Object.assign({},K,t))}}]),n}(S);const U="glide__arrow--left",Z="glide__arrow--right";function tt(t,e){return{mount(){t.settings.rewind||(t.on(["mount.after","resize"],(()=>{e.Sizes.length<=t.settings.perView?t.disable():t.enable()})),t.on(["mount.after","run","resize"],(()=>{e.Controls.items.forEach((n=>{const i=n.querySelector(`.${U}`);i&&(0===t.index||e.Sizes.length<=t.settings.perView?i.setAttribute("disabled",""):i.removeAttribute("disabled"));const r=n.querySelector(`.${Z}`);if(r){(t.settings.bound?t.index+(t.settings.perView-1):t.index)===e.Sizes.length-1||e.Sizes.length<=t.settings.perView?r.setAttribute("disabled",""):r.removeAttribute("disabled")}i.disabled&&r.disabled?n.classList.add("glide__arrows--disabled"):n.classList.remove("glide__arrows--disabled")}))})))}}}((t,e)=>{t.behaviors.glide={attach(t){e("glide",".carousel .glide",t).forEach((t=>{const e=new Q(t,{rewind:!1,bound:!0,dragThreshold:!1,gap:16,perView:4,breakpoints:{9999:{perView:4},1199:{perView:3},767:{perView:2},575:{perView:1}}});let n;const i=t=>{t.settings.perView!==t.previousPerView&&(t.previousPerView=t.settings.perView,t.enable().go("<<").disable())};e.on("resize",(()=>{n&&clearTimeout(n),n=setTimeout(i,50,e)})),e.mount({Controls:X,Breakpoints:J,Swipe:F,ControlsDisabler:tt}),e.previousPerView=e.settings.perView;const r=t.querySelector(".glide__arrow--right"),o=t.querySelector(".glide__arrow--left");r.addEventListener("click",(()=>{e.go(">")})),o.addEventListener("click",(()=>{e.go("<")})),e.on("run",(()=>{t.classList.add("glide-animating")})).on("run.after",(()=>{t.classList.remove("glide-animating")}))}))}}})(Drupal,once)})); + */function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function r(t){return r=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},r(t)}function s(t,e){return s=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},s(t,e)}function o(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function a(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=r(t);if(e){var s=r(this).constructor;n=Reflect.construct(i,arguments,s)}else n=i.apply(this,arguments);return o(this,n)}}function u(){return u="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=r(t)););return t}(t,e);if(i){var s=Object.getOwnPropertyDescriptor(i,e);return s.get?s.get.call(arguments.length<3?t:n):s.value}},u.apply(this,arguments)}var c={type:"slider",startAt:0,perView:1,focusAt:0,gap:10,autoplay:!1,hoverpause:!0,keyboard:!0,bound:!1,swipeThreshold:80,dragThreshold:120,perSwipe:"",touchRatio:.5,touchAngle:45,animationDuration:400,rewind:!0,rewindDuration:800,animationTimingFunc:"cubic-bezier(.165, .840, .440, 1)",waitForTransition:!0,throttle:10,direction:"ltr",peek:0,cloningRatio:1,breakpoints:{},classes:{swipeable:"glide--swipeable",dragging:"glide--dragging",direction:{ltr:"glide--ltr",rtl:"glide--rtl"},type:{slider:"glide--slider",carousel:"glide--carousel"},slide:{clone:"glide__slide--clone",active:"glide__slide--active"},arrow:{disabled:"glide__arrow--disabled"},nav:{active:"glide__bullet--active"}}};function l(t){console.error("[Glide warn]: ".concat(t))}function f(t){return parseInt(t)}function d(t){return"string"==typeof t}function h(e){var n=t(e);return"function"===n||"object"===n&&!!e}function v(t){return"function"==typeof t}function p(t){return t.constructor===Array}function g(t,e,n){Object.defineProperty(t,e,n)}function m(t,e){var n=Object.assign({},t,e);return e.hasOwnProperty("classes")&&(n.classes=Object.assign({},t.classes,e.classes),e.classes.hasOwnProperty("direction")&&(n.classes.direction=Object.assign({},t.classes.direction,e.classes.direction)),e.classes.hasOwnProperty("type")&&(n.classes.type=Object.assign({},t.classes.type,e.classes.type)),e.classes.hasOwnProperty("slide")&&(n.classes.slide=Object.assign({},t.classes.slide,e.classes.slide)),e.classes.hasOwnProperty("arrow")&&(n.classes.arrow=Object.assign({},t.classes.arrow,e.classes.arrow)),e.classes.hasOwnProperty("nav")&&(n.classes.nav=Object.assign({},t.classes.nav,e.classes.nav))),e.hasOwnProperty("breakpoints")&&(n.breakpoints=Object.assign({},t.breakpoints,e.breakpoints)),n}var w=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.events=n,this.hop=n.hasOwnProperty}return i(t,[{key:"on",value:function(t,e){if(!p(t)){this.hop.call(this.events,t)||(this.events[t]=[]);var n=this.events[t].push(e)-1;return{remove:function(){delete this.events[t][n]}}}for(var i=0;i<t.length;i++)this.on(t[i],e)}},{key:"emit",value:function(t,e){if(p(t))for(var n=0;n<t.length;n++)this.emit(t[n],e);else this.hop.call(this.events,t)&&this.events[t].forEach((function(t){t(e||{})}))}}]),t}(),y=function(){function t(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,t),this._c={},this._t=[],this._e=new w,this.disabled=!1,this.selector=n,this.settings=m(c,i),this.index=this.settings.startAt}return i(t,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this._e.emit("mount.before"),h(t)?this._c=function(t,e,n){var i={};for(var r in e)v(e[r])?i[r]=e[r](t,i,n):l("Extension must be a function");for(var s in i)v(i[s].mount)&&i[s].mount();return i}(this,t,this._e):l("You need to provide a object on `mount()`"),this._e.emit("mount.after"),this}},{key:"mutate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return p(t)?this._t=t:l("You need to provide a array on `mutate()`"),this}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.settings=m(this.settings,t),t.hasOwnProperty("startAt")&&(this.index=t.startAt),this._e.emit("update"),this}},{key:"go",value:function(t){return this._c.Run.make(t),this}},{key:"move",value:function(t){return this._c.Transition.disable(),this._c.Move.make(t),this}},{key:"destroy",value:function(){return this._e.emit("destroy"),this}},{key:"play",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return t&&(this.settings.autoplay=t),this._e.emit("play"),this}},{key:"pause",value:function(){return this._e.emit("pause"),this}},{key:"disable",value:function(){return this.disabled=!0,this}},{key:"enable",value:function(){return this.disabled=!1,this}},{key:"on",value:function(t,e){return this._e.on(t,e),this}},{key:"isType",value:function(t){return this.settings.type===t}},{key:"settings",get:function(){return this._o},set:function(t){h(t)?this._o=t:l("Options must be an `object` instance.")}},{key:"index",get:function(){return this._i},set:function(t){this._i=f(t)}},{key:"type",get:function(){return this.settings.type}},{key:"disabled",get:function(){return this._d},set:function(t){this._d=!!t}}]),t}();function b(){return(new Date).getTime()}function _(t,e,n){var i,r,s,o,a=0;n||(n={});var u=function(){a=!1===n.leading?0:b(),i=null,o=t.apply(r,s),i||(r=s=null)},c=function(){var c=b();a||!1!==n.leading||(a=c);var l=e-(c-a);return r=this,s=arguments,l<=0||l>e?(i&&(clearTimeout(i),i=null),a=c,o=t.apply(r,s),i||(r=s=null)):i||!1===n.trailing||(i=setTimeout(u,l)),o};return c.cancel=function(){clearTimeout(i),a=0,i=r=s=null},c}var S={ltr:["marginLeft","marginRight"],rtl:["marginRight","marginLeft"]};function k(t){if(t&&t.parentNode){for(var e=t.parentNode.firstChild,n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}return[]}function O(t){return!!(t&&t instanceof window.HTMLElement)}function T(t){return Array.prototype.slice.call(t)}var x='[data-glide-el="track"]';var H=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.listeners=n}return i(t,[{key:"on",value:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];d(t)&&(t=[t]);for(var r=0;r<t.length;r++)this.listeners[t[r]]=n,e.addEventListener(t[r],this.listeners[t[r]],i)}},{key:"off",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];d(t)&&(t=[t]);for(var i=0;i<t.length;i++)e.removeEventListener(t[i],this.listeners[t[i]],n)}},{key:"destroy",value:function(){delete this.listeners}}]),t}();var A=["ltr","rtl"],j={">":"<","<":">","=":"="};function z(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}function L(t,e){return{modify:function(t){var n=Math.floor(t/e.Sizes.slideWidth);return t+e.Gaps.value*n}}}function P(t,e){return{modify:function(t){return t+e.Clones.grow/2}}}function E(t,e){return{modify:function(n){if(t.settings.focusAt>=0){var i=e.Peek.value;return h(i)?n-i.before:n-i}return n}}}function R(t,e){return{modify:function(n){var i=e.Gaps.value,r=e.Sizes.width,s=t.settings.focusAt,o=e.Sizes.slideWidth;return"center"===s?n-(r/2-o/2):n-o*s-i*s}}}var C=!1;try{var M=Object.defineProperty({},"passive",{get:function(){C=!0}});window.addEventListener("testPassive",null,M),window.removeEventListener("testPassive",null,M)}catch(t){}var V=C,D=["touchstart","mousedown"],B=["touchmove","mousemove"],W=["touchend","touchcancel","mouseup","mouseleave"],q=["mousedown","mousemove","mouseup","mouseleave"];function G(t,e,n){var i=new H,r=0,s=0,o=0,a=!1,u=!!V&&{passive:!0},c={mount:function(){this.bindSwipeStart()},start:function(e){if(!a&&!t.disabled){this.disable();var i=this.touches(e);r=null,s=f(i.pageX),o=f(i.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),n.emit("swipe.start")}},move:function(i){if(!t.disabled){var a=t.settings,u=a.touchAngle,c=a.touchRatio,l=a.classes,d=this.touches(i),h=f(d.pageX)-s,v=f(d.pageY)-o,p=Math.abs(h<<2),g=Math.abs(v<<2),m=Math.sqrt(p+g),w=Math.sqrt(g);if(!(180*(r=Math.asin(w/m))/Math.PI<u))return!1;i.stopPropagation(),e.Move.make(h*parseFloat(c)),e.Html.root.classList.add(l.dragging),n.emit("swipe.move")}},end:function(i){if(!t.disabled){var o=t.settings,a=o.perSwipe,u=o.touchAngle,c=o.classes,l=this.touches(i),f=this.threshold(i),d=l.pageX-s,h=180*r/Math.PI;this.enable(),d>f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,"<"))):d<-f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,">"))):e.Move.make(),e.Html.root.classList.remove(c.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),n.emit("swipe.end")}},bindSwipeStart:function(){var n=this,r=t.settings,s=r.swipeThreshold,o=r.dragThreshold;s&&i.on(D[0],e.Html.wrapper,(function(t){n.start(t)}),u),o&&i.on(D[1],e.Html.wrapper,(function(t){n.start(t)}),u)},unbindSwipeStart:function(){i.off(D[0],e.Html.wrapper,u),i.off(D[1],e.Html.wrapper,u)},bindSwipeMove:function(){var n=this;i.on(B,e.Html.wrapper,_((function(t){n.move(t)}),t.settings.throttle),u)},unbindSwipeMove:function(){i.off(B,e.Html.wrapper,u)},bindSwipeEnd:function(){var t=this;i.on(W,e.Html.wrapper,(function(e){t.end(e)}))},unbindSwipeEnd:function(){i.off(W,e.Html.wrapper)},touches:function(t){return q.indexOf(t.type)>-1?t:t.touches[0]||t.changedTouches[0]},threshold:function(e){var n=t.settings;return q.indexOf(e.type)>-1?n.dragThreshold:n.swipeThreshold},enable:function(){return a=!1,e.Transition.enable(),this},disable:function(){return a=!0,e.Transition.disable(),this}};return n.on("build.after",(function(){e.Html.root.classList.add(t.settings.classes.swipeable)})),n.on("destroy",(function(){c.unbindSwipeStart(),c.unbindSwipeMove(),c.unbindSwipeEnd(),i.destroy()})),c}var F='[data-glide-el^="controls"]',I="".concat(F,' [data-glide-dir*="<"]'),N="".concat(F,' [data-glide-dir*=">"]');function Y(t,e,n){var i=new H,r=!!V&&{passive:!0},s={mount:function(){this._n=e.Html.root.querySelectorAll('[data-glide-el="controls[nav]"]'),this._c=e.Html.root.querySelectorAll(F),this._arrowControls={previous:e.Html.root.querySelectorAll(I),next:e.Html.root.querySelectorAll(N)},this.addBindings()},setActive:function(){for(var t=0;t<this._n.length;t++)this.addClass(this._n[t].children)},removeActive:function(){for(var t=0;t<this._n.length;t++)this.removeClass(this._n[t].children)},addClass:function(e){var n=t.settings,i=e[t.index];i&&i&&(i.classList.add(n.classes.nav.active),k(i).forEach((function(t){t.classList.remove(n.classes.nav.active)})))},removeClass:function(e){var n=e[t.index];n&&n.classList.remove(t.settings.classes.nav.active)},setArrowState:function(){if(!t.settings.rewind){var n=s._arrowControls.next,i=s._arrowControls.previous;this.resetArrowState(n,i),0===t.index&&this.disableArrow(i),t.index===e.Run.length&&this.disableArrow(n)}},resetArrowState:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){T(t).forEach((function(t){t.classList.remove(e.classes.arrow.disabled)}))}))},disableArrow:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){T(t).forEach((function(t){t.classList.add(e.classes.arrow.disabled)}))}))},addBindings:function(){for(var t=0;t<this._c.length;t++)this.bind(this._c[t].children)},removeBindings:function(){for(var t=0;t<this._c.length;t++)this.unbind(this._c[t].children)},bind:function(t){for(var e=0;e<t.length;e++)i.on("click",t[e],this.click),i.on("touchstart",t[e],this.click,r)},unbind:function(t){for(var e=0;e<t.length;e++)i.off(["click","touchstart"],t[e])},click:function(t){V||"touchstart"!==t.type||t.preventDefault();var n=t.currentTarget.getAttribute("data-glide-dir");e.Run.make(e.Direction.resolve(n))}};return g(s,"items",{get:function(){return s._c}}),n.on(["mount.after","move.after"],(function(){s.setActive()})),n.on(["mount.after","run"],(function(){s.setArrowState()})),n.on("destroy",(function(){s.removeBindings(),s.removeActive(),i.destroy()})),s}function X(t){return h(t)?(e=t,Object.keys(e).sort().reduce((function(t,n){return t[n]=e[n],t[n],t}),{})):(l("Breakpoints option must be an object"),{});var e}function $(t,e,n){var i=new H,r=t.settings,s=X(r.breakpoints),o=Object.assign({},r),a={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: ".concat(e,"px)")).matches)return t[e];return o}};return Object.assign(r,a.match(s)),i.on("resize",window,_((function(){t.settings=m(r,a.match(s))}),t.settings.throttle)),n.on("update",(function(){s=X(s),o=Object.assign({},r)})),n.on("destroy",(function(){i.off("resize",window)})),a}var J={Html:function(t,e,n){var i={mount:function(){this.root=t.selector,this.track=this.root.querySelector(x),this.collectSlides()},collectSlides:function(){this.slides=T(this.wrapper.children).filter((function(e){return!e.classList.contains(t.settings.classes.slide.clone)}))}};return g(i,"root",{get:function(){return i._r},set:function(t){d(t)&&(t=document.querySelector(t)),O(t)?i._r=t:l("Root element must be a existing Html node")}}),g(i,"track",{get:function(){return i._t},set:function(t){O(t)?i._t=t:l("Could not find track element. Please use ".concat(x," attribute."))}}),g(i,"wrapper",{get:function(){return i.track.children[0]}}),n.on("update",(function(){i.collectSlides()})),i},Translate:function(t,e,n){var i={set:function(n){var i=function(t,e,n){var i=[L,P,E,R].concat(t._t,[z]);return{mutate:function(r){for(var s=0;s<i.length;s++){var o=i[s];v(o)&&v(o().modify)?r=o(t,e,n).modify(r):l("Transformer should be a function that returns an object with `modify()` method")}return r}}}(t,e).mutate(n),r="translate3d(".concat(-1*i,"px, 0px, 0px)");e.Html.wrapper.style.mozTransform=r,e.Html.wrapper.style.webkitTransform=r,e.Html.wrapper.style.transform=r},remove:function(){e.Html.wrapper.style.transform=""},getStartIndex:function(){var n=e.Sizes.length,i=t.index,r=t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?n+(i-r):(i+r)%n},getTravelDistance:function(){var n=e.Sizes.slideWidth*t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?-1*n:n}};return n.on("move",(function(r){if(!t.isType("carousel")||!e.Run.isOffset())return i.set(r.movement);e.Transition.after((function(){n.emit("translate.jump"),i.set(e.Sizes.slideWidth*t.index)}));var s=e.Sizes.slideWidth*e.Translate.getStartIndex();return i.set(s-e.Translate.getTravelDistance())})),n.on("destroy",(function(){i.remove()})),i},Transition:function(t,e,n){var i=!1,r={compose:function(e){var n=t.settings;return i?"".concat(e," 0ms ").concat(n.animationTimingFunc):"".concat(e," ").concat(this.duration,"ms ").concat(n.animationTimingFunc)},set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"transform";e.Html.wrapper.style.transition=this.compose(t)},remove:function(){e.Html.wrapper.style.transition=""},after:function(t){setTimeout((function(){t()}),this.duration)},enable:function(){i=!1,this.set()},disable:function(){i=!0,this.set()}};return g(r,"duration",{get:function(){var n=t.settings;return t.isType("slider")&&e.Run.offset?n.rewindDuration:n.animationDuration}}),n.on("move",(function(){r.set()})),n.on(["build.before","resize","translate.jump"],(function(){r.disable()})),n.on("run",(function(){r.enable()})),n.on("destroy",(function(){r.remove()})),r},Direction:function(t,e,n){var i={mount:function(){this.value=t.settings.direction},resolve:function(t){var e=t.slice(0,1);return this.is("rtl")?t.split(e).join(j[e]):t},is:function(t){return this.value===t},addClass:function(){e.Html.root.classList.add(t.settings.classes.direction[this.value])},removeClass:function(){e.Html.root.classList.remove(t.settings.classes.direction[this.value])}};return g(i,"value",{get:function(){return i._v},set:function(t){A.indexOf(t)>-1?i._v=t:l("Direction value must be `ltr` or `rtl`")}}),n.on(["destroy","update"],(function(){i.removeClass()})),n.on("update",(function(){i.mount()})),n.on(["build.before","update"],(function(){i.addClass()})),i},Peek:function(t,e,n){var i={mount:function(){this.value=t.settings.peek}};return g(i,"value",{get:function(){return i._v},set:function(t){h(t)?(t.before=f(t.before),t.after=f(t.after)):t=f(t),i._v=t}}),g(i,"reductor",{get:function(){var e=i.value,n=t.settings.perView;return h(e)?e.before/n+e.after/n:2*e/n}}),n.on(["resize","update"],(function(){i.mount()})),i},Sizes:function(t,e,n){var i={setupSlides:function(){for(var t="".concat(this.slideWidth,"px"),n=e.Html.slides,i=0;i<n.length;i++)n[i].style.width=t},setupWrapper:function(){e.Html.wrapper.style.width="".concat(this.wrapperSize,"px")},remove:function(){for(var t=e.Html.slides,n=0;n<t.length;n++)t[n].style.width="";e.Html.wrapper.style.width=""}};return g(i,"length",{get:function(){return e.Html.slides.length}}),g(i,"width",{get:function(){return e.Html.track.offsetWidth}}),g(i,"wrapperSize",{get:function(){return i.slideWidth*i.length+e.Gaps.grow+e.Clones.grow}}),g(i,"slideWidth",{get:function(){return i.width/t.settings.perView-e.Peek.reductor-e.Gaps.reductor}}),n.on(["build.before","resize","update"],(function(){i.setupSlides(),i.setupWrapper()})),n.on("destroy",(function(){i.remove()})),i},Gaps:function(t,e,n){var i={apply:function(t){for(var n=0,i=t.length;n<i;n++){var r=t[n].style,s=e.Direction.value;r[S[s][0]]=0!==n?"".concat(this.value/2,"px"):"",n!==t.length-1?r[S[s][1]]="".concat(this.value/2,"px"):r[S[s][1]]=""}},remove:function(t){for(var e=0,n=t.length;e<n;e++){var i=t[e].style;i.marginLeft="",i.marginRight=""}}};return g(i,"value",{get:function(){return f(t.settings.gap)}}),g(i,"grow",{get:function(){return i.value*e.Sizes.length}}),g(i,"reductor",{get:function(){var e=t.settings.perView;return i.value*(e-1)/e}}),n.on(["build.after","update"],_((function(){i.apply(e.Html.wrapper.children)}),30)),n.on("destroy",(function(){i.remove(e.Html.wrapper.children)})),i},Move:function(t,e,n){var i={mount:function(){this._o=0},make:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.offset=i,n.emit("move",{movement:this.value}),e.Transition.after((function(){n.emit("move.after",{movement:t.value})}))}};return g(i,"offset",{get:function(){return i._o},set:function(t){i._o=function(t){return void 0===t}(t)?0:f(t)}}),g(i,"translate",{get:function(){return e.Sizes.slideWidth*t.index}}),g(i,"value",{get:function(){var t=this.offset,n=this.translate;return e.Direction.is("rtl")?n+t:n-t}}),n.on(["build.before","run"],(function(){i.make()})),i},Clones:function(t,e,n){var i={mount:function(){this.items=[],t.isType("carousel")&&(this.items=this.collect())},collect:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=e.Html.slides,r=t.settings,s=r.perView,o=r.classes,a=r.cloningRatio;if(0!==i.length)for(var u=s+ +!!t.settings.peek+Math.round(s/2),c=i.slice(0,u).reverse(),l=i.slice(-1*u),f=0;f<Math.max(a,Math.floor(s/i.length));f++){for(var d=0;d<c.length;d++){var h=c[d].cloneNode(!0);h.classList.add(o.slide.clone),n.push(h)}for(var v=0;v<l.length;v++){var p=l[v].cloneNode(!0);p.classList.add(o.slide.clone),n.unshift(p)}}return n},append:function(){for(var t=this.items,n=e.Html,i=n.wrapper,r=n.slides,s=Math.floor(t.length/2),o=t.slice(0,s).reverse(),a=t.slice(-1*s).reverse(),u="".concat(e.Sizes.slideWidth,"px"),c=0;c<a.length;c++)i.appendChild(a[c]);for(var l=0;l<o.length;l++)i.insertBefore(o[l],r[0]);for(var f=0;f<t.length;f++)t[f].style.width=u},remove:function(){for(var t=this.items,n=0;n<t.length;n++)e.Html.wrapper.removeChild(t[n])}};return g(i,"grow",{get:function(){return(e.Sizes.slideWidth+e.Gaps.value)*i.items.length}}),n.on("update",(function(){i.remove(),i.mount(),i.append()})),n.on("build.before",(function(){t.isType("carousel")&&i.append()})),n.on("destroy",(function(){i.remove()})),i},Resize:function(t,e,n){var i=new H,r={mount:function(){this.bind()},bind:function(){i.on("resize",window,_((function(){n.emit("resize")}),t.settings.throttle))},unbind:function(){i.off("resize",window)}};return n.on("destroy",(function(){r.unbind(),i.destroy()})),r},Build:function(t,e,n){var i={mount:function(){n.emit("build.before"),this.typeClass(),this.activeClass(),n.emit("build.after")},typeClass:function(){e.Html.root.classList.add(t.settings.classes.type[t.settings.type])},activeClass:function(){var n=t.settings.classes,i=e.Html.slides[t.index];i&&(i.classList.add(n.slide.active),k(i).forEach((function(t){t.classList.remove(n.slide.active)})))},removeClasses:function(){var n=t.settings.classes,i=n.type,r=n.slide;e.Html.root.classList.remove(i[t.settings.type]),e.Html.slides.forEach((function(t){t.classList.remove(r.active)}))}};return n.on(["destroy","update"],(function(){i.removeClasses()})),n.on(["resize","update"],(function(){i.mount()})),n.on("move.after",(function(){i.activeClass()})),i},Run:function(t,e,n){var i={mount:function(){this._o=!1},make:function(i){var r=this;t.disabled||(!t.settings.waitForTransition||t.disable(),this.move=i,n.emit("run.before",this.move),this.calculate(),n.emit("run",this.move),e.Transition.after((function(){r.isStart()&&n.emit("run.start",r.move),r.isEnd()&&n.emit("run.end",r.move),r.isOffset()&&(r._o=!1,n.emit("run.offset",r.move)),n.emit("run.after",r.move),t.enable()})))},calculate:function(){var e=this.move,n=this.length,r=e.steps,s=e.direction,o=1;if("="===s)return t.settings.bound&&f(r)>n?void(t.index=n):void(t.index=r);if(">"!==s||">"!==r)if("<"!==s||"<"!==r){if("|"===s&&(o=t.settings.perView||1),">"===s||"|"===s&&">"===r){var a=function(e){var n=t.index;if(t.isType("carousel"))return n+e;return n+(e-n%e)}(o);return a>n&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e<=r)return e;if(t.isType("carousel"))return e-(r+1);if(t.settings.rewind)return i.isBound()&&!i.isEnd()?r:0;if(i.isBound())return r;return Math.floor(r/n)*n}(a,o))}if("<"===s||"|"===s&&"<"===r){var u=function(e){var n=t.index;if(t.isType("carousel"))return n-e;var i=Math.ceil(n/e);return(i-1)*e}(o);return u<0&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e>=0)return e;if(t.isType("carousel"))return e+(r+1);if(t.settings.rewind)return i.isBound()&&i.isStart()?r:Math.floor(r/n)*n;return 0}(u,o))}l("Invalid direction pattern [".concat(s).concat(r,"] has been used"))}else t.index=0;else t.index=n},isStart:function(){return t.index<=0},isEnd:function(){return t.index>=this.length},isOffset:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return t?!!this._o&&("|>"===t?"|"===this.move.direction&&">"===this.move.steps:"|<"===t?"|"===this.move.direction&&"<"===this.move.steps:this.move.direction===t):this._o},isBound:function(){return t.isType("slider")&&"center"!==t.settings.focusAt&&t.settings.bound}};return g(i,"move",{get:function(){return this._m},set:function(t){var e=t.substr(1);this._m={direction:t.substr(0,1),steps:e?f(e)?f(e):e:0}}}),g(i,"length",{get:function(){var n=t.settings,i=e.Html.slides.length;return this.isBound()?i-1-(f(n.perView)-1)+f(n.focusAt):i-1}}),g(i,"offset",{get:function(){return this._o}}),i}},K=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&s(t,e)}(o,t);var n=a(o);function o(){return e(this,o),n.apply(this,arguments)}return i(o,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return u(r(o.prototype),"mount",this).call(this,Object.assign({},J,t))}}]),o}(y);const Q="glide__arrow--left",U="glide__arrow--right";function Z(t,e){return{mount(){t.settings.rewind||(t.on(["mount.after","resize"],(()=>{e.Sizes.length<=t.settings.perView?t.disable():t.enable()})),t.on(["mount.after","run","resize"],(()=>{e.Controls.items.forEach((n=>{const i=n.querySelector(`.${Q}`);i&&(0===t.index||e.Sizes.length<=t.settings.perView?i.setAttribute("disabled",""):i.removeAttribute("disabled"));const r=n.querySelector(`.${U}`);if(r){(t.settings.bound?t.index+(t.settings.perView-1):t.index)===e.Sizes.length-1||e.Sizes.length<=t.settings.perView?r.setAttribute("disabled",""):r.removeAttribute("disabled")}i.disabled&&r.disabled?n.classList.add("glide__arrows--disabled"):n.classList.remove("glide__arrows--disabled")}))})))}}}((t,e)=>{t.behaviors.glide={attach(t){e("glide",".carousel .glide",t).forEach((t=>{const e=new K(t,{rewind:!1,bound:!0,dragThreshold:!1,gap:16,perView:4,breakpoints:{9999:{perView:4},1199:{perView:3},767:{perView:2},575:{perView:1}}});let n;const i=t=>{t.settings.perView!==t.previousPerView&&(t.previousPerView=t.settings.perView,t.enable().go("<<").disable())};e.on("resize",(()=>{n&&clearTimeout(n),n=setTimeout(i,50,e)})),e.mount({Controls:Y,Breakpoints:$,Swipe:G,ControlsDisabler:Z}),e.previousPerView=e.settings.perView;const r=t.querySelector(".glide__arrow--right"),s=t.querySelector(".glide__arrow--left");r.addEventListener("click",(()=>{e.go(">")})),s.addEventListener("click",(()=>{e.go("<")})),e.on("run",(()=>{t.classList.add("glide-animating")})).on("run.after",(()=>{t.classList.remove("glide-animating")}))}))}}})(Drupal,once)})); //# sourceMappingURL=carousel.min.js.map diff --git a/web/themes/ventuno/assets/js/explore-block.min.js b/web/themes/ventuno/assets/js/explore-block.min.js index a22a910688..c8a4e3d47e 100644 --- a/web/themes/ventuno/assets/js/explore-block.min.js +++ b/web/themes/ventuno/assets/js/explore-block.min.js @@ -1,7 +1,7 @@ !function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict"; /*! - * Glide.js v3.6.2 - * (c) 2013-2024 Jędrzej Chałubek (https://github.com/jedrzejchalubek/) + * Glide.js v3.6.0 + * (c) 2013-2022 Jędrzej Chałubek (https://github.com/jedrzejchalubek/) * Released under the MIT License. - */function t(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function e(e){for(var n=1;n<arguments.length;n++){var i=null!=arguments[n]?arguments[n]:{};n%2?t(Object(i),!0).forEach((function(t){s(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):t(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&r(t.prototype,e),n&&r(t,n),t}function s(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(t){return a=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},a(t)}function u(t,e){return u=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},u(t,e)}function c(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function l(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=a(t);if(e){var r=a(this).constructor;n=Reflect.construct(i,arguments,r)}else n=i.apply(this,arguments);return c(this,n)}}function f(){return f="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=a(t)););return t}(t,e);if(i){var r=Object.getOwnPropertyDescriptor(i,e);return r.get?r.get.call(arguments.length<3?t:n):r.value}},f.apply(this,arguments)}var d={type:"slider",startAt:0,perView:1,focusAt:0,gap:10,autoplay:!1,hoverpause:!0,keyboard:!0,bound:!1,swipeThreshold:80,dragThreshold:120,perSwipe:"",touchRatio:.5,touchAngle:45,animationDuration:400,rewind:!0,rewindDuration:800,animationTimingFunc:"cubic-bezier(.165, .840, .440, 1)",waitForTransition:!0,throttle:10,direction:"ltr",peek:0,cloningRatio:1,breakpoints:{},classes:{swipeable:"glide--swipeable",dragging:"glide--dragging",direction:{ltr:"glide--ltr",rtl:"glide--rtl"},type:{slider:"glide--slider",carousel:"glide--carousel"},slide:{clone:"glide__slide--clone",active:"glide__slide--active"},arrow:{disabled:"glide__arrow--disabled"},nav:{active:"glide__bullet--active"}}};function h(t){console.error("[Glide warn]: ".concat(t))}function v(t){return parseInt(t)}function p(t){return"string"==typeof t}function m(t){var e=n(t);return"function"===e||"object"===e&&!!t}function g(t){return"function"==typeof t}function b(t){return t.constructor===Array}function y(t,e,n){Object.defineProperty(t,e,n)}function w(t,n){var i=Object.assign({},t,n);if(n.hasOwnProperty("classes")){i.classes=Object.assign({},t.classes,n.classes);["direction","type","slide","arrow","nav"].forEach((function(r){n.classes.hasOwnProperty(r)&&(i.classes[r]=e(e({},t.classes[r]),n.classes[r]))}))}return n.hasOwnProperty("breakpoints")&&(i.breakpoints=Object.assign({},t.breakpoints,n.breakpoints)),i}var _=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,t),this.events=e,this.hop=e.hasOwnProperty}return o(t,[{key:"on",value:function(t,e){if(!b(t)){this.hop.call(this.events,t)||(this.events[t]=[]);var n=this.events[t].push(e)-1;return{remove:function(){delete this.events[t][n]}}}for(var i=0;i<t.length;i++)this.on(t[i],e)}},{key:"emit",value:function(t,e){if(b(t))for(var n=0;n<t.length;n++)this.emit(t[n],e);else this.hop.call(this.events,t)&&this.events[t].forEach((function(t){t(e||{})}))}}]),t}(),S=function(){function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};i(this,t),this._c={},this._t=[],this._e=new _,this.disabled=!1,this.selector=e,this.settings=w(d,n),this.index=this.settings.startAt}return o(t,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this._e.emit("mount.before"),m(t)?this._c=function(t,e,n){var i={};for(var r in e)g(e[r])?i[r]=e[r](t,i,n):h("Extension must be a function");for(var o in i)g(i[o].mount)&&i[o].mount();return i}(this,t,this._e):h("You need to provide a object on `mount()`"),this._e.emit("mount.after"),this}},{key:"mutate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return b(t)?this._t=t:h("You need to provide a array on `mutate()`"),this}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.settings=w(this.settings,t),t.hasOwnProperty("startAt")&&(this.index=t.startAt),this._e.emit("update"),this}},{key:"go",value:function(t){return this._c.Run.make(t),this}},{key:"move",value:function(t){return this._c.Transition.disable(),this._c.Move.make(t),this}},{key:"destroy",value:function(){return this._e.emit("destroy"),this}},{key:"play",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return t&&(this.settings.autoplay=t),this._e.emit("play"),this}},{key:"pause",value:function(){return this._e.emit("pause"),this}},{key:"disable",value:function(){return this.disabled=!0,this}},{key:"enable",value:function(){return this.disabled=!1,this}},{key:"on",value:function(t,e){return this._e.on(t,e),this}},{key:"isType",value:function(t){return this.settings.type===t}},{key:"settings",get:function(){return this._o},set:function(t){m(t)?this._o=t:h("Options must be an `object` instance.")}},{key:"index",get:function(){return this._i},set:function(t){this._i=v(t)}},{key:"type",get:function(){return this.settings.type}},{key:"disabled",get:function(){return this._d},set:function(t){this._d=!!t}}]),t}();function k(){return(new Date).getTime()}function O(t,e){var n,i,r,o,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=0,u=function(){a=!1===s.leading?0:k(),n=null,o=t.apply(i,r),n||(i=r=null)},c=function(){var c=k();a||!1!==s.leading||(a=c);var l=e-(c-a);return i=this,r=arguments,l<=0||l>e?(n&&(clearTimeout(n),n=null),a=c,o=t.apply(i,r),n||(i=r=null)):n||!1===s.trailing||(n=setTimeout(u,l)),o};return c.cancel=function(){clearTimeout(n),a=0,n=i=r=null},c}var x={ltr:["marginLeft","marginRight"],rtl:["marginRight","marginLeft"]};function T(t){if(t&&t.parentNode){for(var e=t.parentNode.firstChild,n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}return[]}function H(t){return Array.prototype.slice.call(t)}var j=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,t),this.listeners=e}return o(t,[{key:"on",value:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];p(t)&&(t=[t]);for(var r=0;r<t.length;r++)this.listeners[t[r]]=n,e.addEventListener(t[r],this.listeners[t[r]],i)}},{key:"off",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];p(t)&&(t=[t]);for(var i=0;i<t.length;i++)e.removeEventListener(t[i],this.listeners[t[i]],n)}},{key:"destroy",value:function(){delete this.listeners}}]),t}();var A=["ltr","rtl"],P={">":"<","<":">","=":"="};function z(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}function E(t,e){return{modify:function(t){var n=Math.floor(t/e.Sizes.slideWidth);return t+e.Gaps.value*n}}}function R(t,e){return{modify:function(t){return t+e.Clones.grow/2}}}function C(t,e){return{modify:function(n){if(t.settings.focusAt>=0){var i=e.Peek.value;return m(i)?n-i.before:n-i}return n}}}function L(t,e){return{modify:function(n){var i=e.Gaps.value,r=e.Sizes.width,o=t.settings.focusAt,s=e.Sizes.slideWidth;return"center"===o?n-(r/2-s/2):n-s*o-i*o}}}var M=!1;try{var D=Object.defineProperty({},"passive",{get:function(){M=!0}});window.addEventListener("testPassive",null,D),window.removeEventListener("testPassive",null,D)}catch(t){}var V=M,W=["touchstart","mousedown"],B=["touchmove","mousemove"],q=["touchend","touchcancel","mouseup","mouseleave"],G=["mousedown","mousemove","mouseup","mouseleave"];function F(t,e,n){var i=new j,r=0,o=0,s=0,a=!1,u=!!V&&{passive:!0},c={mount:function(){this.bindSwipeStart()},start:function(e){if(!a&&!t.disabled){this.disable();var i=this.touches(e);r=null,o=v(i.pageX),s=v(i.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),n.emit("swipe.start")}},move:function(i){if(!t.disabled){var a=t.settings,u=a.touchAngle,c=a.touchRatio,l=a.classes,f=this.touches(i),d=v(f.pageX)-o,h=v(f.pageY)-s,p=Math.abs(d<<2),m=Math.abs(h<<2),g=Math.sqrt(p+m),b=Math.sqrt(m);if(!(180*(r=Math.asin(b/g))/Math.PI<u))return!1;i.stopPropagation(),e.Move.make(d*parseFloat(c)),e.Html.root.classList.add(l.dragging),n.emit("swipe.move")}},end:function(i){if(!t.disabled){var s=t.settings,a=s.perSwipe,u=s.touchAngle,c=s.classes,l=this.touches(i),f=this.threshold(i),d=l.pageX-o,h=180*r/Math.PI;this.enable(),d>f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,"<"))):d<-f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,">"))):e.Move.make(),e.Html.root.classList.remove(c.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),n.emit("swipe.end")}},bindSwipeStart:function(){var n=this,r=t.settings,o=r.swipeThreshold,s=r.dragThreshold;o&&i.on(W[0],e.Html.wrapper,(function(t){n.start(t)}),u),s&&i.on(W[1],e.Html.wrapper,(function(t){n.start(t)}),u)},unbindSwipeStart:function(){i.off(W[0],e.Html.wrapper,u),i.off(W[1],e.Html.wrapper,u)},bindSwipeMove:function(){var n=this;i.on(B,e.Html.wrapper,O((function(t){n.move(t)}),t.settings.throttle),u)},unbindSwipeMove:function(){i.off(B,e.Html.wrapper,u)},bindSwipeEnd:function(){var t=this;i.on(q,e.Html.wrapper,(function(e){t.end(e)}))},unbindSwipeEnd:function(){i.off(q,e.Html.wrapper)},touches:function(t){return G.indexOf(t.type)>-1?t:t.touches[0]||t.changedTouches[0]},threshold:function(e){var n=t.settings;return G.indexOf(e.type)>-1?n.dragThreshold:n.swipeThreshold},enable:function(){return a=!1,e.Transition.enable(),this},disable:function(){return a=!0,e.Transition.disable(),this}};return n.on("build.after",(function(){e.Html.root.classList.add(t.settings.classes.swipeable)})),n.on("destroy",(function(){c.unbindSwipeStart(),c.unbindSwipeMove(),c.unbindSwipeEnd(),i.destroy()})),c}var I='[data-glide-el^="controls"]',N="".concat(I,' [data-glide-dir*="<"]'),Y="".concat(I,' [data-glide-dir*=">"]');function X(t,e,n){var i=new j,r=!!V&&{passive:!0},o={mount:function(){this._n=e.Html.root.querySelectorAll('[data-glide-el="controls[nav]"]'),this._c=e.Html.root.querySelectorAll(I),this._arrowControls={previous:e.Html.root.querySelectorAll(N),next:e.Html.root.querySelectorAll(Y)},this.addBindings()},setActive:function(){for(var t=0;t<this._n.length;t++)this.addClass(this._n[t].children)},removeActive:function(){for(var t=0;t<this._n.length;t++)this.removeClass(this._n[t].children)},addClass:function(e){var n=t.settings,i=e[t.index];i&&(i.classList.add(n.classes.nav.active),T(i).forEach((function(t){t.classList.remove(n.classes.nav.active)})))},removeClass:function(e){var n=e[t.index];null==n||n.classList.remove(t.settings.classes.nav.active)},setArrowState:function(){if(!t.settings.rewind){var n=o._arrowControls.next,i=o._arrowControls.previous;this.resetArrowState(n,i),0===t.index&&this.disableArrow(i),t.index===e.Run.length&&this.disableArrow(n)}},resetArrowState:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){H(t).forEach((function(t){t.classList.remove(e.classes.arrow.disabled)}))}))},disableArrow:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){H(t).forEach((function(t){t.classList.add(e.classes.arrow.disabled)}))}))},addBindings:function(){for(var t=0;t<this._c.length;t++)this.bind(this._c[t].children)},removeBindings:function(){for(var t=0;t<this._c.length;t++)this.unbind(this._c[t].children)},bind:function(t){for(var e=0;e<t.length;e++)i.on("click",t[e],this.click),i.on("touchstart",t[e],this.click,r)},unbind:function(t){for(var e=0;e<t.length;e++)i.off(["click","touchstart"],t[e])},click:function(t){V||"touchstart"!==t.type||t.preventDefault();var n=t.currentTarget.getAttribute("data-glide-dir");e.Run.make(e.Direction.resolve(n))}};return y(o,"items",{get:function(){return o._c}}),n.on(["mount.after","move.after"],(function(){o.setActive()})),n.on(["mount.after","run"],(function(){o.setArrowState()})),n.on("destroy",(function(){o.removeBindings(),o.removeActive(),i.destroy()})),o}function $(t){return m(t)?(e=t,Object.keys(e).sort().reduce((function(t,n){return t[n]=e[n],t[n],t}),{})):(h("Breakpoints option must be an object"),{});var e}function J(t,e,n){var i=new j,r=t.settings,o=$(r.breakpoints),s=Object.assign({},r),a={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: ".concat(e,"px)")).matches)return t[e];return s}};return Object.assign(r,a.match(o)),i.on("resize",window,O((function(){t.settings=w(r,a.match(o))}),t.settings.throttle)),n.on("update",(function(){o=$(o),s=Object.assign({},r)})),n.on("destroy",(function(){i.off("resize",window)})),a}var K={Html:function(t,e,n){var i={mount:function(){this.root=t.selector,this.track=this.root.querySelector('[data-glide-el="track"]'),this.collectSlides()},collectSlides:function(){this.slides=H(this.wrapper.children).filter((function(e){return!e.classList.contains(t.settings.classes.slide.clone)}))}};return y(i,"root",{get:function(){return i._r},set:function(t){p(t)&&(t=document.querySelector(t)),null!==t?i._r=t:h("Root element must be a existing Html node")}}),y(i,"track",{get:function(){return i._t},set:function(t){i._t=t}}),y(i,"wrapper",{get:function(){return i.track.children[0]}}),n.on("update",(function(){i.collectSlides()})),i},Translate:function(t,e,n){var i={set:function(n){var i=function(t,e,n){var i=[E,R,C,L].concat(t._t,[z]);return{mutate:function(r){for(var o=0;o<i.length;o++){var s=i[o];g(s)&&g(s().modify)?r=s(t,e,n).modify(r):h("Transformer should be a function that returns an object with `modify()` method")}return r}}}(t,e).mutate(n),r="translate3d(".concat(-1*i,"px, 0px, 0px)");e.Html.wrapper.style.mozTransform=r,e.Html.wrapper.style.webkitTransform=r,e.Html.wrapper.style.transform=r},remove:function(){e.Html.wrapper.style.transform=""},getStartIndex:function(){var n=e.Sizes.length,i=t.index,r=t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?n+(i-r):(i+r)%n},getTravelDistance:function(){var n=e.Sizes.slideWidth*t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?-1*n:n}};return n.on("move",(function(r){if(!t.isType("carousel")||!e.Run.isOffset())return i.set(r.movement);e.Transition.after((function(){n.emit("translate.jump"),i.set(e.Sizes.slideWidth*t.index)}));var o=e.Sizes.slideWidth*e.Translate.getStartIndex();return i.set(o-e.Translate.getTravelDistance())})),n.on("destroy",(function(){i.remove()})),i},Transition:function(t,e,n){var i=!1,r={compose:function(e){var n=t.settings;return i?"".concat(e," 0ms ").concat(n.animationTimingFunc):"".concat(e," ").concat(this.duration,"ms ").concat(n.animationTimingFunc)},set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"transform";e.Html.wrapper.style.transition=this.compose(t)},remove:function(){e.Html.wrapper.style.transition=""},after:function(t){setTimeout((function(){t()}),this.duration)},enable:function(){i=!1,this.set()},disable:function(){i=!0,this.set()}};return y(r,"duration",{get:function(){var n=t.settings;return t.isType("slider")&&e.Run.offset?n.rewindDuration:n.animationDuration}}),n.on("move",(function(){r.set()})),n.on(["build.before","resize","translate.jump"],(function(){r.disable()})),n.on("run",(function(){r.enable()})),n.on("destroy",(function(){r.remove()})),r},Direction:function(t,e,n){var i={mount:function(){this.value=t.settings.direction},resolve:function(t){var e=t.slice(0,1);return this.is("rtl")?t.split(e).join(P[e]):t},is:function(t){return this.value===t},addClass:function(){e.Html.root.classList.add(t.settings.classes.direction[this.value])},removeClass:function(){e.Html.root.classList.remove(t.settings.classes.direction[this.value])}};return y(i,"value",{get:function(){return i._v},set:function(t){A.indexOf(t)>-1?i._v=t:h("Direction value must be `ltr` or `rtl`")}}),n.on(["destroy","update"],(function(){i.removeClass()})),n.on("update",(function(){i.mount()})),n.on(["build.before","update"],(function(){i.addClass()})),i},Peek:function(t,e,n){var i={mount:function(){this.value=t.settings.peek}};return y(i,"value",{get:function(){return i._v},set:function(t){m(t)?(t.before=v(t.before),t.after=v(t.after)):t=v(t),i._v=t}}),y(i,"reductor",{get:function(){var e=i.value,n=t.settings.perView;return m(e)?e.before/n+e.after/n:2*e/n}}),n.on(["resize","update"],(function(){i.mount()})),i},Sizes:function(t,e,n){var i={setupSlides:function(){for(var t="".concat(this.slideWidth,"px"),n=e.Html.slides,i=0;i<n.length;i++)n[i].style.width=t},setupWrapper:function(){e.Html.wrapper.style.width="".concat(this.wrapperSize,"px")},remove:function(){for(var t=e.Html.slides,n=0;n<t.length;n++)t[n].style.width="";e.Html.wrapper.style.width=""}};return y(i,"length",{get:function(){return e.Html.slides.length}}),y(i,"width",{get:function(){return e.Html.track.offsetWidth}}),y(i,"wrapperSize",{get:function(){return i.slideWidth*i.length+e.Gaps.grow+e.Clones.grow}}),y(i,"slideWidth",{get:function(){return i.width/t.settings.perView-e.Peek.reductor-e.Gaps.reductor}}),n.on(["build.before","resize","update"],(function(){i.setupSlides(),i.setupWrapper()})),n.on("destroy",(function(){i.remove()})),i},Gaps:function(t,e,n){var i={apply:function(t){for(var n=0,i=t.length;n<i;n++){var r=t[n].style,o=e.Direction.value;r[x[o][0]]=0!==n?"".concat(this.value/2,"px"):"",n!==t.length-1?r[x[o][1]]="".concat(this.value/2,"px"):r[x[o][1]]=""}},remove:function(t){for(var e=0,n=t.length;e<n;e++){var i=t[e].style;i.marginLeft="",i.marginRight=""}}};return y(i,"value",{get:function(){return v(t.settings.gap)}}),y(i,"grow",{get:function(){return i.value*e.Sizes.length}}),y(i,"reductor",{get:function(){var e=t.settings.perView;return i.value*(e-1)/e}}),n.on(["build.after","update"],O((function(){i.apply(e.Html.wrapper.children)}),30)),n.on("destroy",(function(){i.remove(e.Html.wrapper.children)})),i},Move:function(t,e,n){var i={mount:function(){this._o=0},make:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.offset=i,n.emit("move",{movement:this.value}),e.Transition.after((function(){n.emit("move.after",{movement:t.value})}))}};return y(i,"offset",{get:function(){return i._o},set:function(t){i._o=function(t){return void 0===t}(t)?0:v(t)}}),y(i,"translate",{get:function(){return e.Sizes.slideWidth*t.index}}),y(i,"value",{get:function(){var t=this.offset,n=this.translate;return e.Direction.is("rtl")?n+t:n-t}}),n.on(["build.before","run"],(function(){i.make()})),i},Clones:function(t,e,n){var i={mount:function(){this.items=[],t.isType("carousel")&&(this.items=this.collect())},collect:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=e.Html.slides,r=t.settings,o=r.perView,s=r.classes,a=r.cloningRatio;if(i.length>0)for(var u=o+ +!!t.settings.peek+Math.round(o/2),c=i.slice(0,u).reverse(),l=i.slice(-1*u),f=0;f<Math.max(a,Math.floor(o/i.length));f++){for(var d=0;d<c.length;d++){var h=c[d].cloneNode(!0);h.classList.add(s.slide.clone),n.push(h)}for(var v=0;v<l.length;v++){var p=l[v].cloneNode(!0);p.classList.add(s.slide.clone),n.unshift(p)}}return n},append:function(){for(var t=this.items,n=e.Html,i=n.wrapper,r=n.slides,o=Math.floor(t.length/2),s=t.slice(0,o).reverse(),a=t.slice(-1*o).reverse(),u="".concat(e.Sizes.slideWidth,"px"),c=0;c<a.length;c++)i.appendChild(a[c]);for(var l=0;l<s.length;l++)i.insertBefore(s[l],r[0]);for(var f=0;f<t.length;f++)t[f].style.width=u},remove:function(){for(var t=this.items,n=0;n<t.length;n++)e.Html.wrapper.removeChild(t[n])}};return y(i,"grow",{get:function(){return(e.Sizes.slideWidth+e.Gaps.value)*i.items.length}}),n.on("update",(function(){i.remove(),i.mount(),i.append()})),n.on("build.before",(function(){t.isType("carousel")&&i.append()})),n.on("destroy",(function(){i.remove()})),i},Resize:function(t,e,n){var i=new j,r={mount:function(){this.bind()},bind:function(){i.on("resize",window,O((function(){n.emit("resize")}),t.settings.throttle))},unbind:function(){i.off("resize",window)}};return n.on("destroy",(function(){r.unbind(),i.destroy()})),r},Build:function(t,e,n){var i={mount:function(){n.emit("build.before"),this.typeClass(),this.activeClass(),n.emit("build.after")},typeClass:function(){e.Html.root.classList.add(t.settings.classes.type[t.settings.type])},activeClass:function(){var n=t.settings.classes,i=e.Html.slides[t.index];i&&(i.classList.add(n.slide.active),T(i).forEach((function(t){t.classList.remove(n.slide.active)})))},removeClasses:function(){var n=t.settings.classes,i=n.type,r=n.slide;e.Html.root.classList.remove(i[t.settings.type]),e.Html.slides.forEach((function(t){t.classList.remove(r.active)}))}};return n.on(["destroy","update"],(function(){i.removeClasses()})),n.on(["resize","update"],(function(){i.mount()})),n.on("move.after",(function(){i.activeClass()})),i},Run:function(t,e,n){var i={mount:function(){this._o=!1},make:function(i){var r=this;t.disabled||(!t.settings.waitForTransition||t.disable(),this.move=i,n.emit("run.before",this.move),this.calculate(),n.emit("run",this.move),e.Transition.after((function(){r.isStart()&&n.emit("run.start",r.move),r.isEnd()&&n.emit("run.end",r.move),r.isOffset()&&(r._o=!1,n.emit("run.offset",r.move)),n.emit("run.after",r.move),t.enable()})))},calculate:function(){var e=this.move,n=this.length,r=e.steps,o=e.direction,s=1;if("="===o)return t.settings.bound&&v(r)>n?void(t.index=n):void(t.index=r);if(">"!==o||">"!==r)if("<"!==o||"<"!==r){if("|"===o&&(s=t.settings.perView||1),">"===o||"|"===o&&">"===r){var a=function(e){var n=t.index;if(t.isType("carousel"))return n+e;return n+(e-n%e)}(s);return a>n&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e<=r)return e;if(t.isType("carousel"))return e-(r+1);if(t.settings.rewind)return i.isBound()&&!i.isEnd()?r:0;if(i.isBound())return r;return Math.floor(r/n)*n}(a,s))}if("<"===o||"|"===o&&"<"===r){var u=function(e){var n=t.index;if(t.isType("carousel"))return n-e;var i=Math.ceil(n/e);return(i-1)*e}(s);return u<0&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e>=0)return e;if(t.isType("carousel"))return e+(r+1);if(t.settings.rewind)return i.isBound()&&i.isStart()?r:Math.floor(r/n)*n;return 0}(u,s))}h("Invalid direction pattern [".concat(o).concat(r,"] has been used"))}else t.index=0;else t.index=n},isStart:function(){return t.index<=0},isEnd:function(){return t.index>=this.length},isOffset:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return t?!!this._o&&("|>"===t?"|"===this.move.direction&&">"===this.move.steps:"|<"===t?"|"===this.move.direction&&"<"===this.move.steps:this.move.direction===t):this._o},isBound:function(){return t.isType("slider")&&"center"!==t.settings.focusAt&&t.settings.bound}};return y(i,"move",{get:function(){return this._m},set:function(t){var e=t.substr(1);this._m={direction:t.substr(0,1),steps:e?v(e)?v(e):e:0}}}),y(i,"length",{get:function(){var n=t.settings,i=e.Html.slides.length;return this.isBound()?i-1-(v(n.perView)-1)+v(n.focusAt):i-1}}),y(i,"offset",{get:function(){return this._o}}),i}},Q=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&u(t,e)}(n,t);var e=l(n);function n(){return i(this,n),e.apply(this,arguments)}return o(n,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return f(a(n.prototype),"mount",this).call(this,Object.assign({},K,t))}}]),n}(S);const U="glide__arrow--left",Z="glide__arrow--right";function tt(t,e){return{mount(){t.settings.rewind||(t.on(["mount.after","resize"],(()=>{e.Sizes.length<=t.settings.perView?t.disable():t.enable()})),t.on(["mount.after","run","resize"],(()=>{e.Controls.items.forEach((n=>{const i=n.querySelector(`.${U}`);i&&(0===t.index||e.Sizes.length<=t.settings.perView?i.setAttribute("disabled",""):i.removeAttribute("disabled"));const r=n.querySelector(`.${Z}`);if(r){(t.settings.bound?t.index+(t.settings.perView-1):t.index)===e.Sizes.length-1||e.Sizes.length<=t.settings.perView?r.setAttribute("disabled",""):r.removeAttribute("disabled")}i.disabled&&r.disabled?n.classList.add("glide__arrows--disabled"):n.classList.remove("glide__arrows--disabled")}))})))}}}Drupal.behaviors.glide={attach(){const t=document.querySelectorAll(".explore-block button.nav-link");function e(){document.querySelectorAll(".tab-pane.active .glide").forEach((t=>{new Q(t,{rewind:!1,bound:!0,dragThreshold:!1,gap:24,perView:4,wrapperWidth:300,breakpoints:{1199:{perView:3},991:{perView:2},767:{perView:1}}}).mount({Controls:X,Breakpoints:J,Swipe:F,ControlsDisabler:tt}).update({wrapperWidth:300})}))}for(let n=0;n<t.length;n++)t[n].addEventListener("click",(()=>{e()}));e()}}})); + */function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function r(t){return r=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},r(t)}function s(t,e){return s=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},s(t,e)}function o(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function a(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=r(t);if(e){var s=r(this).constructor;n=Reflect.construct(i,arguments,s)}else n=i.apply(this,arguments);return o(this,n)}}function u(){return u="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=r(t)););return t}(t,e);if(i){var s=Object.getOwnPropertyDescriptor(i,e);return s.get?s.get.call(arguments.length<3?t:n):s.value}},u.apply(this,arguments)}var c={type:"slider",startAt:0,perView:1,focusAt:0,gap:10,autoplay:!1,hoverpause:!0,keyboard:!0,bound:!1,swipeThreshold:80,dragThreshold:120,perSwipe:"",touchRatio:.5,touchAngle:45,animationDuration:400,rewind:!0,rewindDuration:800,animationTimingFunc:"cubic-bezier(.165, .840, .440, 1)",waitForTransition:!0,throttle:10,direction:"ltr",peek:0,cloningRatio:1,breakpoints:{},classes:{swipeable:"glide--swipeable",dragging:"glide--dragging",direction:{ltr:"glide--ltr",rtl:"glide--rtl"},type:{slider:"glide--slider",carousel:"glide--carousel"},slide:{clone:"glide__slide--clone",active:"glide__slide--active"},arrow:{disabled:"glide__arrow--disabled"},nav:{active:"glide__bullet--active"}}};function l(t){console.error("[Glide warn]: ".concat(t))}function f(t){return parseInt(t)}function d(t){return"string"==typeof t}function h(e){var n=t(e);return"function"===n||"object"===n&&!!e}function v(t){return"function"==typeof t}function p(t){return t.constructor===Array}function m(t,e,n){Object.defineProperty(t,e,n)}function g(t,e){var n=Object.assign({},t,e);return e.hasOwnProperty("classes")&&(n.classes=Object.assign({},t.classes,e.classes),e.classes.hasOwnProperty("direction")&&(n.classes.direction=Object.assign({},t.classes.direction,e.classes.direction)),e.classes.hasOwnProperty("type")&&(n.classes.type=Object.assign({},t.classes.type,e.classes.type)),e.classes.hasOwnProperty("slide")&&(n.classes.slide=Object.assign({},t.classes.slide,e.classes.slide)),e.classes.hasOwnProperty("arrow")&&(n.classes.arrow=Object.assign({},t.classes.arrow,e.classes.arrow)),e.classes.hasOwnProperty("nav")&&(n.classes.nav=Object.assign({},t.classes.nav,e.classes.nav))),e.hasOwnProperty("breakpoints")&&(n.breakpoints=Object.assign({},t.breakpoints,e.breakpoints)),n}var y=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.events=n,this.hop=n.hasOwnProperty}return i(t,[{key:"on",value:function(t,e){if(!p(t)){this.hop.call(this.events,t)||(this.events[t]=[]);var n=this.events[t].push(e)-1;return{remove:function(){delete this.events[t][n]}}}for(var i=0;i<t.length;i++)this.on(t[i],e)}},{key:"emit",value:function(t,e){if(p(t))for(var n=0;n<t.length;n++)this.emit(t[n],e);else this.hop.call(this.events,t)&&this.events[t].forEach((function(t){t(e||{})}))}}]),t}(),b=function(){function t(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,t),this._c={},this._t=[],this._e=new y,this.disabled=!1,this.selector=n,this.settings=g(c,i),this.index=this.settings.startAt}return i(t,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this._e.emit("mount.before"),h(t)?this._c=function(t,e,n){var i={};for(var r in e)v(e[r])?i[r]=e[r](t,i,n):l("Extension must be a function");for(var s in i)v(i[s].mount)&&i[s].mount();return i}(this,t,this._e):l("You need to provide a object on `mount()`"),this._e.emit("mount.after"),this}},{key:"mutate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return p(t)?this._t=t:l("You need to provide a array on `mutate()`"),this}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.settings=g(this.settings,t),t.hasOwnProperty("startAt")&&(this.index=t.startAt),this._e.emit("update"),this}},{key:"go",value:function(t){return this._c.Run.make(t),this}},{key:"move",value:function(t){return this._c.Transition.disable(),this._c.Move.make(t),this}},{key:"destroy",value:function(){return this._e.emit("destroy"),this}},{key:"play",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return t&&(this.settings.autoplay=t),this._e.emit("play"),this}},{key:"pause",value:function(){return this._e.emit("pause"),this}},{key:"disable",value:function(){return this.disabled=!0,this}},{key:"enable",value:function(){return this.disabled=!1,this}},{key:"on",value:function(t,e){return this._e.on(t,e),this}},{key:"isType",value:function(t){return this.settings.type===t}},{key:"settings",get:function(){return this._o},set:function(t){h(t)?this._o=t:l("Options must be an `object` instance.")}},{key:"index",get:function(){return this._i},set:function(t){this._i=f(t)}},{key:"type",get:function(){return this.settings.type}},{key:"disabled",get:function(){return this._d},set:function(t){this._d=!!t}}]),t}();function w(){return(new Date).getTime()}function _(t,e,n){var i,r,s,o,a=0;n||(n={});var u=function(){a=!1===n.leading?0:w(),i=null,o=t.apply(r,s),i||(r=s=null)},c=function(){var c=w();a||!1!==n.leading||(a=c);var l=e-(c-a);return r=this,s=arguments,l<=0||l>e?(i&&(clearTimeout(i),i=null),a=c,o=t.apply(r,s),i||(r=s=null)):i||!1===n.trailing||(i=setTimeout(u,l)),o};return c.cancel=function(){clearTimeout(i),a=0,i=r=s=null},c}var S={ltr:["marginLeft","marginRight"],rtl:["marginRight","marginLeft"]};function k(t){if(t&&t.parentNode){for(var e=t.parentNode.firstChild,n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}return[]}function O(t){return!!(t&&t instanceof window.HTMLElement)}function T(t){return Array.prototype.slice.call(t)}var x='[data-glide-el="track"]';var H=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.listeners=n}return i(t,[{key:"on",value:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];d(t)&&(t=[t]);for(var r=0;r<t.length;r++)this.listeners[t[r]]=n,e.addEventListener(t[r],this.listeners[t[r]],i)}},{key:"off",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];d(t)&&(t=[t]);for(var i=0;i<t.length;i++)e.removeEventListener(t[i],this.listeners[t[i]],n)}},{key:"destroy",value:function(){delete this.listeners}}]),t}();var A=["ltr","rtl"],j={">":"<","<":">","=":"="};function z(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}function R(t,e){return{modify:function(t){var n=Math.floor(t/e.Sizes.slideWidth);return t+e.Gaps.value*n}}}function C(t,e){return{modify:function(t){return t+e.Clones.grow/2}}}function E(t,e){return{modify:function(n){if(t.settings.focusAt>=0){var i=e.Peek.value;return h(i)?n-i.before:n-i}return n}}}function L(t,e){return{modify:function(n){var i=e.Gaps.value,r=e.Sizes.width,s=t.settings.focusAt,o=e.Sizes.slideWidth;return"center"===s?n-(r/2-o/2):n-o*s-i*s}}}var P=!1;try{var M=Object.defineProperty({},"passive",{get:function(){P=!0}});window.addEventListener("testPassive",null,M),window.removeEventListener("testPassive",null,M)}catch(t){}var D=P,V=["touchstart","mousedown"],W=["touchmove","mousemove"],B=["touchend","touchcancel","mouseup","mouseleave"],q=["mousedown","mousemove","mouseup","mouseleave"];function G(t,e,n){var i=new H,r=0,s=0,o=0,a=!1,u=!!D&&{passive:!0},c={mount:function(){this.bindSwipeStart()},start:function(e){if(!a&&!t.disabled){this.disable();var i=this.touches(e);r=null,s=f(i.pageX),o=f(i.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),n.emit("swipe.start")}},move:function(i){if(!t.disabled){var a=t.settings,u=a.touchAngle,c=a.touchRatio,l=a.classes,d=this.touches(i),h=f(d.pageX)-s,v=f(d.pageY)-o,p=Math.abs(h<<2),m=Math.abs(v<<2),g=Math.sqrt(p+m),y=Math.sqrt(m);if(!(180*(r=Math.asin(y/g))/Math.PI<u))return!1;i.stopPropagation(),e.Move.make(h*parseFloat(c)),e.Html.root.classList.add(l.dragging),n.emit("swipe.move")}},end:function(i){if(!t.disabled){var o=t.settings,a=o.perSwipe,u=o.touchAngle,c=o.classes,l=this.touches(i),f=this.threshold(i),d=l.pageX-s,h=180*r/Math.PI;this.enable(),d>f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,"<"))):d<-f&&h<u?e.Run.make(e.Direction.resolve("".concat(a,">"))):e.Move.make(),e.Html.root.classList.remove(c.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),n.emit("swipe.end")}},bindSwipeStart:function(){var n=this,r=t.settings,s=r.swipeThreshold,o=r.dragThreshold;s&&i.on(V[0],e.Html.wrapper,(function(t){n.start(t)}),u),o&&i.on(V[1],e.Html.wrapper,(function(t){n.start(t)}),u)},unbindSwipeStart:function(){i.off(V[0],e.Html.wrapper,u),i.off(V[1],e.Html.wrapper,u)},bindSwipeMove:function(){var n=this;i.on(W,e.Html.wrapper,_((function(t){n.move(t)}),t.settings.throttle),u)},unbindSwipeMove:function(){i.off(W,e.Html.wrapper,u)},bindSwipeEnd:function(){var t=this;i.on(B,e.Html.wrapper,(function(e){t.end(e)}))},unbindSwipeEnd:function(){i.off(B,e.Html.wrapper)},touches:function(t){return q.indexOf(t.type)>-1?t:t.touches[0]||t.changedTouches[0]},threshold:function(e){var n=t.settings;return q.indexOf(e.type)>-1?n.dragThreshold:n.swipeThreshold},enable:function(){return a=!1,e.Transition.enable(),this},disable:function(){return a=!0,e.Transition.disable(),this}};return n.on("build.after",(function(){e.Html.root.classList.add(t.settings.classes.swipeable)})),n.on("destroy",(function(){c.unbindSwipeStart(),c.unbindSwipeMove(),c.unbindSwipeEnd(),i.destroy()})),c}var F='[data-glide-el^="controls"]',I="".concat(F,' [data-glide-dir*="<"]'),N="".concat(F,' [data-glide-dir*=">"]');function Y(t,e,n){var i=new H,r=!!D&&{passive:!0},s={mount:function(){this._n=e.Html.root.querySelectorAll('[data-glide-el="controls[nav]"]'),this._c=e.Html.root.querySelectorAll(F),this._arrowControls={previous:e.Html.root.querySelectorAll(I),next:e.Html.root.querySelectorAll(N)},this.addBindings()},setActive:function(){for(var t=0;t<this._n.length;t++)this.addClass(this._n[t].children)},removeActive:function(){for(var t=0;t<this._n.length;t++)this.removeClass(this._n[t].children)},addClass:function(e){var n=t.settings,i=e[t.index];i&&i&&(i.classList.add(n.classes.nav.active),k(i).forEach((function(t){t.classList.remove(n.classes.nav.active)})))},removeClass:function(e){var n=e[t.index];n&&n.classList.remove(t.settings.classes.nav.active)},setArrowState:function(){if(!t.settings.rewind){var n=s._arrowControls.next,i=s._arrowControls.previous;this.resetArrowState(n,i),0===t.index&&this.disableArrow(i),t.index===e.Run.length&&this.disableArrow(n)}},resetArrowState:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){T(t).forEach((function(t){t.classList.remove(e.classes.arrow.disabled)}))}))},disableArrow:function(){for(var e=t.settings,n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];i.forEach((function(t){T(t).forEach((function(t){t.classList.add(e.classes.arrow.disabled)}))}))},addBindings:function(){for(var t=0;t<this._c.length;t++)this.bind(this._c[t].children)},removeBindings:function(){for(var t=0;t<this._c.length;t++)this.unbind(this._c[t].children)},bind:function(t){for(var e=0;e<t.length;e++)i.on("click",t[e],this.click),i.on("touchstart",t[e],this.click,r)},unbind:function(t){for(var e=0;e<t.length;e++)i.off(["click","touchstart"],t[e])},click:function(t){D||"touchstart"!==t.type||t.preventDefault();var n=t.currentTarget.getAttribute("data-glide-dir");e.Run.make(e.Direction.resolve(n))}};return m(s,"items",{get:function(){return s._c}}),n.on(["mount.after","move.after"],(function(){s.setActive()})),n.on(["mount.after","run"],(function(){s.setArrowState()})),n.on("destroy",(function(){s.removeBindings(),s.removeActive(),i.destroy()})),s}function X(t){return h(t)?(e=t,Object.keys(e).sort().reduce((function(t,n){return t[n]=e[n],t[n],t}),{})):(l("Breakpoints option must be an object"),{});var e}function $(t,e,n){var i=new H,r=t.settings,s=X(r.breakpoints),o=Object.assign({},r),a={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: ".concat(e,"px)")).matches)return t[e];return o}};return Object.assign(r,a.match(s)),i.on("resize",window,_((function(){t.settings=g(r,a.match(s))}),t.settings.throttle)),n.on("update",(function(){s=X(s),o=Object.assign({},r)})),n.on("destroy",(function(){i.off("resize",window)})),a}var J={Html:function(t,e,n){var i={mount:function(){this.root=t.selector,this.track=this.root.querySelector(x),this.collectSlides()},collectSlides:function(){this.slides=T(this.wrapper.children).filter((function(e){return!e.classList.contains(t.settings.classes.slide.clone)}))}};return m(i,"root",{get:function(){return i._r},set:function(t){d(t)&&(t=document.querySelector(t)),O(t)?i._r=t:l("Root element must be a existing Html node")}}),m(i,"track",{get:function(){return i._t},set:function(t){O(t)?i._t=t:l("Could not find track element. Please use ".concat(x," attribute."))}}),m(i,"wrapper",{get:function(){return i.track.children[0]}}),n.on("update",(function(){i.collectSlides()})),i},Translate:function(t,e,n){var i={set:function(n){var i=function(t,e,n){var i=[R,C,E,L].concat(t._t,[z]);return{mutate:function(r){for(var s=0;s<i.length;s++){var o=i[s];v(o)&&v(o().modify)?r=o(t,e,n).modify(r):l("Transformer should be a function that returns an object with `modify()` method")}return r}}}(t,e).mutate(n),r="translate3d(".concat(-1*i,"px, 0px, 0px)");e.Html.wrapper.style.mozTransform=r,e.Html.wrapper.style.webkitTransform=r,e.Html.wrapper.style.transform=r},remove:function(){e.Html.wrapper.style.transform=""},getStartIndex:function(){var n=e.Sizes.length,i=t.index,r=t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?n+(i-r):(i+r)%n},getTravelDistance:function(){var n=e.Sizes.slideWidth*t.settings.perView;return e.Run.isOffset(">")||e.Run.isOffset("|>")?-1*n:n}};return n.on("move",(function(r){if(!t.isType("carousel")||!e.Run.isOffset())return i.set(r.movement);e.Transition.after((function(){n.emit("translate.jump"),i.set(e.Sizes.slideWidth*t.index)}));var s=e.Sizes.slideWidth*e.Translate.getStartIndex();return i.set(s-e.Translate.getTravelDistance())})),n.on("destroy",(function(){i.remove()})),i},Transition:function(t,e,n){var i=!1,r={compose:function(e){var n=t.settings;return i?"".concat(e," 0ms ").concat(n.animationTimingFunc):"".concat(e," ").concat(this.duration,"ms ").concat(n.animationTimingFunc)},set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"transform";e.Html.wrapper.style.transition=this.compose(t)},remove:function(){e.Html.wrapper.style.transition=""},after:function(t){setTimeout((function(){t()}),this.duration)},enable:function(){i=!1,this.set()},disable:function(){i=!0,this.set()}};return m(r,"duration",{get:function(){var n=t.settings;return t.isType("slider")&&e.Run.offset?n.rewindDuration:n.animationDuration}}),n.on("move",(function(){r.set()})),n.on(["build.before","resize","translate.jump"],(function(){r.disable()})),n.on("run",(function(){r.enable()})),n.on("destroy",(function(){r.remove()})),r},Direction:function(t,e,n){var i={mount:function(){this.value=t.settings.direction},resolve:function(t){var e=t.slice(0,1);return this.is("rtl")?t.split(e).join(j[e]):t},is:function(t){return this.value===t},addClass:function(){e.Html.root.classList.add(t.settings.classes.direction[this.value])},removeClass:function(){e.Html.root.classList.remove(t.settings.classes.direction[this.value])}};return m(i,"value",{get:function(){return i._v},set:function(t){A.indexOf(t)>-1?i._v=t:l("Direction value must be `ltr` or `rtl`")}}),n.on(["destroy","update"],(function(){i.removeClass()})),n.on("update",(function(){i.mount()})),n.on(["build.before","update"],(function(){i.addClass()})),i},Peek:function(t,e,n){var i={mount:function(){this.value=t.settings.peek}};return m(i,"value",{get:function(){return i._v},set:function(t){h(t)?(t.before=f(t.before),t.after=f(t.after)):t=f(t),i._v=t}}),m(i,"reductor",{get:function(){var e=i.value,n=t.settings.perView;return h(e)?e.before/n+e.after/n:2*e/n}}),n.on(["resize","update"],(function(){i.mount()})),i},Sizes:function(t,e,n){var i={setupSlides:function(){for(var t="".concat(this.slideWidth,"px"),n=e.Html.slides,i=0;i<n.length;i++)n[i].style.width=t},setupWrapper:function(){e.Html.wrapper.style.width="".concat(this.wrapperSize,"px")},remove:function(){for(var t=e.Html.slides,n=0;n<t.length;n++)t[n].style.width="";e.Html.wrapper.style.width=""}};return m(i,"length",{get:function(){return e.Html.slides.length}}),m(i,"width",{get:function(){return e.Html.track.offsetWidth}}),m(i,"wrapperSize",{get:function(){return i.slideWidth*i.length+e.Gaps.grow+e.Clones.grow}}),m(i,"slideWidth",{get:function(){return i.width/t.settings.perView-e.Peek.reductor-e.Gaps.reductor}}),n.on(["build.before","resize","update"],(function(){i.setupSlides(),i.setupWrapper()})),n.on("destroy",(function(){i.remove()})),i},Gaps:function(t,e,n){var i={apply:function(t){for(var n=0,i=t.length;n<i;n++){var r=t[n].style,s=e.Direction.value;r[S[s][0]]=0!==n?"".concat(this.value/2,"px"):"",n!==t.length-1?r[S[s][1]]="".concat(this.value/2,"px"):r[S[s][1]]=""}},remove:function(t){for(var e=0,n=t.length;e<n;e++){var i=t[e].style;i.marginLeft="",i.marginRight=""}}};return m(i,"value",{get:function(){return f(t.settings.gap)}}),m(i,"grow",{get:function(){return i.value*e.Sizes.length}}),m(i,"reductor",{get:function(){var e=t.settings.perView;return i.value*(e-1)/e}}),n.on(["build.after","update"],_((function(){i.apply(e.Html.wrapper.children)}),30)),n.on("destroy",(function(){i.remove(e.Html.wrapper.children)})),i},Move:function(t,e,n){var i={mount:function(){this._o=0},make:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.offset=i,n.emit("move",{movement:this.value}),e.Transition.after((function(){n.emit("move.after",{movement:t.value})}))}};return m(i,"offset",{get:function(){return i._o},set:function(t){i._o=function(t){return void 0===t}(t)?0:f(t)}}),m(i,"translate",{get:function(){return e.Sizes.slideWidth*t.index}}),m(i,"value",{get:function(){var t=this.offset,n=this.translate;return e.Direction.is("rtl")?n+t:n-t}}),n.on(["build.before","run"],(function(){i.make()})),i},Clones:function(t,e,n){var i={mount:function(){this.items=[],t.isType("carousel")&&(this.items=this.collect())},collect:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=e.Html.slides,r=t.settings,s=r.perView,o=r.classes,a=r.cloningRatio;if(0!==i.length)for(var u=s+ +!!t.settings.peek+Math.round(s/2),c=i.slice(0,u).reverse(),l=i.slice(-1*u),f=0;f<Math.max(a,Math.floor(s/i.length));f++){for(var d=0;d<c.length;d++){var h=c[d].cloneNode(!0);h.classList.add(o.slide.clone),n.push(h)}for(var v=0;v<l.length;v++){var p=l[v].cloneNode(!0);p.classList.add(o.slide.clone),n.unshift(p)}}return n},append:function(){for(var t=this.items,n=e.Html,i=n.wrapper,r=n.slides,s=Math.floor(t.length/2),o=t.slice(0,s).reverse(),a=t.slice(-1*s).reverse(),u="".concat(e.Sizes.slideWidth,"px"),c=0;c<a.length;c++)i.appendChild(a[c]);for(var l=0;l<o.length;l++)i.insertBefore(o[l],r[0]);for(var f=0;f<t.length;f++)t[f].style.width=u},remove:function(){for(var t=this.items,n=0;n<t.length;n++)e.Html.wrapper.removeChild(t[n])}};return m(i,"grow",{get:function(){return(e.Sizes.slideWidth+e.Gaps.value)*i.items.length}}),n.on("update",(function(){i.remove(),i.mount(),i.append()})),n.on("build.before",(function(){t.isType("carousel")&&i.append()})),n.on("destroy",(function(){i.remove()})),i},Resize:function(t,e,n){var i=new H,r={mount:function(){this.bind()},bind:function(){i.on("resize",window,_((function(){n.emit("resize")}),t.settings.throttle))},unbind:function(){i.off("resize",window)}};return n.on("destroy",(function(){r.unbind(),i.destroy()})),r},Build:function(t,e,n){var i={mount:function(){n.emit("build.before"),this.typeClass(),this.activeClass(),n.emit("build.after")},typeClass:function(){e.Html.root.classList.add(t.settings.classes.type[t.settings.type])},activeClass:function(){var n=t.settings.classes,i=e.Html.slides[t.index];i&&(i.classList.add(n.slide.active),k(i).forEach((function(t){t.classList.remove(n.slide.active)})))},removeClasses:function(){var n=t.settings.classes,i=n.type,r=n.slide;e.Html.root.classList.remove(i[t.settings.type]),e.Html.slides.forEach((function(t){t.classList.remove(r.active)}))}};return n.on(["destroy","update"],(function(){i.removeClasses()})),n.on(["resize","update"],(function(){i.mount()})),n.on("move.after",(function(){i.activeClass()})),i},Run:function(t,e,n){var i={mount:function(){this._o=!1},make:function(i){var r=this;t.disabled||(!t.settings.waitForTransition||t.disable(),this.move=i,n.emit("run.before",this.move),this.calculate(),n.emit("run",this.move),e.Transition.after((function(){r.isStart()&&n.emit("run.start",r.move),r.isEnd()&&n.emit("run.end",r.move),r.isOffset()&&(r._o=!1,n.emit("run.offset",r.move)),n.emit("run.after",r.move),t.enable()})))},calculate:function(){var e=this.move,n=this.length,r=e.steps,s=e.direction,o=1;if("="===s)return t.settings.bound&&f(r)>n?void(t.index=n):void(t.index=r);if(">"!==s||">"!==r)if("<"!==s||"<"!==r){if("|"===s&&(o=t.settings.perView||1),">"===s||"|"===s&&">"===r){var a=function(e){var n=t.index;if(t.isType("carousel"))return n+e;return n+(e-n%e)}(o);return a>n&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e<=r)return e;if(t.isType("carousel"))return e-(r+1);if(t.settings.rewind)return i.isBound()&&!i.isEnd()?r:0;if(i.isBound())return r;return Math.floor(r/n)*n}(a,o))}if("<"===s||"|"===s&&"<"===r){var u=function(e){var n=t.index;if(t.isType("carousel"))return n-e;var i=Math.ceil(n/e);return(i-1)*e}(o);return u<0&&(this._o=!0),void(t.index=function(e,n){var r=i.length;if(e>=0)return e;if(t.isType("carousel"))return e+(r+1);if(t.settings.rewind)return i.isBound()&&i.isStart()?r:Math.floor(r/n)*n;return 0}(u,o))}l("Invalid direction pattern [".concat(s).concat(r,"] has been used"))}else t.index=0;else t.index=n},isStart:function(){return t.index<=0},isEnd:function(){return t.index>=this.length},isOffset:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return t?!!this._o&&("|>"===t?"|"===this.move.direction&&">"===this.move.steps:"|<"===t?"|"===this.move.direction&&"<"===this.move.steps:this.move.direction===t):this._o},isBound:function(){return t.isType("slider")&&"center"!==t.settings.focusAt&&t.settings.bound}};return m(i,"move",{get:function(){return this._m},set:function(t){var e=t.substr(1);this._m={direction:t.substr(0,1),steps:e?f(e)?f(e):e:0}}}),m(i,"length",{get:function(){var n=t.settings,i=e.Html.slides.length;return this.isBound()?i-1-(f(n.perView)-1)+f(n.focusAt):i-1}}),m(i,"offset",{get:function(){return this._o}}),i}},K=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&s(t,e)}(o,t);var n=a(o);function o(){return e(this,o),n.apply(this,arguments)}return i(o,[{key:"mount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return u(r(o.prototype),"mount",this).call(this,Object.assign({},J,t))}}]),o}(b);const Q="glide__arrow--left",U="glide__arrow--right";function Z(t,e){return{mount(){t.settings.rewind||(t.on(["mount.after","resize"],(()=>{e.Sizes.length<=t.settings.perView?t.disable():t.enable()})),t.on(["mount.after","run","resize"],(()=>{e.Controls.items.forEach((n=>{const i=n.querySelector(`.${Q}`);i&&(0===t.index||e.Sizes.length<=t.settings.perView?i.setAttribute("disabled",""):i.removeAttribute("disabled"));const r=n.querySelector(`.${U}`);if(r){(t.settings.bound?t.index+(t.settings.perView-1):t.index)===e.Sizes.length-1||e.Sizes.length<=t.settings.perView?r.setAttribute("disabled",""):r.removeAttribute("disabled")}i.disabled&&r.disabled?n.classList.add("glide__arrows--disabled"):n.classList.remove("glide__arrows--disabled")}))})))}}}Drupal.behaviors.glide={attach(){const t=document.querySelectorAll(".explore-block button.nav-link");function e(){document.querySelectorAll(".tab-pane.active .glide").forEach((t=>{new K(t,{rewind:!1,bound:!0,dragThreshold:!1,gap:24,perView:4,wrapperWidth:300,breakpoints:{1199:{perView:3},991:{perView:2},767:{perView:1}}}).mount({Controls:Y,Breakpoints:$,Swipe:G,ControlsDisabler:Z}).update({wrapperWidth:300})}))}for(let n=0;n<t.length;n++)t[n].addEventListener("click",(()=>{e()}));e()}}})); //# sourceMappingURL=explore-block.min.js.map -- GitLab From 49af8af2376de5b6ed2d3c32155c9e440fd434b1 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 09:29:54 +0300 Subject: [PATCH 030/149] ISAICP-9045: Temporarily disable a test (until ISAICP-9055). --- tests/features/communities/oss_catalogue/oss_catalogue.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/features/communities/oss_catalogue/oss_catalogue.feature b/tests/features/communities/oss_catalogue/oss_catalogue.feature index e80971b6a5..fa76710b68 100644 --- a/tests/features/communities/oss_catalogue/oss_catalogue.feature +++ b/tests/features/communities/oss_catalogue/oss_catalogue.feature @@ -131,7 +131,7 @@ Feature: When I go to the content page of the type "oss_solution" with the title "Foo" Then I should see the text "Foo's GIT description" - @loggedErrors + @wip @loggedErrors Scenario: All necessary OSS Solution fields are visible on node page. Given oss_contact content: | title | -- GitLab From 8ec3b6be4f18ee08b7059f67503e6d769343d0c0 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 09:31:37 +0300 Subject: [PATCH 031/149] ISAICP-9045: Drop update tests. --- tests/features/update/ISAICP-8911.feature | 39 ----------------------- 1 file changed, 39 deletions(-) delete mode 100644 tests/features/update/ISAICP-8911.feature diff --git a/tests/features/update/ISAICP-8911.feature b/tests/features/update/ISAICP-8911.feature deleted file mode 100644 index b654cfff6d..0000000000 --- a/tests/features/update/ISAICP-8911.feature +++ /dev/null @@ -1,39 +0,0 @@ -@api @group-clone -Feature: Test the converted videos into document. - - @update:joinup_core_update_111200 - Scenario: Videos have migrated correctly. - When I visit "node/125946" - Then I should see the heading "eGovernment Reduction of Administrative Burden-ePractice TV interview: Mr Siim Sikkut" - And I should see the text "Mr Siim Sikkut, Government office of Estonia" - And I should see the text "Published on: 10/06/2014" - And I should see the text "Last update: 09/06/2014" - - When I visit "node/125943" - Then I should see the heading "Concluding Remarks - Terje Peetso, DG CONNECT" - And I should see the text "Terje Peetso, DG CONNECT - eHealth and the Brain - ICT for Neuropsychiatric Health, 5 November, Brussels" - And I should see the text "Published on: 20/11/2013" - - When I visit "node/125865" - Then I should see the heading "EIF workshop-ePractice TV:Soeren Bittins, Massimiliano Massi" - And I should see the text "EIF workshop, 16 April 2012" - And I should see the text "Interviewees: Soeren Bittins, Massimiliano Massi, Fraunhofer Fokus" - And I should see the text "Published on: 11/05/2012" - - When I visit "/community/epractice/video/egov-reduction-admininstrative-burden-epractice-tv-interview-kris-blancke" - Then I should see the heading "eGov Reduction of Admininstrative Burden-ePractice TV interview: Kris Blancke" - And I should see the text "Mr Kris Blancke, Chancellery of the Prime Minister, Administrative Simplification Agency (DAV/ASA)" - And I should see the text "Published on: 10/06/2014" - - @update:joinup_core_update_111200 - Scenario Outline: Ensure old /elibrary/video/* redirects are maintained and are pointing to the new document nodes. - Given I visit "<source>" - Then I should be on "<destination>" - - Examples: - | source | destination | - | /elibrary/video/us-national-information-exchange-model-niem-explained | /collection/semic-support-centre/document/us-national-information-exchange-model-niem-explained | - | /elibrary/video/e-codex-e-justice-communication-online-data-exchange | /collection/justice-law-and-security/document/e-codex-e-justice-communication-online-data-exchange | - | /elibrary/video/eu-declan-deasy-about-digital-single-market | /collection/egovernment/document/eu-declan-deasy-about-digital-single-market | - | /elibrary/video/eu-story-explaining-digital-single-market-and-large-scale-pilots | /collection/egovernment/document/eu-story-explaining-digital-single-market-and-large-scale-pilots | - | /elibrary/video/presenting-osepa-project-share-knowledge-and-experience-about-foss-public-administrat | /collection/open-source-observatory-osor/document/presenting-osepa-project-share-knowledge-and-experience-about-foss-public-administrations | -- GitLab From 37a3985ac6ffe9e22d3698c08bc10d7ed0a233f1 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 09:36:40 +0300 Subject: [PATCH 032/149] ISAICP-9045: Document test disabling. --- tests/features/communities/oss_catalogue/oss_catalogue.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/features/communities/oss_catalogue/oss_catalogue.feature b/tests/features/communities/oss_catalogue/oss_catalogue.feature index fa76710b68..3adb83635c 100644 --- a/tests/features/communities/oss_catalogue/oss_catalogue.feature +++ b/tests/features/communities/oss_catalogue/oss_catalogue.feature @@ -131,6 +131,7 @@ Feature: When I go to the content page of the type "oss_solution" with the title "Foo" Then I should see the text "Foo's GIT description" + # TODO: Re-enable this test in ISAICP-9055. @wip @loggedErrors Scenario: All necessary OSS Solution fields are visible on node page. Given oss_contact content: -- GitLab From 252d5a60a1e6d12a72dfd071f51bea68a12a1594 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 09:38:54 +0300 Subject: [PATCH 033/149] ISAICP-9045: Temporarily disable 2 tests (to be re-enabled in ISAICP-9052). --- tests/features/eulogin/eulogin.feature | 2 ++ tests/features/user/developer.feature | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/features/eulogin/eulogin.feature b/tests/features/eulogin/eulogin.feature index 2a0be93c14..4e9ad45a56 100644 --- a/tests/features/eulogin/eulogin.feature +++ b/tests/features/eulogin/eulogin.feature @@ -329,6 +329,8 @@ Feature: Log in through EU Login When I go to "/user/password" Then the response status code should be 404 + # TODO: Re-enable this test in ISAICP-9052 + @wip Scenario: As a developer I can temporary disable the site registration. Given CAS users: | Username | E-mail | Password | diff --git a/tests/features/user/developer.feature b/tests/features/user/developer.feature index ce9ad8758b..dbfbe906a6 100644 --- a/tests/features/user/developer.feature +++ b/tests/features/user/developer.feature @@ -56,6 +56,8 @@ Feature: Variety tests for the developer role. And I am on the homepage Then I should not see the text "Warning: You are working on production. Please, be extra cautious!" + # TODO: Re-enable this test in ISAICP-9052 + @wip Scenario: Configuration is locked and unlocked on developers login and logout. Given users: | Username | Roles | -- GitLab From f36ffb8a410b9d23d72bea6c6a191134298734f6 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 11:24:17 +0300 Subject: [PATCH 034/149] ISAICP-9045: Fix the social media test. --- tests/features/user/profile.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/features/user/profile.feature b/tests/features/user/profile.feature index 3d280960d2..4b7d2da1dd 100644 --- a/tests/features/user/profile.feature +++ b/tests/features/user/profile.feature @@ -49,7 +49,7 @@ Feature: User profile And I should see the text "Supplier exchange" And I should see the link "Edit" And the link "Facebook" in the "Header" region should point to "https://www.facebook.com/leodavinci" - And the link "X" in the "Header" region should point to "https://www.x.com/therealdavinci" + And the link "X" in the "Header" region should point to "https://x.com/therealdavinci" And the link "LinkedIn" in the "Header" region should point to "https://www.linkedin.com/leonardo.davinci" And the link "GitHub" in the "Header" region should point to "https://github.com/davinci" And the link "Mastodon" in the "Header" region should point to "https://myaccount.pl" -- GitLab From 924716c557ab7d8c85eb0ccdc126d9853e5b62db Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 11:50:28 +0300 Subject: [PATCH 035/149] ISAICP-9045: Config already provided by markdown_easy. --- .../config/install/filter.format.markdown.yml | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 web/modules/custom/eu_oss_catalogue/config/install/filter.format.markdown.yml diff --git a/web/modules/custom/eu_oss_catalogue/config/install/filter.format.markdown.yml b/web/modules/custom/eu_oss_catalogue/config/install/filter.format.markdown.yml deleted file mode 100644 index 56c1a77748..0000000000 --- a/web/modules/custom/eu_oss_catalogue/config/install/filter.format.markdown.yml +++ /dev/null @@ -1,33 +0,0 @@ -langcode: en -status: true -dependencies: - module: - - editor - - markdown_easy -name: Markdown -format: markdown -weight: 0 -filters: - filter_htmlcorrector: - id: filter_htmlcorrector - provider: filter - status: false - weight: -33 - settings: { } - filter_html: - id: filter_html - provider: filter - status: true - weight: -49 - settings: - allowed_html: "<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type='1 A I'> <li> <dl> <dt> <dd> <h2 id='jump-*'> <h3 id> <h4 id> <h5 id> <h6 id>" - filter_html_help: true - filter_html_nofollow: false - markdown_easy: - id: markdown_easy - provider: markdown_easy - status: true - weight: -50 - settings: - flavor: standard - tips: '' -- GitLab From 72b1861b210dae7d3e8399f902b97938625cedf5 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 12:02:25 +0300 Subject: [PATCH 036/149] ISAICP-9045: Temporarily disable killswitch.feature. --- tests/features/communities/oss_catalogue/killswitch.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/features/communities/oss_catalogue/killswitch.feature b/tests/features/communities/oss_catalogue/killswitch.feature index a77ba248f2..29d89ddaae 100644 --- a/tests/features/communities/oss_catalogue/killswitch.feature +++ b/tests/features/communities/oss_catalogue/killswitch.feature @@ -1,4 +1,5 @@ -@api @group-clone +# TODO: Re-enable in ISAICP-9052 +@wip @api @group-clone Feature: Test EU OSS Catalogue killswitch Scenario: Switch ON/OFF -- GitLab From 27d135e354ccec45716232c25059b0b649728c79 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Thu, 5 Sep 2024 14:40:59 +0300 Subject: [PATCH 037/149] ISAICP-9045: Mute a deprecation with Twig. --- resources/drupal-scaffold/.deprecation-ignore.txt.append | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/drupal-scaffold/.deprecation-ignore.txt.append b/resources/drupal-scaffold/.deprecation-ignore.txt.append index be5c2f63bd..25801cb88f 100644 --- a/resources/drupal-scaffold/.deprecation-ignore.txt.append +++ b/resources/drupal-scaffold/.deprecation-ignore.txt.append @@ -4,3 +4,5 @@ # TODO: Remove in Drupal 11. %Renderer::renderPlain\(\) is deprecated in drupal:10.3.0 and is removed from drupal:12.0.0. Instead, you should use ::renderInIsolation\(\). See https://www.drupal.org/node/3407994% + +%Since twig/twig 3.12: Getting node "[^"]*" on a "[^"]*" class is deprecated.% -- GitLab From ca4008fdbf625e29d56612dbbf970a9e62d7a21d Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Thu, 5 Sep 2024 18:33:22 +0200 Subject: [PATCH 038/149] ISAICP-5244: Refactor collection_member_count/solution_member_count. --- .../custom/collection/collection.module | 24 +---------------- .../src/Entity/CollectionInterface.php | 8 ++++++ .../joinup_group/src/Entity/GroupTrait.php | 27 +++++++++++++++++++ web/modules/custom/solution/solution.module | 24 +---------------- .../solution/src/Entity/SolutionInterface.php | 8 ++++++ .../src/Form/ExportStatisticsPerGroupForm.php | 2 +- 6 files changed, 46 insertions(+), 47 deletions(-) diff --git a/web/modules/custom/collection/collection.module b/web/modules/custom/collection/collection.module index 16fe34c42b..1fe510b564 100644 --- a/web/modules/custom/collection/collection.module +++ b/web/modules/custom/collection/collection.module @@ -284,7 +284,7 @@ function collection_rdf_entity_view(array &$build, EntityInterface $entity, Enti // Member count. if ($display->getComponent('members')) { - $member_count = collection_member_count($entity); + $member_count = $entity->getActiveMemberCount(); // Invalidate the member count every time the group membership list changes. // @see \Drupal\og\Plugin\Block\MemberCountBlock::getCacheTags() $tags = Cache::buildTags(OgMembershipInterface::GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX, $entity->getCacheTagsToInvalidate()); @@ -331,28 +331,6 @@ function collection_rdf_entity_view(array &$build, EntityInterface $entity, Enti } } -/** - * Amount of members of a collection. - * - * @param \Drupal\rdf_entity\RdfInterface $entity - * The collection. - * - * @return int - * Amount of members. - */ -function collection_member_count(RdfInterface $entity): int { - // We're doing a direct database query rather than using methods in OG's - // MembershipManager service since we just need a count, and we need to filter - // out blocked user accounts. - $query = \Drupal::database()->select('og_membership', 'om'); - $query->innerJoin('users_field_data', 'ufd', 'om.uid = ufd.uid'); - $query->condition('ufd.status', 1) - ->condition('entity_type', 'rdf_entity') - ->condition('entity_id', $entity->id()) - ->condition('state', OgMembershipInterface::STATE_ACTIVE); - return (int) $query->countQuery()->execute()->fetchField(); -} - /** * Implements hook_entity_bundle_field_info(). */ diff --git a/web/modules/custom/collection/src/Entity/CollectionInterface.php b/web/modules/custom/collection/src/Entity/CollectionInterface.php index 6ecc1e949c..d756701f86 100644 --- a/web/modules/custom/collection/src/Entity/CollectionInterface.php +++ b/web/modules/custom/collection/src/Entity/CollectionInterface.php @@ -30,6 +30,14 @@ interface CollectionInterface extends RdfInterface, EntityPublicationTimeInterfa */ public function getSolutions(bool $only_published = FALSE): array; + /** + * Returns the number of active members in this collection. + * + * @return int + * The number of active members. + */ + public function getActiveMemberCount(): int; + /** * Returns the IDs of the solutions that are affiliated with this collection. * diff --git a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php index e09bbee62f..fb11c4bcb1 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php @@ -25,6 +25,13 @@ trait GroupTrait { use OutdatedContentTrait; + /** + * The number of active members. + * + * @var int + */ + protected $activeMemberCount; + /** * {@inheritdoc} */ @@ -324,4 +331,24 @@ protected function getMembershipManager(): MembershipManagerInterface { return \Drupal::service('og.membership_manager'); } + /** + * {@inheritdoc} + */ + public function getActiveMemberCount(): int { + if (isset($this->activeMemberCount)) { + return $this->activeMemberCount; + } + + // We're doing a direct database query rather than using methods in OG's + // MembershipManager service since we just need a count, and we need to + // filter out blocked user accounts. + $query = \Drupal::database()->select('og_membership', 'om'); + $query->innerJoin('users_field_data', 'ufd', '[om].[uid] = [ufd].[uid]'); + $query->condition('ufd.status', 1) + ->condition('entity_type', 'rdf_entity') + ->condition('entity_id', $this->id()) + ->condition('state', OgMembershipInterface::STATE_ACTIVE); + return $this->activeMemberCount = (int) $query->countQuery()->execute()->fetchField(); + } + } diff --git a/web/modules/custom/solution/solution.module b/web/modules/custom/solution/solution.module index 80c2033f3a..235bfb52c7 100644 --- a/web/modules/custom/solution/solution.module +++ b/web/modules/custom/solution/solution.module @@ -392,7 +392,7 @@ function solution_rdf_entity_view(array &$build, RdfInterface $solution, EntityV // Member count. if ($display->getComponent('members')) { - $member_count = solution_member_count($solution); + $member_count = $solution->getActiveMemberCount(); // Invalidate the member count every time the group membership list changes. // @see \Drupal\og\Plugin\Block\MemberCountBlock::getCacheTags() $tags = Cache::buildTags(OgMembershipInterface::GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX, $solution->getCacheTagsToInvalidate()); @@ -729,28 +729,6 @@ function solution_module_implements_alter(&$implementations, $hook): void { } } -/** - * Amount of members of a solution. - * - * @param \Drupal\rdf_entity\RdfInterface $entity - * The solution. - * - * @return int - * Amount of members. - */ -function solution_member_count(RdfInterface $entity): int { - // We're doing a direct database query rather than using methods in OG's - // MembershipManager service since we just need a count, and we need to filter - // out blocked user accounts. - $query = \Drupal::database()->select('og_membership', 'om'); - $query->innerJoin('users_field_data', 'ufd', '[om].[uid] = [ufd].[uid]'); - $query->condition('ufd.status', 1) - ->condition('om.entity_type', 'rdf_entity') - ->condition('om.entity_id', $entity->id()) - ->condition('om.state', OgMembershipInterface::STATE_ACTIVE); - return (int) $query->countQuery()->execute()->fetchField(); -} - /** * Implements hook_theme(). */ diff --git a/web/modules/custom/solution/src/Entity/SolutionInterface.php b/web/modules/custom/solution/src/Entity/SolutionInterface.php index b8c355a039..8501425043 100644 --- a/web/modules/custom/solution/src/Entity/SolutionInterface.php +++ b/web/modules/custom/solution/src/Entity/SolutionInterface.php @@ -70,4 +70,12 @@ public function getAffiliatedCollections(): array; */ public function getAffiliatedCollectionIds(): array; + /** + * Returns the number of active members in this solution. + * + * @return int + * The number of active members. + */ + public function getActiveMemberCount(): int; + } diff --git a/web/profiles/joinup/src/Form/ExportStatisticsPerGroupForm.php b/web/profiles/joinup/src/Form/ExportStatisticsPerGroupForm.php index dfa176fb85..c26bf06eb7 100644 --- a/web/profiles/joinup/src/Form/ExportStatisticsPerGroupForm.php +++ b/web/profiles/joinup/src/Form/ExportStatisticsPerGroupForm.php @@ -239,7 +239,7 @@ public function generateGroupStatistics(string $entity_id, array &$context): voi + $group_content['document']['archived'] + $group_content['event']['archived'] + $group_content['news']['archived'], - 'Number of members' => collection_member_count($group), + 'Number of members' => $group->getActiveMemberCount(), 'Description word count' => str_word_count(strip_tags($description)), 'Total number of likes' => !empty($content_ids) ? $this->getLikesCount($content_ids) : 0, ]; -- GitLab From d608afb5097189c70ae805c03d00a289ab88e5d4 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Mon, 9 Sep 2024 12:01:42 +0300 Subject: [PATCH 039/149] ISAICP-8996: QA nit picks. --- web/modules/custom/eu_oss_catalogue/README.md | 2 +- .../Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/README.md b/web/modules/custom/eu_oss_catalogue/README.md index 707441975f..80d3e07c2d 100644 --- a/web/modules/custom/eu_oss_catalogue/README.md +++ b/web/modules/custom/eu_oss_catalogue/README.md @@ -246,7 +246,7 @@ Run the following, to fetch from ``` Run the following, to fetch from -Dutch catalogue onboarding +Fetch solutions from Dutch catalogue ```bash ./vendor/bin/drush eu-oss:fetch dutch_catalogue diff --git a/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php index 16a467faee..e78f8f404c 100644 --- a/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php +++ b/web/modules/custom/eu_oss_catalogue/src/Plugin/eu_oss_catalogue/Provider/DutchCatalogue.php @@ -21,21 +21,19 @@ * @EuOssCatalogueProvider( * id = "dutch_catalogue", * label = @Translation("Dutch catalogue"), - * description = @Translation("Dutch catalogue onboarding."), + * description = @Translation("Dutch open source software solutions for the public administrations."), * parser = "publiccode_yml", * ) */ class DutchCatalogue extends EuOssCatalogueProviderPluginBase { /** - * Developers Italia API endpoint. - * - * @var string + * Dutch catalogue endpoint. */ protected const string ENDPOINT = 'https://gist.githubusercontent.com/dvh/95a09cf9df9b4567c256c188a0e8f4b2/raw'; /** - * List of projects fetched from Developers Italia API. + * List of projects fetched from Dutch catalogue API. * * @var array[][] * A list of fetched projects keyed by the coding platform base URL. The -- GitLab From 1b369ad54f3e6b91b0aab2030e69a3300a17f770 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 9 Sep 2024 12:21:41 +0200 Subject: [PATCH 040/149] ISAICP-9002: Add tmgmt_ec_etranslation and depencencies. --- composer.json | 3 +- composer.lock | 134 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d3bca6053b..09b66aff01 100644 --- a/composer.json +++ b/composer.json @@ -111,6 +111,7 @@ "drupal/svg_image": "^3.0", "drupal/symfony_mailer_lite": "^1.0", "drupal/theme_rule": "^1.0", + "drupal/tmgmt_ec_etranslation": "^1.0", "drupal/token": "~1.7", "drupal/video_embed_field": "^2", "drupal/view_unpublished": "^1.0", @@ -121,8 +122,8 @@ "drupal/views_multiple_permissions": "^2.0", "drupal/webform": "^6.2", "drush/drush": "^12.1", - "jakeasmith/http_build_url": "^1.0", "gitonomy/gitlib": "^1.4", + "jakeasmith/http_build_url": "^1.0", "knplabs/github-api": "^3.13", "m4tthumphrey/php-gitlab-api": "^11.12", "openeuropa/composer-artifacts": "^1.0", diff --git a/composer.lock b/composer.lock index 3ba336768d..5cc3b30236 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7e56945cd869c86d68dd6f18a9cdf822", + "content-hash": "486747bcc153a93ce7eccf5be8985611", "packages": [ { "name": "asm89/stack-cors", @@ -8815,6 +8815,138 @@ "issues": "https://www.drupal.org/project/issues/theme_rule" } }, + { + "name": "drupal/tmgmt", + "version": "1.15.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/tmgmt.git", + "reference": "8.x-1.15" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/tmgmt-8.x-1.15.zip", + "reference": "8.x-1.15", + "shasum": "07732ee85222927585ee59e42b40b07fca8ff8b0" + }, + "require": { + "drupal/core": "^9.3 || ^10" + }, + "require-dev": { + "drupal/metatag": "1.x-dev", + "drupal/paragraphs": "1.x-dev", + "drupal/pathauto": "1.x-dev", + "drupal/tmgmt_content": "*", + "drupal/tmgmt_file": "*", + "drupal/tmgmt_language_combination": "*", + "drupal/tmgmt_local": "*", + "drupal/tmgmt_locale": "*", + "drupal/webform": "5.x-dev || 6.x-dev || 6.2.x-dev" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.15", + "datestamp": "1680643412", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "berdir", + "homepage": "https://www.drupal.org/user/214652" + }, + { + "name": "cgalli", + "homepage": "https://www.drupal.org/user/77453" + }, + { + "name": "dawehner", + "homepage": "https://www.drupal.org/user/99340" + }, + { + "name": "floretan", + "homepage": "https://www.drupal.org/user/66163" + }, + { + "name": "fubhy", + "homepage": "https://www.drupal.org/user/761344" + }, + { + "name": "miro_dietiker", + "homepage": "https://www.drupal.org/user/227761" + }, + { + "name": "Schnitzel", + "homepage": "https://www.drupal.org/user/643820" + }, + { + "name": "webflo", + "homepage": "https://www.drupal.org/user/254778" + } + ], + "description": "Translation Management Tool", + "homepage": "https://www.drupal.org/project/tmgmt", + "support": { + "source": "https://git.drupalcode.org/project/tmgmt" + } + }, + { + "name": "drupal/tmgmt_ec_etranslation", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/tmgmt_ec_etranslation.git", + "reference": "1.0.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/tmgmt_ec_etranslation-1.0.0.zip", + "reference": "1.0.0", + "shasum": "dbdae0176227b239bfff140467171480e080fde0" + }, + "require": { + "drupal/core": "^8 || ^9 || ^10", + "drupal/tmgmt": "*" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "1.0.0", + "datestamp": "1685699050", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "claudiu.cristea", + "homepage": "https://www.drupal.org/user/56348" + }, + { + "name": "dieterholvoet", + "homepage": "https://www.drupal.org/user/3567222" + } + ], + "description": "TMGMT plugin for eTranslation, an online machine translation service provided by the European Commission (EC).", + "homepage": "https://www.drupal.org/project/tmgmt_ec_etranslation", + "support": { + "source": "https://git.drupalcode.org/project/tmgmt_ec_etranslation" + } + }, { "name": "drupal/token", "version": "1.15.0", -- GitLab From d8de68e2d74dd5a5fa1850f7fc3127f9b83daede Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 9 Sep 2024 12:29:49 +0200 Subject: [PATCH 041/149] ISAICP-9002: Enable tmgmt_ec_etranslation and export default settings. --- config/sync/core.extension.yml | 2 + config/sync/tmgmt.settings.yml | 11 + .../sync/tmgmt.translator.ec_etranslation.yml | 18 + config/sync/views.view.tmgmt_job_items.yml | 922 +++++++++++++++ config/sync/views.view.tmgmt_job_messages.yml | 363 ++++++ config/sync/views.view.tmgmt_job_overview.yml | 949 +++++++++++++++ ...s.view.tmgmt_translation_all_job_items.yml | 1013 +++++++++++++++++ 7 files changed, 3278 insertions(+) create mode 100644 config/sync/tmgmt.settings.yml create mode 100644 config/sync/tmgmt.translator.ec_etranslation.yml create mode 100644 config/sync/views.view.tmgmt_job_items.yml create mode 100644 config/sync/views.view.tmgmt_job_messages.yml create mode 100644 config/sync/views.view.tmgmt_job_overview.yml create mode 100644 config/sync/views.view.tmgmt_translation_all_job_items.yml diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 9bc01aab90..664b3ae5e6 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -242,6 +242,8 @@ module: template_suggestion: 0 text: 0 theme_rule: 0 + tmgmt: 0 + tmgmt_ec_etranslation: 0 token: 0 toolbar: 0 topic: 0 diff --git a/config/sync/tmgmt.settings.yml b/config/sync/tmgmt.settings.yml new file mode 100644 index 0000000000..e3f17b959d --- /dev/null +++ b/config/sync/tmgmt.settings.yml @@ -0,0 +1,11 @@ +_core: + default_config_hash: kNAclv7Nq8cW0Huko5DpTk2YAMaXNiCVB9iZON_MNHc +quick_checkout: true +anonymous_access: true +purge_finished: _never +word_count_exclude_tags: true +source_list_limit: 20 +respect_text_format: true +submit_job_item_on_cron: false +job_items_cron_limit: 50 +allowed_formats: { } diff --git a/config/sync/tmgmt.translator.ec_etranslation.yml b/config/sync/tmgmt.translator.ec_etranslation.yml new file mode 100644 index 0000000000..d2f4b9b731 --- /dev/null +++ b/config/sync/tmgmt.translator.ec_etranslation.yml @@ -0,0 +1,18 @@ +uuid: 922f7945-f457-4a27-b77c-53eca85d902a +langcode: en +status: true +dependencies: + module: + - tmgmt_ec_etranslation +name: ec_etranslation +label: 'European Commission eTranslation' +description: "Allows the European Commission's eTranslation service to process translation jobs." +auto_accept: null +weight: null +plugin: ec_etranslation +settings: + username: null + password: null + domain: SPD + email: null +remote_languages_mappings: { } diff --git a/config/sync/views.view.tmgmt_job_items.yml b/config/sync/views.view.tmgmt_job_items.yml new file mode 100644 index 0000000000..6e04e95808 --- /dev/null +++ b/config/sync/views.view.tmgmt_job_items.yml @@ -0,0 +1,922 @@ +uuid: 50126206-f9fb-445c-a062-82cde1b1be53 +langcode: en +status: true +dependencies: + module: + - tmgmt +_core: + default_config_hash: Ymf_yLVVBTztOPWtyVdjoiB3zrz-2YNYJpONc58ET0M +id: tmgmt_job_items +label: 'Translation Job Items' +module: views +description: '' +tag: '' +base_table: tmgmt_job_item +base_field: tjiid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 1 + display_options: + rendering_language: '***LANGUAGE_entity_default***' + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: '‹ previous' + next: 'next ›' + first: '« first' + last: 'last »' + quantity: 9 + pagination_heading_level: h4 + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + label: label + type: type + state: state + progress: progress + word_count: word_count + changed: changed + operations: operations + info: + label: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + type: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + state: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + progress: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + word_count: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: changed + empty_table: false + row: + type: fields + fields: + state: + id: state + table: tmgmt_job_item + field: state + relationship: none + group_type: group + admin_label: '' + label: State + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + machine_name: false + entity_type: tmgmt_job_item + entity_field: state + plugin_id: machine_name + label: + id: label + table: tmgmt_job_item + field: label + relationship: none + group_type: group + admin_label: '' + label: Label + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label + type: + id: type + table: tmgmt_job_item + field: type + relationship: none + group_type: group + admin_label: '' + label: Type + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_type + progress: + id: progress + table: tmgmt_job_item + field: progress + relationship: none + group_type: group + admin_label: '' + label: Progress + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_progress + word_count: + id: word_count + table: tmgmt_job_item + field: word_count + relationship: none + group_type: group + admin_label: '' + label: Words + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job_item + entity_field: word_count + plugin_id: field + tags_count: + id: tags_count + table: tmgmt_job_item + field: tags_count + relationship: none + group_type: group + admin_label: '' + label: Tags + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job_item + entity_field: tags_count + plugin_id: field + changed: + id: changed + table: tmgmt_job_item + field: changed + relationship: none + group_type: group + admin_label: '' + label: Changed + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: fallback + custom_date_format: '' + timezone: '' + entity_type: tmgmt_job_item + entity_field: changed + plugin_id: date + operations: + id: operations + table: tmgmt_job_item + field: operations + relationship: none + group_type: group + admin_label: '' + label: Operations + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + destination: false + entity_type: tmgmt_job_item + plugin_id: entity_operations + filters: { } + sorts: { } + title: 'Job Items' + header: { } + footer: { } + empty: + area: + id: area + table: views + field: area + relationship: none + group_type: group + admin_label: '' + empty: true + tokenize: false + content: + value: 'There are no items attached to this translation job.' + format: basic_html + plugin_id: text + relationships: { } + arguments: + tjid: + id: tjid + table: tmgmt_job_item + field: tjid + relationship: none + group_type: group + admin_label: '' + default_action: 'not found' + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: fixed + default_argument_options: + argument: '' + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + break_phrase: false + not: false + entity_type: tmgmt_job_item + entity_field: tjid + plugin_id: numeric + display_extenders: { } + use_ajax: true + cache_metadata: + contexts: + - 'languages:language_interface' + - url + - url.query_args + cacheable: false + max-age: 0 + tags: { } + checkout: + display_plugin: embed + id: checkout + display_title: Checkout + position: 2 + display_options: + display_extenders: { } + display_description: '' + rendering_language: '***LANGUAGE_entity_default***' + fields: + label: + id: label + table: tmgmt_job_item + field: label + relationship: none + group_type: group + admin_label: '' + label: Label + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label + type: + id: type + table: tmgmt_job_item + field: type + relationship: none + group_type: group + admin_label: '' + label: Type + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_type + word_count: + id: word_count + table: tmgmt_job_item + field: word_count + relationship: none + group_type: group + admin_label: '' + label: Words + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job_item + entity_field: word_count + plugin_id: field + changed: + id: changed + table: tmgmt_job_item + field: changed + relationship: none + group_type: group + admin_label: '' + label: Changed + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: timestamp + settings: + date_format: medium + custom_date_format: '' + timezone: '' + tooltip: + date_format: '' + custom_date_format: '' + time_diff: + enabled: false + future_format: '@interval hence' + past_format: '@interval ago' + granularity: 2 + refresh: 60 + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job_item + entity_field: changed + plugin_id: field + defaults: + fields: false + cache_metadata: + contexts: + - 'languages:language_interface' + - url + - url.query_args + cacheable: false + submitted: + display_plugin: embed + id: submitted + display_title: Submitted + position: 1 + display_options: + rendering_language: '***LANGUAGE_entity_default***' + display_extenders: { } + display_description: '' + cache_metadata: + contexts: + - 'languages:language_interface' + - url + - url.query_args + cacheable: false diff --git a/config/sync/views.view.tmgmt_job_messages.yml b/config/sync/views.view.tmgmt_job_messages.yml new file mode 100644 index 0000000000..6256d491ed --- /dev/null +++ b/config/sync/views.view.tmgmt_job_messages.yml @@ -0,0 +1,363 @@ +uuid: 0f855c49-9ead-4647-bd70-284dfde7bffe +langcode: en +status: true +dependencies: + module: + - tmgmt + - user +_core: + default_config_hash: Oc4rgGJ1UsWBRKlkWEX36de0R9bhbnGTY-x4DCCdN7k +id: tmgmt_job_messages +label: 'Translation Job messages' +module: views +description: '' +tag: '' +base_table: tmgmt_message +base_field: mid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 1 + display_options: + rendering_language: '***LANGUAGE_entity_default***' + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 10 + offset: 0 + id: 1 + total_pages: null + tags: + previous: '‹ previous' + next: 'next ›' + first: '« first' + last: 'last »' + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + pagination_heading_level: h4 + style: + type: table + row: + type: fields + fields: + created: + id: created + table: tmgmt_message + field: created + relationship: none + group_type: group + admin_label: '' + label: Created + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: null + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: html_date + custom_date_format: '' + timezone: '' + plugin_id: date + label: + id: label + table: tmgmt_job_item + field: label + relationship: tjiid + group_type: group + admin_label: '' + label: Item + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_entity: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label + message: + id: message + table: tmgmt_message + field: message + plugin_id: tmgmt_handler_field_tmgmt_message_message + exclude: false + name: + id: name + table: users_field_data + field: name + relationship: uid + group_type: group + admin_label: '' + label: Name + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: user_name + settings: + link_to_entity: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: user + entity_field: name + plugin_id: field + filters: { } + sorts: + created: + id: created + table: tmgmt_message + field: created + relationship: none + group_type: group + admin_label: '' + order: DESC + exposed: false + expose: + label: '' + granularity: second + entity_type: tmgmt_message + entity_field: created + plugin_id: date + title: Messages + header: { } + footer: { } + empty: + area: + id: area + table: views + field: area + relationship: none + group_type: group + admin_label: '' + empty: true + tokenize: false + content: + value: 'There are no messages yet in this Job.' + format: basic_html + plugin_id: text + relationships: + tjiid: + id: tjiid + table: tmgmt_message + field: tjiid + relationship: none + group_type: group + admin_label: 'Translation Job Item' + required: false + plugin_id: standard + uid: + id: uid + table: tmgmt_message + field: uid + relationship: none + group_type: group + admin_label: User + required: false + entity_type: tmgmt_message + entity_field: uid + plugin_id: standard + arguments: + tjid: + id: tjid + table: tmgmt_message + field: tjid + relationship: none + group_type: group + admin_label: '' + default_action: ignore + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: fixed + default_argument_options: + argument: '' + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: false + not: false + plugin_id: numeric + display_extenders: { } + cache_metadata: + contexts: + - 'languages:language_interface' + - url + - url.query_args + cacheable: false + max-age: 0 + tags: { } + embed: + display_plugin: embed + id: embed + display_title: Embed + position: 1 + display_options: + rendering_language: '***LANGUAGE_entity_default***' + display_extenders: { } + cache_metadata: + contexts: + - 'languages:language_interface' + - url + - url.query_args + cacheable: false + max-age: 0 + tags: { } diff --git a/config/sync/views.view.tmgmt_job_overview.yml b/config/sync/views.view.tmgmt_job_overview.yml new file mode 100644 index 0000000000..f2e10ed5d1 --- /dev/null +++ b/config/sync/views.view.tmgmt_job_overview.yml @@ -0,0 +1,949 @@ +uuid: 9488c0ad-14ef-4f59-a661-f7578392e547 +langcode: en +status: true +dependencies: + config: + - system.menu.admin + module: + - tmgmt +_core: + default_config_hash: vZFV4gb5A2TPJtl6SIsCJNP16rioI9hr7nRFRMU9CXw +id: tmgmt_job_overview +label: 'Job overview' +module: views +description: 'Gives a bulk operation overview of translation jobs in the system.' +tag: '' +base_table: tmgmt_job +base_field: tjid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 1 + display_options: + rendering_language: '***LANGUAGE_entity_default***' + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 20 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: '‹ previous' + next: 'next ›' + first: '« first' + last: 'last »' + quantity: 9 + pagination_heading_level: h4 + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + label: label + source_language_1: source_language_1 + state: state + target_language: target_language + translator: translator + progress: progress + word_count: word_count + changed: changed + operations: operations + info: + label: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + source_language_1: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + state: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + target_language: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + translator: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + progress: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + word_count: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + default: changed + empty_table: false + row: + type: fields + fields: + state: + id: state + table: tmgmt_job + field: state + relationship: none + group_type: group + admin_label: '' + label: State + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job + entity_field: state + plugin_id: field + label: + id: label + table: tmgmt_job + field: label + relationship: none + group_type: group + admin_label: '' + label: Label + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job + plugin_id: tmgmt_entity_label + source_language_1: + id: source_language_1 + table: tmgmt_job + field: source_language + relationship: none + group_type: group + admin_label: '' + label: From + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: language + settings: + link_to_entity: false + native_language: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job + entity_field: source_language + plugin_id: field + target_language: + id: target_language + table: tmgmt_job + field: target_language + relationship: none + group_type: group + admin_label: '' + label: To + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: language + settings: + link_to_entity: false + native_language: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job + entity_field: target_language + plugin_id: field + translator: + id: translator + table: tmgmt_job + field: translator + relationship: none + group_type: group + admin_label: '' + label: Provider + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job + entity_field: translator + plugin_id: tmgmt_translator + progress: + id: progress + table: tmgmt_job + field: progress + relationship: none + group_type: group + admin_label: '' + label: Progress + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job + plugin_id: tmgmt_progress + word_count: + id: word_count + table: tmgmt_job + field: word_count + relationship: none + group_type: group + admin_label: '' + label: Words + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job + plugin_id: tmgmt_wordcount + tags_count: + id: tags_count + table: tmgmt_job + field: tags_count + relationship: none + group_type: group + admin_label: '' + label: Tags + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job + plugin_id: tmgmt_tagscount + changed: + id: changed + table: tmgmt_job + field: changed + relationship: none + group_type: group + admin_label: '' + label: Changed + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: fallback + custom_date_format: '' + timezone: '' + entity_type: tmgmt_job + entity_field: changed + plugin_id: date + operations: + id: operations + table: tmgmt_job + field: operations + relationship: none + group_type: group + admin_label: '' + label: Operations + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + destination: true + entity_type: tmgmt_job + plugin_id: entity_operations + filters: + state: + id: state + table: tmgmt_job + field: state + relationship: none + group_type: group + admin_label: '' + operator: job_state + value: + value: open_jobs + group: 1 + exposed: true + expose: + operator_id: state_op + label: State + description: '' + use_operator: false + operator: state_op + identifier: state + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: tmgmt_job + plugin_id: numeric + source_language: + id: source_language + table: tmgmt_job + field: source_language + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: source_language_op + label: 'Source language' + description: '' + use_operator: false + operator: source_language_op + identifier: source_language + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: tmgmt_job + entity_field: source_language + plugin_id: language + target_language: + id: target_language + table: tmgmt_job + field: target_language + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: target_language_op + label: 'Target language' + description: '' + use_operator: false + operator: target_language_op + identifier: target_language + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: tmgmt_job + entity_field: target_language + plugin_id: language + translator: + id: translator + table: tmgmt_job + field: translator + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: translator_op + label: Provider + description: '' + use_operator: false + operator: translator_op + identifier: translator + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: tmgmt_job + entity_field: translator + plugin_id: in_operator + sorts: { } + title: 'Job overview' + header: { } + footer: + footer: + id: footer + table: tmgmt_job + field: footer + relationship: none + group_type: group + admin_label: '' + empty: false + entity_type: tmgmt_job + plugin_id: tmgmt_job_legend + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + relationship: none + group_type: group + admin_label: '' + empty: true + tokenize: false + content: 'No jobs available.' + plugin_id: text_custom + relationships: { } + arguments: { } + filter_groups: + operator: AND + groups: + 1: AND + display_extenders: { } + cache_metadata: + contexts: + - 'languages:language_interface' + - url + - url.query_args + cacheable: false + max-age: 0 + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + path: admin/tmgmt/jobs + rendering_language: '***LANGUAGE_entity_default***' + menu: + type: normal + title: Jobs + description: 'Manage and review existing translation jobs.' + parent: tmgmt.admin_tmgmt + weight: 10 + context: '0' + menu_name: admin + tab_options: + type: normal + title: Jobs + description: '' + weight: 0 + display_extenders: { } + cache_metadata: + contexts: + - 'languages:language_interface' + - url + - url.query_args + cacheable: false + max-age: 0 + tags: { } diff --git a/config/sync/views.view.tmgmt_translation_all_job_items.yml b/config/sync/views.view.tmgmt_translation_all_job_items.yml new file mode 100644 index 0000000000..5c4a871e85 --- /dev/null +++ b/config/sync/views.view.tmgmt_translation_all_job_items.yml @@ -0,0 +1,1013 @@ +uuid: 330aa0bd-9141-4cba-bad9-2a3bd15b9ced +langcode: en +status: true +dependencies: + config: + - system.menu.admin + module: + - tmgmt +_core: + default_config_hash: cgVpfZ9kESndXtn3A_cvyl71krium1lcTfyeOZmhsTo +id: tmgmt_translation_all_job_items +label: 'Translation All Job Items' +module: views +description: '' +tag: '' +base_table: tmgmt_job_item +base_field: tjiid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: '‹ Previous' + next: 'Next ›' + first: '« First' + last: 'Last »' + quantity: 9 + pagination_heading_level: h4 + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + label: label + type: type + source_language: source_language + target_language: target_language + state: state + progress: progress + word_count: word_count + tags_count: tags_count + changed: changed + operations: operations + info: + label: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + type: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + source_language: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + target_language: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + state: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + progress: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + word_count: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + tags_count: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: changed + empty_table: false + row: + type: fields + fields: + state: + id: state + table: tmgmt_job_item + field: state + relationship: none + group_type: group + admin_label: '' + label: State + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_state + label: + id: label + table: tmgmt_job_item + field: label + relationship: none + group_type: group + admin_label: '' + label: Label + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label + tjid: + id: tjid + table: tmgmt_job_item + field: tjid + entity_type: tmgmt_job_item + entity_field: tjid + plugin_id: field + type: + id: type + table: tmgmt_job_item + field: type + relationship: none + group_type: group + admin_label: '' + label: Type + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_type + source_language: + id: source_language + table: tmgmt_job + field: source_language + relationship: tjid + group_type: group + admin_label: '' + label: From + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: language + settings: + link_to_entity: false + native_language: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job + entity_field: source_language + plugin_id: field + target_language: + id: target_language + table: tmgmt_job + field: target_language + relationship: tjid + group_type: group + admin_label: '' + label: To + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: language + settings: + link_to_entity: false + native_language: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job + entity_field: target_language + plugin_id: field + progress: + id: progress + table: tmgmt_job_item + field: progress + relationship: none + group_type: group + admin_label: '' + label: Progress + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_progress + word_count: + id: word_count + table: tmgmt_job_item + field: word_count + relationship: none + group_type: group + admin_label: '' + label: Word + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job_item + entity_field: word_count + plugin_id: field + tags_count: + id: tags_count + table: tmgmt_job_item + field: tags_count + relationship: none + group_type: group + admin_label: '' + label: Tags + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job_item + entity_field: tags_count + plugin_id: field + changed: + id: changed + table: tmgmt_job_item + field: changed + relationship: none + group_type: group + admin_label: '' + label: Changed + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: timestamp + settings: + date_format: medium + custom_date_format: '' + timezone: '' + tooltip: + date_format: '' + custom_date_format: '' + time_diff: + enabled: false + future_format: '@interval hence' + past_format: '@interval ago' + granularity: 2 + refresh: 60 + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: tmgmt_job_item + entity_field: changed + plugin_id: field + operations: + id: operations + table: tmgmt_job_item + field: operations + relationship: none + group_type: group + admin_label: '' + label: Operations + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + destination: false + entity_type: null + entity_field: null + plugin_id: entity_operations + filters: + state: + id: state + table: tmgmt_job_item + field: state + relationship: none + group_type: group + admin_label: '' + operator: job_item_state + value: + 2: '2' + group: 1 + exposed: true + expose: + operator_id: state_op + label: States + description: '' + use_operator: false + operator: state_op + identifier: state + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + reduce: false + is_grouped: false + group_info: + label: State + description: '' + identifier: state + optional: true + widget: select + multiple: false + remember: false + default_group: '' + default_group_multiple: { } + group_items: { } + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_filter + source_language: + id: source_language + table: tmgmt_job + field: source_language + relationship: tjid + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: source_language_op + label: 'Source language' + description: '' + use_operator: false + operator: source_language_op + identifier: source_language + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: tmgmt_job + entity_field: source_language + plugin_id: language + target_language: + id: target_language + table: tmgmt_job + field: target_language + relationship: tjid + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: target_language_op + label: 'Target language' + description: '' + use_operator: false + operator: target_language_op + identifier: target_language + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: tmgmt_job + entity_field: target_language + plugin_id: language + job_type: + id: job_type + table: tmgmt_job + field: job_type + relationship: tjid + group_type: group + admin_label: '' + operator: '=' + group: 1 + exposed: true + expose: + operator_id: job_type_op + label: 'Job Type (Custom)' + description: null + use_operator: false + operator: job_type_op + identifier: job_type + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + hide_no_continuous: true + is_grouped: true + group_info: + label: 'Job type' + description: '' + identifier: job_type + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: + 1: + title: Normal + operator: '=' + value: + value: normal + 2: + title: Continuous + operator: '=' + value: + value: continuous + entity_type: tmgmt_job + plugin_id: tmgmt_job_type_filter + sorts: { } + title: 'Job Items' + header: { } + footer: + footer: + id: footer + table: tmgmt_job_item + field: footer + relationship: none + group_type: group + admin_label: '' + empty: true + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_legend + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + relationship: none + group_type: group + admin_label: '' + empty: true + tokenize: false + content: 'No job items for the current selection.' + plugin_id: text_custom + relationships: + tjid: + id: tjid + table: tmgmt_job_item + field: tjid + relationship: none + group_type: group + admin_label: 'Translation Job' + required: true + entity_type: tmgmt_job_item + entity_field: tjid + plugin_id: standard + arguments: { } + display_extenders: { } + filter_groups: + operator: AND + groups: + 1: AND + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: admin/tmgmt/job_items + menu: + type: normal + title: 'Job Items' + description: 'Overview of existing job items.' + expanded: false + parent: tmgmt.admin_tmgmt + weight: 5 + context: '0' + menu_name: admin + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + tags: { } -- GitLab From 0f987efa61471ef4040dcda4ec3967100dd7d7c1 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 9 Sep 2024 13:56:06 +0200 Subject: [PATCH 042/149] ISAICP-9002: Enable tmgmt_content. --- config/sync/core.extension.yml | 1 + config/sync/tmgmt.settings.yml | 4 ++-- config/sync/tmgmt_content.settings.yml | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 config/sync/tmgmt_content.settings.yml diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 664b3ae5e6..3dc37b0a49 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -243,6 +243,7 @@ module: text: 0 theme_rule: 0 tmgmt: 0 + tmgmt_content: 0 tmgmt_ec_etranslation: 0 token: 0 toolbar: 0 diff --git a/config/sync/tmgmt.settings.yml b/config/sync/tmgmt.settings.yml index e3f17b959d..a69a4ccb0b 100644 --- a/config/sync/tmgmt.settings.yml +++ b/config/sync/tmgmt.settings.yml @@ -3,9 +3,9 @@ _core: quick_checkout: true anonymous_access: true purge_finished: _never +respect_text_format: true +allowed_formats: { } word_count_exclude_tags: true source_list_limit: 20 -respect_text_format: true submit_job_item_on_cron: false job_items_cron_limit: 50 -allowed_formats: { } diff --git a/config/sync/tmgmt_content.settings.yml b/config/sync/tmgmt_content.settings.yml new file mode 100644 index 0000000000..c3646aee6f --- /dev/null +++ b/config/sync/tmgmt_content.settings.yml @@ -0,0 +1,4 @@ +_core: + default_config_hash: zJBQPBc6SKaZZvDCvMKeZm7_0CH-7OCtq92DRu-vuPs +embedded_fields: { } +default_moderation_states: { } -- GitLab From 7170022edaf6b09facb2773b9c80dd55e61927d1 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 9 Sep 2024 14:08:20 +0200 Subject: [PATCH 043/149] ISAICP-9002: Check permissions. --- tests/features/authentication.feature | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/features/authentication.feature b/tests/features/authentication.feature index ef1d62b70b..cb07f51948 100644 --- a/tests/features/authentication.feature +++ b/tests/features/authentication.feature @@ -45,6 +45,12 @@ Feature: User authentication | admin/structure/compatibility-document/display | | admin/structure/compatibility-document/form-display | | admin/structure/media | + | admin/tmgmt/job_items | + | admin/tmgmt/jobs | + | admin/tmgmt/sources | + | admin/tmgmt/cart | + | admin/tmgmt/translators | + | admin/tmgmt/settings | | announcements | | dashboard | | licence | @@ -129,6 +135,12 @@ Feature: User authentication | admin/structure/compatibility-document/display | | admin/structure/compatibility-document/form-display | | admin/structure/media | + | admin/tmgmt/job_items | + | admin/tmgmt/jobs | + | admin/tmgmt/sources | + | admin/tmgmt/cart | + | admin/tmgmt/translators | + | admin/tmgmt/settings | | announcements | | dashboard | | licence | @@ -223,6 +235,12 @@ Feature: User authentication | admin/structure/compatibility-document/display | | admin/structure/compatibility-document/form-display | | admin/structure/media | + | admin/tmgmt/job_items | + | admin/tmgmt/jobs | + | admin/tmgmt/sources | + | admin/tmgmt/cart | + | admin/tmgmt/translators | + | admin/tmgmt/settings | | node/add | | node/add/contact_information | | node/add/custom_page | -- GitLab From 22b425d3b3ab63e08e46b71ace816e4d48871618 Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Mon, 9 Sep 2024 16:23:45 +0200 Subject: [PATCH 044/149] ISAICP-9059: Move getActiveMemberCount to GroupInterface. --- .../custom/collection/src/Entity/CollectionInterface.php | 8 -------- .../custom/joinup_group/src/Entity/GroupInterface.php | 8 ++++++++ .../custom/solution/src/Entity/SolutionInterface.php | 8 -------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/web/modules/custom/collection/src/Entity/CollectionInterface.php b/web/modules/custom/collection/src/Entity/CollectionInterface.php index d756701f86..6ecc1e949c 100644 --- a/web/modules/custom/collection/src/Entity/CollectionInterface.php +++ b/web/modules/custom/collection/src/Entity/CollectionInterface.php @@ -30,14 +30,6 @@ interface CollectionInterface extends RdfInterface, EntityPublicationTimeInterfa */ public function getSolutions(bool $only_published = FALSE): array; - /** - * Returns the number of active members in this collection. - * - * @return int - * The number of active members. - */ - public function getActiveMemberCount(): int; - /** * Returns the IDs of the solutions that are affiliated with this collection. * diff --git a/web/modules/custom/joinup_group/src/Entity/GroupInterface.php b/web/modules/custom/joinup_group/src/Entity/GroupInterface.php index eb71c2ee63..052c7eb216 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupInterface.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupInterface.php @@ -379,4 +379,12 @@ public function getValidatedContactInformationEmails(): array; */ public function getWebsiteLinkFieldName(): string; + /** + * Returns the number of active members in this group. + * + * @return int + * The number of active members. + */ + public function getActiveMemberCount(): int; + } diff --git a/web/modules/custom/solution/src/Entity/SolutionInterface.php b/web/modules/custom/solution/src/Entity/SolutionInterface.php index 8501425043..b8c355a039 100644 --- a/web/modules/custom/solution/src/Entity/SolutionInterface.php +++ b/web/modules/custom/solution/src/Entity/SolutionInterface.php @@ -70,12 +70,4 @@ public function getAffiliatedCollections(): array; */ public function getAffiliatedCollectionIds(): array; - /** - * Returns the number of active members in this solution. - * - * @return int - * The number of active members. - */ - public function getActiveMemberCount(): int; - } -- GitLab From d857f0eb242a3fca5ca78b80c1f7d53933231170 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 9 Sep 2024 16:25:04 +0200 Subject: [PATCH 045/149] ISAICP-9002: Use latest version. --- composer.json | 2 +- composer.lock | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 09b66aff01..89ad171dc9 100644 --- a/composer.json +++ b/composer.json @@ -111,7 +111,7 @@ "drupal/svg_image": "^3.0", "drupal/symfony_mailer_lite": "^1.0", "drupal/theme_rule": "^1.0", - "drupal/tmgmt_ec_etranslation": "^1.0", + "drupal/tmgmt_ec_etranslation": "^1.1", "drupal/token": "~1.7", "drupal/video_embed_field": "^2", "drupal/view_unpublished": "^1.0", diff --git a/composer.lock b/composer.lock index 5cc3b30236..7e8aef38a6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "486747bcc153a93ce7eccf5be8985611", + "content-hash": "1d3ce595887470c71a55f78d705de8fe", "packages": [ { "name": "asm89/stack-cors", @@ -8900,27 +8900,31 @@ }, { "name": "drupal/tmgmt_ec_etranslation", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/tmgmt_ec_etranslation.git", - "reference": "1.0.0" + "reference": "1.1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/tmgmt_ec_etranslation-1.0.0.zip", - "reference": "1.0.0", - "shasum": "dbdae0176227b239bfff140467171480e080fde0" + "url": "https://ftp.drupal.org/files/projects/tmgmt_ec_etranslation-1.1.0.zip", + "reference": "1.1.0", + "shasum": "017703c1d307a53983140a1b3b090cd934ff4da3" }, "require": { - "drupal/core": "^8 || ^9 || ^10", - "drupal/tmgmt": "*" + "drupal/core": "^9.2 || ^10", + "drupal/tmgmt": "^1.5", + "php": ">=8.0" + }, + "require-dev": { + "drupal/http_request_mock": "^1.1" }, "type": "drupal-module", "extra": { "drupal": { - "version": "1.0.0", - "datestamp": "1685699050", + "version": "1.1.0", + "datestamp": "1725891728", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -8929,7 +8933,7 @@ }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0-or-later" + "GPL-2.0+" ], "authors": [ { @@ -8943,6 +8947,11 @@ ], "description": "TMGMT plugin for eTranslation, an online machine translation service provided by the European Commission (EC).", "homepage": "https://www.drupal.org/project/tmgmt_ec_etranslation", + "keywords": [ + "Drupal", + "tmgmt", + "translation" + ], "support": { "source": "https://git.drupalcode.org/project/tmgmt_ec_etranslation" } -- GitLab From 376f4f085236744fa0cd8c32d0cbadd9f16dba12 Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Mon, 9 Sep 2024 16:25:05 +0200 Subject: [PATCH 046/149] ISAICP-9059: Remove static caching attempt (follow up in ISAICP-8949). --- .../custom/joinup_group/src/Entity/GroupTrait.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php index fb11c4bcb1..6038011cdd 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php @@ -25,13 +25,6 @@ trait GroupTrait { use OutdatedContentTrait; - /** - * The number of active members. - * - * @var int - */ - protected $activeMemberCount; - /** * {@inheritdoc} */ @@ -335,10 +328,6 @@ protected function getMembershipManager(): MembershipManagerInterface { * {@inheritdoc} */ public function getActiveMemberCount(): int { - if (isset($this->activeMemberCount)) { - return $this->activeMemberCount; - } - // We're doing a direct database query rather than using methods in OG's // MembershipManager service since we just need a count, and we need to // filter out blocked user accounts. -- GitLab From 2fac0f4088c0987a00b58e52c99fd0950be6a21b Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 10 Sep 2024 07:59:59 +0200 Subject: [PATCH 047/149] ISAICP-9002: Dave and reexport configuration. --- ...ntent_subscription.field_group_content.yml | 21 +- config/sync/views.view.tmgmt_job_items.yml | 346 +++++++------- config/sync/views.view.tmgmt_job_messages.yml | 204 ++++----- config/sync/views.view.tmgmt_job_overview.yml | 404 ++++++++-------- ...s.view.tmgmt_translation_all_job_items.yml | 432 +++++++++--------- 5 files changed, 713 insertions(+), 694 deletions(-) diff --git a/config/sync/field.field.message.group_content_subscription.field_group_content.yml b/config/sync/field.field.message.group_content_subscription.field_group_content.yml index d769750d88..f7f379c098 100644 --- a/config/sync/field.field.message.group_content_subscription.field_group_content.yml +++ b/config/sync/field.field.message.group_content_subscription.field_group_content.yml @@ -79,6 +79,9 @@ settings: entity_subqueue: handler: 'default:entity_subqueue' handler_settings: { } + hosting_platform: + handler: 'default:hosting_platform' + handler_settings: { } facets_facet: handler: 'default:facets_facet' handler_settings: { } @@ -112,9 +115,6 @@ settings: geocoder_provider: handler: 'default:geocoder_provider' handler_settings: { } - hosting_platform: - handler: 'default:hosting_platform' - handler_settings: { } image_style: handler: 'default:image_style' handler_settings: { } @@ -274,6 +274,21 @@ settings: theme_rule: handler: 'default:theme_rule' handler_settings: { } + tmgmt_job: + handler: 'default:tmgmt_job' + handler_settings: { } + tmgmt_message: + handler: 'default:tmgmt_message' + handler_settings: { } + tmgmt_remote: + handler: 'default:tmgmt_remote' + handler_settings: { } + tmgmt_translator: + handler: 'default:tmgmt_translator' + handler_settings: { } + tmgmt_job_item: + handler: 'default:tmgmt_job_item' + handler_settings: { } tour: handler: 'default:tour' handler_settings: { } diff --git a/config/sync/views.view.tmgmt_job_items.yml b/config/sync/views.view.tmgmt_job_items.yml index 6e04e95808..07b4757173 100644 --- a/config/sync/views.view.tmgmt_job_items.yml +++ b/config/sync/views.view.tmgmt_job_items.yml @@ -15,130 +15,12 @@ base_table: tmgmt_job_item base_field: tjiid display: default: - display_plugin: default id: default display_title: Master + display_plugin: default position: 1 display_options: - rendering_language: '***LANGUAGE_entity_default***' - access: - type: tmgmt_job - options: { } - cache: - type: none - options: { } - query: - type: views_query - options: - disable_sql_rewrite: false - distinct: false - query_comment: '' - query_tags: { } - exposed_form: - type: basic - options: - submit_button: Apply - reset_button: false - reset_button_label: Reset - exposed_sorts_label: 'Sort by' - expose_sort_order: true - sort_asc_label: Asc - sort_desc_label: Desc - pager: - type: full - options: - items_per_page: 10 - offset: 0 - id: 0 - total_pages: null - expose: - items_per_page: false - items_per_page_label: 'Items per page' - items_per_page_options: '5, 10, 20, 40, 60' - items_per_page_options_all: false - items_per_page_options_all_label: '- All -' - offset: false - offset_label: Offset - tags: - previous: '‹ previous' - next: 'next ›' - first: '« first' - last: 'last »' - quantity: 9 - pagination_heading_level: h4 - style: - type: table - options: - grouping: { } - row_class: '' - default_row_class: true - override: true - sticky: false - caption: '' - summary: '' - description: '' - columns: - label: label - type: type - state: state - progress: progress - word_count: word_count - changed: changed - operations: operations - info: - label: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - type: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - state: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - progress: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - word_count: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - changed: - sortable: true - default_sort_order: desc - align: '' - separator: '' - empty_column: false - responsive: '' - operations: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - default: changed - empty_table: false - row: - type: fields + title: 'Job Items' fields: state: id: state @@ -147,6 +29,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: state + plugin_id: machine_name label: State exclude: false alter: @@ -189,9 +74,6 @@ display: empty_zero: false hide_alter_empty: true machine_name: false - entity_type: tmgmt_job_item - entity_field: state - plugin_id: machine_name label: id: label table: tmgmt_job_item @@ -199,6 +81,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label label: Label exclude: false alter: @@ -240,8 +124,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_entity_label type: id: type table: tmgmt_job_item @@ -249,6 +131,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_type label: Type exclude: false alter: @@ -290,8 +174,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_job_item_type progress: id: progress table: tmgmt_job_item @@ -299,6 +181,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_progress label: Progress exclude: false alter: @@ -340,8 +224,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_progress word_count: id: word_count table: tmgmt_job_item @@ -349,6 +231,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: word_count + plugin_id: field label: Words exclude: false alter: @@ -405,9 +290,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job_item - entity_field: word_count - plugin_id: field tags_count: id: tags_count table: tmgmt_job_item @@ -415,6 +297,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: tags_count + plugin_id: field label: Tags exclude: false alter: @@ -471,9 +356,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job_item - entity_field: tags_count - plugin_id: field changed: id: changed table: tmgmt_job_item @@ -481,6 +363,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: changed + plugin_id: date label: Changed exclude: false alter: @@ -525,9 +410,6 @@ display: date_format: fallback custom_date_format: '' timezone: '' - entity_type: tmgmt_job_item - entity_field: changed - plugin_id: date operations: id: operations table: tmgmt_job_item @@ -535,6 +417,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: entity_operations label: Operations exclude: false alter: @@ -577,13 +461,44 @@ display: empty_zero: false hide_alter_empty: true destination: false - entity_type: tmgmt_job_item - plugin_id: entity_operations - filters: { } - sorts: { } - title: 'Job Items' - header: { } - footer: { } + pager: + type: full + options: + offset: 0 + pagination_heading_level: h4 + items_per_page: 10 + total_pages: null + id: 0 + tags: + next: 'next ›' + previous: '‹ previous' + first: '« first' + last: 'last »' + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } empty: area: id: area @@ -592,13 +507,13 @@ display: relationship: none group_type: group admin_label: '' + plugin_id: text empty: true - tokenize: false content: value: 'There are no items attached to this translation job.' format: basic_html - plugin_id: text - relationships: { } + tokenize: false + sorts: { } arguments: tjid: id: tjid @@ -607,6 +522,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: tjid + plugin_id: numeric default_action: 'not found' exception: value: all @@ -620,8 +538,8 @@ display: summary_options: base_path: '' count: true - items_per_page: 25 override: false + items_per_page: 25 summary: sort_order: asc number_of_records: 0 @@ -632,28 +550,107 @@ display: fail: 'not found' break_phrase: false not: false - entity_type: tmgmt_job_item - entity_field: tjid - plugin_id: numeric - display_extenders: { } + filters: { } + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + columns: + label: label + type: type + state: state + progress: progress + word_count: word_count + changed: changed + operations: operations + default: changed + info: + label: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + type: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + state: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + progress: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + word_count: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + override: true + sticky: false + summary: '' + empty_table: false + caption: '' + description: '' + row: + type: fields + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + query_tags: { } + relationships: { } use_ajax: true + header: { } + footer: { } + rendering_language: '***LANGUAGE_entity_default***' + display_extenders: { } cache_metadata: + max-age: -1 contexts: - 'languages:language_interface' - url - url.query_args - cacheable: false - max-age: 0 tags: { } + cacheable: false checkout: - display_plugin: embed id: checkout display_title: Checkout + display_plugin: embed position: 2 display_options: - display_extenders: { } - display_description: '' - rendering_language: '***LANGUAGE_entity_default***' fields: label: id: label @@ -662,6 +659,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label label: Label exclude: false alter: @@ -703,8 +702,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_entity_label type: id: type table: tmgmt_job_item @@ -712,6 +709,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_type label: Type exclude: false alter: @@ -753,8 +752,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_job_item_type word_count: id: word_count table: tmgmt_job_item @@ -762,6 +759,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: word_count + plugin_id: field label: Words exclude: false alter: @@ -818,9 +818,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job_item - entity_field: word_count - plugin_id: field changed: id: changed table: tmgmt_job_item @@ -828,6 +825,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: changed + plugin_id: field label: Changed exclude: true alter: @@ -894,29 +894,33 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job_item - entity_field: changed - plugin_id: field defaults: fields: false + display_description: '' + rendering_language: '***LANGUAGE_entity_default***' + display_extenders: { } cache_metadata: + max-age: -1 contexts: - 'languages:language_interface' - url - url.query_args + tags: { } cacheable: false submitted: - display_plugin: embed id: submitted display_title: Submitted + display_plugin: embed position: 1 display_options: + display_description: '' rendering_language: '***LANGUAGE_entity_default***' display_extenders: { } - display_description: '' cache_metadata: + max-age: -1 contexts: - 'languages:language_interface' - url - url.query_args + tags: { } cacheable: false diff --git a/config/sync/views.view.tmgmt_job_messages.yml b/config/sync/views.view.tmgmt_job_messages.yml index 6256d491ed..a9c257563e 100644 --- a/config/sync/views.view.tmgmt_job_messages.yml +++ b/config/sync/views.view.tmgmt_job_messages.yml @@ -16,61 +16,12 @@ base_table: tmgmt_message base_field: mid display: default: - display_plugin: default id: default display_title: Master + display_plugin: default position: 1 display_options: - rendering_language: '***LANGUAGE_entity_default***' - access: - type: tmgmt_job - options: { } - cache: - type: none - options: { } - query: - type: views_query - options: - disable_sql_rewrite: false - distinct: false - query_comment: '' - query_tags: { } - exposed_form: - type: basic - options: - submit_button: Apply - reset_button: false - reset_button_label: Reset - exposed_sorts_label: 'Sort by' - expose_sort_order: true - sort_asc_label: Asc - sort_desc_label: Desc - pager: - type: full - options: - items_per_page: 10 - offset: 0 - id: 1 - total_pages: null - tags: - previous: '‹ previous' - next: 'next ›' - first: '« first' - last: 'last »' - expose: - items_per_page: false - items_per_page_label: 'Items per page' - items_per_page_options: '5, 10, 20, 40, 60' - items_per_page_options_all: false - items_per_page_options_all_label: '- All -' - offset: false - offset_label: Offset - quantity: 9 - pagination_heading_level: h4 - style: - type: table - row: - type: fields + title: Messages fields: created: id: created @@ -79,6 +30,7 @@ display: relationship: none group_type: group admin_label: '' + plugin_id: date label: Created exclude: false alter: @@ -123,7 +75,6 @@ display: date_format: html_date custom_date_format: '' timezone: '' - plugin_id: date label: id: label table: tmgmt_job_item @@ -131,6 +82,8 @@ display: relationship: tjiid group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label label: Item exclude: false alter: @@ -173,8 +126,6 @@ display: empty_zero: false hide_alter_empty: true link_to_entity: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_entity_label message: id: message table: tmgmt_message @@ -188,6 +139,9 @@ display: relationship: uid group_type: group admin_label: '' + entity_type: user + entity_field: name + plugin_id: field label: Name exclude: false alter: @@ -243,29 +197,44 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: user - entity_field: name - plugin_id: field - filters: { } - sorts: - created: - id: created - table: tmgmt_message - field: created - relationship: none - group_type: group - admin_label: '' - order: DESC - exposed: false + pager: + type: full + options: + offset: 0 + pagination_heading_level: h4 + items_per_page: 10 + total_pages: null + id: 1 + tags: + next: 'next ›' + previous: '‹ previous' + first: '« first' + last: 'last »' expose: - label: '' - granularity: second - entity_type: tmgmt_message - entity_field: created - plugin_id: date - title: Messages - header: { } - footer: { } + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } empty: area: id: area @@ -274,33 +243,28 @@ display: relationship: none group_type: group admin_label: '' + plugin_id: text empty: true - tokenize: false content: value: 'There are no messages yet in this Job.' format: basic_html - plugin_id: text - relationships: - tjiid: - id: tjiid - table: tmgmt_message - field: tjiid - relationship: none - group_type: group - admin_label: 'Translation Job Item' - required: false - plugin_id: standard - uid: - id: uid + tokenize: false + sorts: + created: + id: created table: tmgmt_message - field: uid + field: created relationship: none group_type: group - admin_label: User - required: false + admin_label: '' entity_type: tmgmt_message - entity_field: uid - plugin_id: standard + entity_field: created + plugin_id: date + order: DESC + expose: + label: '' + exposed: false + granularity: second arguments: tjid: id: tjid @@ -309,6 +273,7 @@ display: relationship: none group_type: group admin_label: '' + plugin_id: numeric default_action: ignore exception: value: all @@ -322,8 +287,8 @@ display: summary_options: base_path: '' count: true - items_per_page: 25 override: false + items_per_page: 25 summary: sort_order: asc number_of_records: 0 @@ -335,29 +300,64 @@ display: validate_options: { } break_phrase: false not: false - plugin_id: numeric + filters: { } + style: + type: table + row: + type: fields + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + query_tags: { } + relationships: + tjiid: + id: tjiid + table: tmgmt_message + field: tjiid + relationship: none + group_type: group + admin_label: 'Translation Job Item' + plugin_id: standard + required: false + uid: + id: uid + table: tmgmt_message + field: uid + relationship: none + group_type: group + admin_label: User + entity_type: tmgmt_message + entity_field: uid + plugin_id: standard + required: false + header: { } + footer: { } + rendering_language: '***LANGUAGE_entity_default***' display_extenders: { } cache_metadata: + max-age: -1 contexts: - 'languages:language_interface' - url - url.query_args - cacheable: false - max-age: 0 tags: { } + cacheable: false embed: - display_plugin: embed id: embed display_title: Embed + display_plugin: embed position: 1 display_options: rendering_language: '***LANGUAGE_entity_default***' display_extenders: { } cache_metadata: + max-age: -1 contexts: - 'languages:language_interface' - url - url.query_args - cacheable: false - max-age: 0 tags: { } + cacheable: false diff --git a/config/sync/views.view.tmgmt_job_overview.yml b/config/sync/views.view.tmgmt_job_overview.yml index f2e10ed5d1..a6f82f5b6f 100644 --- a/config/sync/views.view.tmgmt_job_overview.yml +++ b/config/sync/views.view.tmgmt_job_overview.yml @@ -17,146 +17,12 @@ base_table: tmgmt_job base_field: tjid display: default: - display_plugin: default id: default display_title: Master + display_plugin: default position: 1 display_options: - rendering_language: '***LANGUAGE_entity_default***' - access: - type: tmgmt_job - options: { } - cache: - type: none - options: { } - query: - type: views_query - options: - disable_sql_rewrite: false - distinct: false - query_comment: '' - query_tags: { } - exposed_form: - type: basic - options: - submit_button: Apply - reset_button: false - reset_button_label: Reset - exposed_sorts_label: 'Sort by' - expose_sort_order: true - sort_asc_label: Asc - sort_desc_label: Desc - pager: - type: full - options: - items_per_page: 20 - offset: 0 - id: 0 - total_pages: null - expose: - items_per_page: false - items_per_page_label: 'Items per page' - items_per_page_options: '5, 10, 20, 40, 60' - items_per_page_options_all: false - items_per_page_options_all_label: '- All -' - offset: false - offset_label: Offset - tags: - previous: '‹ previous' - next: 'next ›' - first: '« first' - last: 'last »' - quantity: 9 - pagination_heading_level: h4 - style: - type: table - options: - grouping: { } - row_class: '' - default_row_class: true - override: true - sticky: false - caption: '' - summary: '' - description: '' - columns: - label: label - source_language_1: source_language_1 - state: state - target_language: target_language - translator: translator - progress: progress - word_count: word_count - changed: changed - operations: operations - info: - label: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - source_language_1: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - state: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - target_language: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - translator: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - progress: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - word_count: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - changed: - sortable: true - default_sort_order: desc - align: '' - separator: '' - empty_column: false - responsive: '' - operations: - sortable: false - default_sort_order: desc - align: '' - separator: '' - empty_column: false - responsive: '' - default: changed - empty_table: false - row: - type: fields + title: 'Job overview' fields: state: id: state @@ -165,6 +31,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: state + plugin_id: field label: State exclude: false alter: @@ -221,9 +90,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job - entity_field: state - plugin_id: field label: id: label table: tmgmt_job @@ -231,6 +97,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + plugin_id: tmgmt_entity_label label: Label exclude: false alter: @@ -272,8 +140,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job - plugin_id: tmgmt_entity_label source_language_1: id: source_language_1 table: tmgmt_job @@ -281,6 +147,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: source_language + plugin_id: field label: From exclude: false alter: @@ -337,9 +206,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job - entity_field: source_language - plugin_id: field target_language: id: target_language table: tmgmt_job @@ -347,6 +213,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: target_language + plugin_id: field label: To exclude: false alter: @@ -403,9 +272,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job - entity_field: target_language - plugin_id: field translator: id: translator table: tmgmt_job @@ -413,6 +279,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: translator + plugin_id: tmgmt_translator label: Provider exclude: false alter: @@ -454,9 +323,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job - entity_field: translator - plugin_id: tmgmt_translator progress: id: progress table: tmgmt_job @@ -464,6 +330,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + plugin_id: tmgmt_progress label: Progress exclude: false alter: @@ -505,8 +373,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job - plugin_id: tmgmt_progress word_count: id: word_count table: tmgmt_job @@ -514,6 +380,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + plugin_id: tmgmt_wordcount label: Words exclude: false alter: @@ -555,8 +423,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job - plugin_id: tmgmt_wordcount tags_count: id: tags_count table: tmgmt_job @@ -564,6 +430,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + plugin_id: tmgmt_tagscount label: Tags exclude: false alter: @@ -605,8 +473,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job - plugin_id: tmgmt_tagscount changed: id: changed table: tmgmt_job @@ -614,6 +480,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: changed + plugin_id: date label: Changed exclude: false alter: @@ -658,9 +527,6 @@ display: date_format: fallback custom_date_format: '' timezone: '' - entity_type: tmgmt_job - entity_field: changed - plugin_id: date operations: id: operations table: tmgmt_job @@ -668,6 +534,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + plugin_id: entity_operations label: Operations exclude: false alter: @@ -710,8 +578,58 @@ display: empty_zero: false hide_alter_empty: true destination: true - entity_type: tmgmt_job - plugin_id: entity_operations + pager: + type: full + options: + offset: 0 + pagination_heading_level: h4 + items_per_page: 20 + total_pages: null + id: 0 + tags: + next: 'next ›' + previous: '‹ previous' + first: '« first' + last: 'last »' + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + relationship: none + group_type: group + admin_label: '' + plugin_id: text_custom + empty: true + content: 'No jobs available.' + tokenize: false + sorts: { } + arguments: { } filters: state: id: state @@ -720,6 +638,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + plugin_id: numeric operator: job_state value: value: open_jobs @@ -751,8 +671,6 @@ display: default_group: All default_group_multiple: { } group_items: { } - entity_type: tmgmt_job - plugin_id: numeric source_language: id: source_language table: tmgmt_job @@ -760,6 +678,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: source_language + plugin_id: language operator: in value: { } group: 1 @@ -791,9 +712,6 @@ display: default_group: All default_group_multiple: { } group_items: { } - entity_type: tmgmt_job - entity_field: source_language - plugin_id: language target_language: id: target_language table: tmgmt_job @@ -801,6 +719,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: target_language + plugin_id: language operator: in value: { } group: 1 @@ -832,9 +753,6 @@ display: default_group: All default_group_multiple: { } group_items: { } - entity_type: tmgmt_job - entity_field: target_language - plugin_id: language translator: id: translator table: tmgmt_job @@ -842,6 +760,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: translator + plugin_id: in_operator operator: in value: { } group: 1 @@ -873,11 +794,107 @@ display: default_group: All default_group_multiple: { } group_items: { } - entity_type: tmgmt_job - entity_field: translator - plugin_id: in_operator - sorts: { } - title: 'Job overview' + filter_groups: + operator: AND + groups: + 1: AND + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + columns: + label: label + source_language_1: source_language_1 + state: state + target_language: target_language + translator: translator + progress: progress + word_count: word_count + changed: changed + operations: operations + default: changed + info: + label: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + source_language_1: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + state: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + target_language: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + translator: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + progress: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + word_count: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + override: true + sticky: false + summary: '' + empty_table: false + caption: '' + description: '' + row: + type: fields + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + query_tags: { } + relationships: { } header: { } footer: footer: @@ -887,63 +904,46 @@ display: relationship: none group_type: group admin_label: '' - empty: false entity_type: tmgmt_job plugin_id: tmgmt_job_legend - empty: - area_text_custom: - id: area_text_custom - table: views - field: area_text_custom - relationship: none - group_type: group - admin_label: '' - empty: true - tokenize: false - content: 'No jobs available.' - plugin_id: text_custom - relationships: { } - arguments: { } - filter_groups: - operator: AND - groups: - 1: AND + empty: false + rendering_language: '***LANGUAGE_entity_default***' display_extenders: { } cache_metadata: + max-age: -1 contexts: - 'languages:language_interface' - url - url.query_args - cacheable: false - max-age: 0 tags: { } + cacheable: false page_1: - display_plugin: page id: page_1 display_title: Page + display_plugin: page position: 1 display_options: - path: admin/tmgmt/jobs rendering_language: '***LANGUAGE_entity_default***' + display_extenders: { } + path: admin/tmgmt/jobs menu: type: normal title: Jobs description: 'Manage and review existing translation jobs.' - parent: tmgmt.admin_tmgmt weight: 10 - context: '0' menu_name: admin + parent: tmgmt.admin_tmgmt + context: '0' tab_options: type: normal title: Jobs description: '' weight: 0 - display_extenders: { } cache_metadata: + max-age: -1 contexts: - 'languages:language_interface' - url - url.query_args - cacheable: false - max-age: 0 tags: { } + cacheable: false diff --git a/config/sync/views.view.tmgmt_translation_all_job_items.yml b/config/sync/views.view.tmgmt_translation_all_job_items.yml index 5c4a871e85..2b8dd135ac 100644 --- a/config/sync/views.view.tmgmt_translation_all_job_items.yml +++ b/config/sync/views.view.tmgmt_translation_all_job_items.yml @@ -17,154 +17,12 @@ base_table: tmgmt_job_item base_field: tjiid display: default: - display_plugin: default id: default display_title: Master + display_plugin: default position: 0 display_options: - access: - type: tmgmt_job - options: { } - cache: - type: none - options: { } - query: - type: views_query - options: - disable_sql_rewrite: false - distinct: false - replica: false - query_comment: '' - query_tags: { } - exposed_form: - type: basic - options: - submit_button: Apply - reset_button: false - reset_button_label: Reset - exposed_sorts_label: 'Sort by' - expose_sort_order: true - sort_asc_label: Asc - sort_desc_label: Desc - pager: - type: full - options: - items_per_page: 10 - offset: 0 - id: 0 - total_pages: null - expose: - items_per_page: false - items_per_page_label: 'Items per page' - items_per_page_options: '5, 10, 25, 50' - items_per_page_options_all: false - items_per_page_options_all_label: '- All -' - offset: false - offset_label: Offset - tags: - previous: '‹ Previous' - next: 'Next ›' - first: '« First' - last: 'Last »' - quantity: 9 - pagination_heading_level: h4 - style: - type: table - options: - grouping: { } - row_class: '' - default_row_class: true - override: true - sticky: false - caption: '' - summary: '' - description: '' - columns: - label: label - type: type - source_language: source_language - target_language: target_language - state: state - progress: progress - word_count: word_count - tags_count: tags_count - changed: changed - operations: operations - info: - label: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - type: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - source_language: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - target_language: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - state: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - progress: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - word_count: - sortable: true - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - tags_count: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - changed: - sortable: true - default_sort_order: desc - align: '' - separator: '' - empty_column: false - responsive: '' - operations: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - default: changed - empty_table: false - row: - type: fields + title: 'Job Items' fields: state: id: state @@ -173,6 +31,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_state label: State exclude: false alter: @@ -214,8 +74,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_job_item_state label: id: label table: tmgmt_job_item @@ -223,6 +81,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_entity_label label: Label exclude: false alter: @@ -264,8 +124,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_entity_label tjid: id: tjid table: tmgmt_job_item @@ -280,6 +138,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_type label: Type exclude: false alter: @@ -321,8 +181,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_job_item_type source_language: id: source_language table: tmgmt_job @@ -330,6 +188,9 @@ display: relationship: tjid group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: source_language + plugin_id: field label: From exclude: false alter: @@ -386,9 +247,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job - entity_field: source_language - plugin_id: field target_language: id: target_language table: tmgmt_job @@ -396,6 +254,9 @@ display: relationship: tjid group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: target_language + plugin_id: field label: To exclude: false alter: @@ -452,9 +313,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job - entity_field: target_language - plugin_id: field progress: id: progress table: tmgmt_job_item @@ -462,6 +320,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_progress label: Progress exclude: false alter: @@ -503,8 +363,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: tmgmt_job_item - plugin_id: tmgmt_progress word_count: id: word_count table: tmgmt_job_item @@ -512,6 +370,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: word_count + plugin_id: field label: Word exclude: false alter: @@ -568,9 +429,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job_item - entity_field: word_count - plugin_id: field tags_count: id: tags_count table: tmgmt_job_item @@ -578,6 +436,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: tags_count + plugin_id: field label: Tags exclude: false alter: @@ -634,9 +495,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job_item - entity_field: tags_count - plugin_id: field changed: id: changed table: tmgmt_job_item @@ -644,6 +502,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + entity_field: changed + plugin_id: field label: Changed exclude: false alter: @@ -710,9 +571,6 @@ display: multi_type: separator separator: ', ' field_api_classes: false - entity_type: tmgmt_job_item - entity_field: changed - plugin_id: field operations: id: operations table: tmgmt_job_item @@ -720,6 +578,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: null + entity_field: null + plugin_id: entity_operations label: Operations exclude: false alter: @@ -762,9 +623,58 @@ display: empty_zero: false hide_alter_empty: true destination: false - entity_type: null - entity_field: null - plugin_id: entity_operations + pager: + type: full + options: + offset: 0 + pagination_heading_level: h4 + items_per_page: 10 + total_pages: null + id: 0 + tags: + next: 'Next ›' + previous: '‹ Previous' + first: '« First' + last: 'Last »' + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: tmgmt_job + options: { } + cache: + type: none + options: { } + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + relationship: none + group_type: group + admin_label: '' + plugin_id: text_custom + empty: true + content: 'No job items for the current selection.' + tokenize: false + sorts: { } + arguments: { } filters: state: id: state @@ -773,6 +683,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: tmgmt_job_item + plugin_id: tmgmt_job_item_filter operator: job_item_state value: 2: '2' @@ -803,8 +715,6 @@ display: default_group: '' default_group_multiple: { } group_items: { } - entity_type: tmgmt_job_item - plugin_id: tmgmt_job_item_filter source_language: id: source_language table: tmgmt_job @@ -812,6 +722,9 @@ display: relationship: tjid group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: source_language + plugin_id: language operator: in value: { } group: 1 @@ -843,9 +756,6 @@ display: default_group: All default_group_multiple: { } group_items: { } - entity_type: tmgmt_job - entity_field: source_language - plugin_id: language target_language: id: target_language table: tmgmt_job @@ -853,6 +763,9 @@ display: relationship: tjid group_type: group admin_label: '' + entity_type: tmgmt_job + entity_field: target_language + plugin_id: language operator: in value: { } group: 1 @@ -884,9 +797,6 @@ display: default_group: All default_group_multiple: { } group_items: { } - entity_type: tmgmt_job - entity_field: target_language - plugin_id: language job_type: id: job_type table: tmgmt_job @@ -894,6 +804,8 @@ display: relationship: tjid group_type: group admin_label: '' + entity_type: tmgmt_job + plugin_id: tmgmt_job_type_filter operator: '=' group: 1 exposed: true @@ -932,10 +844,127 @@ display: operator: '=' value: value: continuous - entity_type: tmgmt_job - plugin_id: tmgmt_job_type_filter - sorts: { } - title: 'Job Items' + filter_groups: + operator: AND + groups: + 1: AND + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + columns: + label: label + type: type + source_language: source_language + target_language: target_language + state: state + progress: progress + word_count: word_count + tags_count: tags_count + changed: changed + operations: operations + default: changed + info: + label: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + type: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + source_language: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + target_language: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + state: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + progress: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + word_count: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + tags_count: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + override: true + sticky: false + summary: '' + empty_table: false + caption: '' + description: '' + row: + type: fields + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + replica: false + query_tags: { } + relationships: + tjid: + id: tjid + table: tmgmt_job_item + field: tjid + relationship: none + group_type: group + admin_label: 'Translation Job' + entity_type: tmgmt_job_item + entity_field: tjid + plugin_id: standard + required: true header: { } footer: footer: @@ -945,41 +974,12 @@ display: relationship: none group_type: group admin_label: '' - empty: true entity_type: tmgmt_job_item plugin_id: tmgmt_job_item_legend - empty: - area_text_custom: - id: area_text_custom - table: views - field: area_text_custom - relationship: none - group_type: group - admin_label: '' empty: true - tokenize: false - content: 'No job items for the current selection.' - plugin_id: text_custom - relationships: - tjid: - id: tjid - table: tmgmt_job_item - field: tjid - relationship: none - group_type: group - admin_label: 'Translation Job' - required: true - entity_type: tmgmt_job_item - entity_field: tjid - plugin_id: standard - arguments: { } display_extenders: { } - filter_groups: - operator: AND - groups: - 1: AND cache_metadata: - max-age: 0 + max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' @@ -987,9 +987,9 @@ display: - url.query_args tags: { } page_1: - display_plugin: page id: page_1 display_title: Page + display_plugin: page position: 1 display_options: display_extenders: { } @@ -998,13 +998,13 @@ display: type: normal title: 'Job Items' description: 'Overview of existing job items.' + weight: 5 expanded: false + menu_name: admin parent: tmgmt.admin_tmgmt - weight: 5 context: '0' - menu_name: admin cache_metadata: - max-age: 0 + max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' -- GitLab From f136d5d75c6cae4d02011f269caaab60a306d5c1 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 10 Sep 2024 09:05:32 +0200 Subject: [PATCH 048/149] ISAICP-9002: European Commission eTranslation credentials. --- .env.example | 6 ++++++ resources/runner/drupal.yml | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/.env.example b/.env.example index ad74c13ac9..065177b5e2 100644 --- a/.env.example +++ b/.env.example @@ -18,3 +18,9 @@ NEXTCLOUD_PASS= # The GitHub token. Generate a personal access token if you want to be able to # use the GitHub feed paragraph. JOINUP_GITHUB_TOKEN= + +# European Commission eTranslation credentials. These settings are used +# to provide functionality for creating and managing translation jobs, +# sending them to the eTranslation service, and retrieving translations. +TMGMT_ETRANSLATION_USERNAME= +TMGMT_ETRANSLATION_PASSWORD= diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml index 883e0cc29c..5966fe46a6 100644 --- a/resources/runner/drupal.yml +++ b/resources/runner/drupal.yml @@ -33,6 +33,7 @@ drupal: - RDF backend - Configuration - Search API + - European Commission eTranslation - OpenEuropa Webtools Analytics - OpenEuropa Newsroom Newsletter Settings - Custom error handler @@ -45,6 +46,7 @@ drupal: - RDF backend - Configuration - Search API + - European Commission eTranslation - OpenEuropa Webtools Analytics - OpenEuropa Newsroom Newsletter Settings - Custom error handler @@ -64,6 +66,7 @@ drupal: - RDF backend - Configuration - Search API + - European Commission eTranslation - OpenEuropa Webtools Analytics - Custom error handler - Permissions @@ -85,6 +88,7 @@ drupal: - Configuration - Testing configuration alters - Search API + - European Commission eTranslation - OpenEuropa Webtools Analytics - Custom error handler - Permissions @@ -104,6 +108,7 @@ drupal: - RDF backend - Configuration - Search API + - European Commission eTranslation - OpenEuropa Webtools Analytics - Custom error handler - Permissions @@ -124,6 +129,7 @@ drupal: - RDF backend - Configuration - Search API + - European Commission eTranslation - OpenEuropa Webtools Analytics - Custom error handler - Permissions @@ -144,6 +150,7 @@ drupal: - Configuration - Search API - OpenEuropa Newsroom Newsletter Settings + - European Commission eTranslation - OpenEuropa Webtools Analytics - GitHub Token Setup - Custom error handler @@ -318,6 +325,9 @@ drupal: // @see \Joinup\TaskRunner\Commands\SolrCommands::getUrl() $config['search_api.server.joinup']['backend_config']['connector_config']['path'] = '/'; $config['search_api.server.joinup']['backend_config']['connector_config']['core'] = getenv('SEARCH_API_SERVER_SS_SOLR_CORE'); + European Commission eTranslation: | + $config['tmgmt.translator.ec_etranslation']['settings']['username'] = getenv('TMGMT_ETRANSLATION_USERNAME'); + $config['tmgmt.translator.ec_etranslation']['settings']['password'] = getenv('TMGMT_ETRANSLATION_PASSWORD'); OpenEuropa Webtools Analytics: | $config['oe_webtools_analytics.settings']['siteID'] = getenv('OE_WEBTOOLS_ANALYTICS_SITE_ID'); $config['oe_webtools_analytics.settings']['sitePath'] = getenv('OE_WEBTOOLS_ANALYTICS_SITE_PATH'); -- GitLab From deca5a55d947fcb3e709864280de2c24baadb598 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 10 Sep 2024 13:40:07 +0200 Subject: [PATCH 049/149] ISAICP-8816: Refactor, move recipients methods as part of AnnouncementInterface. --- tests/src/Context/JoinupGroupContext.php | 3 +- .../joinup_group/src/Entity/Announcement.php | 45 +++++++++++++++++++ .../src/Entity/AnnouncementInterface.php | 29 ++++++++++++ .../src/Entity/GroupInterface.php | 29 ------------ .../joinup_group/src/Entity/GroupTrait.php | 43 +----------------- .../AnnouncementTransitionSubscriber.php | 5 +-- .../src/Form/AnnouncementForm.php | 4 +- .../SendGroupAnnouncementsQueueWorker.php | 3 +- 8 files changed, 81 insertions(+), 80 deletions(-) diff --git a/tests/src/Context/JoinupGroupContext.php b/tests/src/Context/JoinupGroupContext.php index 2d63490215..14a4d01ca2 100644 --- a/tests/src/Context/JoinupGroupContext.php +++ b/tests/src/Context/JoinupGroupContext.php @@ -374,8 +374,7 @@ public function assertDeliveredAnnouncements(string $subject): void { $body = $announcement->getBody(); $offset = 0; $limit = 250; - $group = $announcement->getGroup(); - while ($member_emails = $group->getAnnouncementRecipients($offset, $limit)) { + while ($member_emails = $announcement->getRecipients($offset, $limit)) { foreach ($member_emails as $member_email) { $emails = $this->getEmailsBySubjectAndMail($announcement->getSubject(), $member_email); $email = reset($emails); diff --git a/web/modules/custom/joinup_group/src/Entity/Announcement.php b/web/modules/custom/joinup_group/src/Entity/Announcement.php index ce898f67ca..6cb62fde50 100644 --- a/web/modules/custom/joinup_group/src/Entity/Announcement.php +++ b/web/modules/custom/joinup_group/src/Entity/Announcement.php @@ -4,8 +4,10 @@ namespace Drupal\joinup_group\Entity; +use Drupal\Core\Database\Query\SelectInterface; use Drupal\joinup_workflow\EntityWorkflowStateTrait; use Drupal\message\Entity\Message; +use Drupal\og\OgMembershipInterface; /** * Bundle class for announcement messages. @@ -94,4 +96,47 @@ protected function getGroupFieldName(): string { return 'group'; } + /** + * {@inheritdoc} + */ + public function getRecipients(int $offset, int $limit): array { + return $this->getRecipientsQuery() + ->range($offset, $limit) + ->execute() + ->fetchCol(); + } + + /** + * {@inheritdoc} + */ + public function getRecipientsCount(): int { + return (int) $this->getRecipientsQuery() + ->countQuery() + ->execute() + ->fetchField(); + } + + /** + * Provides a helper function preparing a query. + * + * @return \Drupal\Core\Database\Query\SelectInterface + * The database query. + */ + protected function getRecipientsQuery(): SelectInterface { + $group = $this->getGroup(); + + $query = \Drupal::database()->select('og_membership', 'og'); + $query->join('users_field_data', 'u', 'og.uid = u.uid'); + // Only users which accepted the 'Legal notice' are receiving announcements. + $query->join('entity_legal_document_acceptance', 'a', 'og.uid = a.uid'); + return $query->condition('og.entity_type', 'rdf_entity') + ->fields('u', ['mail']) + ->condition('og.entity_bundle', $group->bundle()) + ->condition('og.entity_id', $group->id()) + ->condition('og.state', OgMembershipInterface::STATE_ACTIVE) + ->condition('og.announcements', 1) + ->condition('u.status', 1) + ->orderBy('og.uid'); + } + } diff --git a/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php b/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php index d5e2e9ba01..efd99fb410 100644 --- a/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php +++ b/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php @@ -56,4 +56,33 @@ public function getBody(): ?string; */ public function getBodyFormat(): string; + /** + * Returns a list of emails of members subscribed to receive announcements. + * + * Note that this method is not using the entity API as some groups may have + * tens of thousands of members, and we need a fast way to queue them. Doing a + * direct database query is faster. + * + * Also, passing an offset and a limit is mandatory in order to avoid huge + * return arrays. It's the caller responsibility to pass the correct range and + * reassemble the results according to its functionality. + * + * @param int $offset + * The query offset. + * @param int $limit + * The query limit. + * + * @return string[] + * A list of groups members emails. + */ + public function getRecipients(int $offset, int $limit): array; + + /** + * Returns the number of active members subscribed to receive announcements. + * + * @return int + * The number of active members subscribed to receive announcements. + */ + public function getRecipientsCount(): int; + } diff --git a/web/modules/custom/joinup_group/src/Entity/GroupInterface.php b/web/modules/custom/joinup_group/src/Entity/GroupInterface.php index eb71c2ee63..3db6559ca7 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupInterface.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupInterface.php @@ -318,35 +318,6 @@ public function getSetting(string $field_name): FieldItemListInterface; */ public function getMembers(int $offset = 0, ?int $limit = NULL, array $roles = [OgRoleInterface::AUTHENTICATED], array $states = [OgMembershipInterface::STATE_ACTIVE]): array; - /** - * Returns a list of emails of members subscribed to receive announcements. - * - * Note that this method is not using the entity API as some groups may have - * tens of thousands of members, and we need a fast way to queue them. Doing a - * direct database query is faster. - * - * Also, passing an offset and a limit is mandatory in order to avoid huge - * return arrays. It's the caller responsibility to pass the correct range and - * reassemble the results according to its functionality. - * - * @param int $offset - * The query offset. - * @param int $limit - * The query limit. - * - * @return string[] - * A list of groups members emails. - */ - public function getAnnouncementRecipients(int $offset, int $limit): array; - - /** - * Returns the number of active members subscribed to receive announcements. - * - * @return int - * The number of active members subscribed to receive announcements. - */ - public function getAnnouncementRecipientsCount(): int; - /** * Returns the contact information field name. * diff --git a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php index e09bbee62f..68bcaf764d 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php @@ -237,48 +237,7 @@ public function getMembers(int $offset = 0, ?int $limit = NULL, array $roles = [ sort($uids); return $entity_type_manager->getStorage('user')->loadMultiple($uids); } - - /** - * {@inheritdoc} - */ - public function getAnnouncementRecipients(int $offset, int $limit): array { - return $this->getAnnouncementRecipientsQuery() - ->range($offset, $limit) - ->execute() - ->fetchCol(); - } - - /** - * {@inheritdoc} - */ - public function getAnnouncementRecipientsCount(): int { - return (int) $this->getAnnouncementRecipientsQuery() - ->countQuery() - ->execute() - ->fetchField(); - } - - /** - * Provides a helper function preparing a query. - * - * @return \Drupal\Core\Database\Query\SelectInterface - * The database query. - */ - protected function getAnnouncementRecipientsQuery(): SelectInterface { - $query = \Drupal::database()->select('og_membership', 'og'); - $query->join('users_field_data', 'u', 'og.uid = u.uid'); - // Only users which accepted the 'Legal notice' are receiving announcements. - $query->join('entity_legal_document_acceptance', 'a', 'og.uid = a.uid'); - return $query->condition('og.entity_type', 'rdf_entity') - ->fields('u', ['mail']) - ->condition('og.entity_bundle', $this->bundle()) - ->condition('og.entity_id', $this->id()) - ->condition('og.state', OgMembershipInterface::STATE_ACTIVE) - ->condition('og.announcements', 1) - ->condition('u.status', 1) - ->orderBy('og.uid'); - } - + /** * Processes and returns a list of group content entities. * diff --git a/web/modules/custom/joinup_group/src/EventSubscriber/AnnouncementTransitionSubscriber.php b/web/modules/custom/joinup_group/src/EventSubscriber/AnnouncementTransitionSubscriber.php index 939e7f880b..d9019d5950 100644 --- a/web/modules/custom/joinup_group/src/EventSubscriber/AnnouncementTransitionSubscriber.php +++ b/web/modules/custom/joinup_group/src/EventSubscriber/AnnouncementTransitionSubscriber.php @@ -111,9 +111,8 @@ public function onAnnouncementSentForApproval(WorkflowTransitionEvent $event): v public function onAnnouncementApproved(WorkflowTransitionEvent $event): void { /** @var \Drupal\joinup_group\Entity\AnnouncementInterface $announcement */ $announcement = $event->getEntity(); - $group = $announcement->getGroup(); - if (!$recipients_count = $group->getAnnouncementRecipientsCount()) { + if (!$recipients_count = $announcement->getRecipientsCount()) { // Normally, this cannot happen because we're handling this in the form. // @see \Drupal\joinup_group\Form\AnnouncementForm::validateForm() return; @@ -121,7 +120,7 @@ public function onAnnouncementApproved(WorkflowTransitionEvent $event): void { // For smaller groups we send the announcements instantly. if ($recipients_count <= 50) { - $recipients = $group->getAnnouncementRecipients(0, 50); + $recipients = $announcement->getRecipients(0, 50); $this->messageDelivery->sendMessageToEmailAddresses($announcement, $recipients); return; } diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index 230e22049e..ed377adcf7 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -190,7 +190,7 @@ public function validateForm(array &$form, FormStateInterface $form_state): void $transition = $form_state->getTriggeringElement()['#state_machine_transition'] ?? NULL; if ($transition === 'approve') { $group = $this->announcement->getGroup(); - if (!$group->getAnnouncementRecipientsCount()) { + if (!$this->announcement->getRecipientsCount()) { $form_state->setError($form, $this->t('Cannot send this announcement to %group @type because none of its members are subscribed to receive announcements.', [ '%group' => $group->label(), '@type' => $group->get('rid')->entity->getSingularLabel(), @@ -265,7 +265,7 @@ public function submitForm(array &$form, FormStateInterface $form_state): void { $status = $this->t("The announcement has been restored."); } elseif ($this->announcement->getWorkflowState() === 'delivered') { - if ($this->announcement->getGroup()->getAnnouncementRecipientsCount() > 50) { + if ($this->announcement->getRecipientsCount() > 50) { $status = $this->t("The announcement has been scheduled to be delivered to the %group @type members. Because the @type has a large amount of members the emails will be sent in several batches.", $args); } else { diff --git a/web/modules/custom/joinup_group/src/Plugin/QueueWorker/SendGroupAnnouncementsQueueWorker.php b/web/modules/custom/joinup_group/src/Plugin/QueueWorker/SendGroupAnnouncementsQueueWorker.php index dc833039a9..65fa0338d8 100644 --- a/web/modules/custom/joinup_group/src/Plugin/QueueWorker/SendGroupAnnouncementsQueueWorker.php +++ b/web/modules/custom/joinup_group/src/Plugin/QueueWorker/SendGroupAnnouncementsQueueWorker.php @@ -112,9 +112,8 @@ public function processItem($data): void { $queue->createQueue(); $offset = 0; $limit = 250; - $group = $announcement->getGroup(); // Don't allow queue entries with tens of thousands of recipients. - while ($recipients = $group->getAnnouncementRecipients($offset, $limit)) { + while ($recipients = $announcement->getRecipients($offset, $limit)) { $queue->createItem([ 'announcement' => (int) $announcement->id(), 'recipients' => $recipients, -- GitLab From cbea07ca0bb40aed27d71e83500ad66c706b2a8d Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 10 Sep 2024 13:40:55 +0200 Subject: [PATCH 050/149] ISAICP-8816: Refactor, move recipients methods as part of AnnouncementInterface. --- web/modules/custom/joinup_group/src/Entity/GroupTrait.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php index 68bcaf764d..429846e810 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php @@ -5,7 +5,6 @@ namespace Drupal\joinup_group\Entity; use Drupal\Core\Access\AccessResultInterface; -use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Session\AccountInterface; use Drupal\joinup_core\Entity\OutdatedContentTrait; @@ -237,7 +236,7 @@ public function getMembers(int $offset = 0, ?int $limit = NULL, array $roles = [ sort($uids); return $entity_type_manager->getStorage('user')->loadMultiple($uids); } - + /** * Processes and returns a list of group content entities. * -- GitLab From 735f43b94309436167457db8178e83d6d68f2ac6 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 10 Sep 2024 14:12:29 +0200 Subject: [PATCH 051/149] ISAICP-8816: Add professional domain field. --- ...m_display.message.announcement.default.yml | 22 ++++++++++++++ ...w_display.message.announcement.default.yml | 28 ++++++++++++++++++ ...display.message.announcement.mail_body.yml | 2 ++ ...play.message.announcement.mail_subject.yml | 2 ++ ...ssage.announcement.professional_domain.yml | 29 +++++++++++++++++++ ...ld.storage.message.professional_domain.yml | 20 +++++++++++++ 6 files changed, 103 insertions(+) create mode 100644 config/sync/core.entity_form_display.message.announcement.default.yml create mode 100644 config/sync/core.entity_view_display.message.announcement.default.yml create mode 100644 config/sync/field.field.message.announcement.professional_domain.yml create mode 100644 config/sync/field.storage.message.professional_domain.yml diff --git a/config/sync/core.entity_form_display.message.announcement.default.yml b/config/sync/core.entity_form_display.message.announcement.default.yml new file mode 100644 index 0000000000..1ca17e0fee --- /dev/null +++ b/config/sync/core.entity_form_display.message.announcement.default.yml @@ -0,0 +1,22 @@ +uuid: 8eaf4036-0841-4e1b-8414-0151f3abc4b2 +langcode: en +status: true +dependencies: + config: + - field.field.message.announcement.body + - field.field.message.announcement.group + - field.field.message.announcement.professional_domain + - field.field.message.announcement.state + - field.field.message.announcement.subject + - message.template.announcement +id: message.announcement.default +targetEntityType: message +bundle: announcement +mode: default +content: { } +hidden: + body: true + group: true + professional_domain: true + state: true + subject: true diff --git a/config/sync/core.entity_view_display.message.announcement.default.yml b/config/sync/core.entity_view_display.message.announcement.default.yml new file mode 100644 index 0000000000..23503fbe81 --- /dev/null +++ b/config/sync/core.entity_view_display.message.announcement.default.yml @@ -0,0 +1,28 @@ +uuid: ce0bdc82-83b7-4fea-ac19-05c597b74eeb +langcode: en +status: true +dependencies: + config: + - field.field.message.announcement.body + - field.field.message.announcement.group + - field.field.message.announcement.professional_domain + - field.field.message.announcement.state + - field.field.message.announcement.subject + - message.template.announcement +id: message.announcement.default +targetEntityType: message +bundle: announcement +mode: default +content: + partial_0: + settings: { } + third_party_settings: { } + weight: 0 + region: content +hidden: + body: true + group: true + professional_domain: true + search_api_excerpt: true + state: true + subject: true diff --git a/config/sync/core.entity_view_display.message.announcement.mail_body.yml b/config/sync/core.entity_view_display.message.announcement.mail_body.yml index a2dee3c9f6..02d329d78e 100644 --- a/config/sync/core.entity_view_display.message.announcement.mail_body.yml +++ b/config/sync/core.entity_view_display.message.announcement.mail_body.yml @@ -6,6 +6,7 @@ dependencies: - core.entity_view_mode.message.mail_body - field.field.message.announcement.body - field.field.message.announcement.group + - field.field.message.announcement.professional_domain - field.field.message.announcement.state - field.field.message.announcement.subject - message.template.announcement @@ -28,6 +29,7 @@ content: hidden: body: true group: true + professional_domain: true search_api_excerpt: true state: true subject: true diff --git a/config/sync/core.entity_view_display.message.announcement.mail_subject.yml b/config/sync/core.entity_view_display.message.announcement.mail_subject.yml index 53638ba6af..b767039edd 100644 --- a/config/sync/core.entity_view_display.message.announcement.mail_subject.yml +++ b/config/sync/core.entity_view_display.message.announcement.mail_subject.yml @@ -6,6 +6,7 @@ dependencies: - core.entity_view_mode.message.mail_subject - field.field.message.announcement.body - field.field.message.announcement.group + - field.field.message.announcement.professional_domain - field.field.message.announcement.state - field.field.message.announcement.subject - message.template.announcement @@ -32,5 +33,6 @@ hidden: body: true group: true partial_0: true + professional_domain: true search_api_excerpt: true state: true diff --git a/config/sync/field.field.message.announcement.professional_domain.yml b/config/sync/field.field.message.announcement.professional_domain.yml new file mode 100644 index 0000000000..8485ef20fd --- /dev/null +++ b/config/sync/field.field.message.announcement.professional_domain.yml @@ -0,0 +1,29 @@ +uuid: a9fb9c7e-bdfe-47a5-b909-1f3343482aa8 +langcode: en +status: true +dependencies: + config: + - field.storage.message.professional_domain + - message.template.announcement + - taxonomy.vocabulary.topic +id: message.announcement.professional_domain +field_name: professional_domain +entity_type: message +bundle: announcement +label: 'Professional domain' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:taxonomy_term' + handler_settings: + target_bundles: + topic: topic + sort: + field: name + direction: asc + auto_create: false + auto_create_bundle: '' +field_type: entity_reference diff --git a/config/sync/field.storage.message.professional_domain.yml b/config/sync/field.storage.message.professional_domain.yml new file mode 100644 index 0000000000..0b7d49cfc0 --- /dev/null +++ b/config/sync/field.storage.message.professional_domain.yml @@ -0,0 +1,20 @@ +uuid: deaed812-272b-444a-be80-21253db96d78 +langcode: en +status: true +dependencies: + module: + - message + - taxonomy +id: message.professional_domain +field_name: professional_domain +entity_type: message +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false -- GitLab From bbd1880fa5931a0e56868f5e140acb73c01f87bb Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 11 Sep 2024 12:24:00 +0200 Subject: [PATCH 052/149] ISAICP-8816: WIP --- .../src/Form/AnnouncementForm.php | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index ed377adcf7..d0ffccd26e 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -13,6 +13,7 @@ use Drupal\Core\Url; use Drupal\joinup_group\Entity\AnnouncementInterface; use Drupal\joinup_notification\JoinupMessageDeliveryInterface; +use Drupal\og\OgMembershipInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -141,6 +142,16 @@ public function buildForm(array $form, FormStateInterface $form_state): array { }, array_keys($arguments))), ]; + $form['professional_domain'] = [ + '#type' => 'select', + '#title' => $this->t('Professional domain'), + '#description' => $this->t('description?'), + '#options' => $this->getOptions(), + '#multiple' => TRUE, // Allows multiple selections. + '#required' => FALSE, + '#size' => 10, + ]; + $form['state'] = [ '#type' => 'item', '#title' => $this->t('Announcement state:'), @@ -346,4 +357,91 @@ protected function getArguments(): array { ]; } + /** + * Gets options for professional domain. + * + * @return array + * Option list. + */ + protected function getOptions(): array { + $membership = $this->getMembershipCount(); + + $count = 0; + $options = []; + $definition = $this->announcement->get('professional_domain') + ->getFieldDefinition(); + $domains = $definition + ->getFieldStorageDefinition() + ->getOptionsProvider('target_id', $this->announcement) + ->getPossibleOptions($this->currentUser()); + + foreach ($domains as $key => $domain) { + $is_parent = !str_starts_with($domain, '-'); + if ($is_parent) { + $parent = $domain; + continue; + } + + $number_of_users = $membership[$key] ?? NULL; + if (isset($parent) && $number_of_users) { + $options[$parent][$key] = $domain . ' (' . $number_of_users . ')'; + $count += $number_of_users; + } + } + + dpm('count:' . $count); + + return $options; + } + + public function getMembershipCount(): array { + $group = $this->announcement->getGroup(); + + $query = \Drupal::database()->select('og_membership', 'og'); + $query->join('users_field_data', 'u', 'og.uid = u.uid'); + $query->join('user__field_user_professional_domain', 'pd', 'pd.entity_id = og.uid'); + $query->fields('pd', ['field_user_professional_domain_target_id']); + $query->fields('u', ['uid']); + + $membership = []; + $domain_assigments = $query->condition('og.entity_type', 'rdf_entity') + ->condition('og.entity_bundle', $group->bundle()) + ->condition('og.entity_id', $group->id()) + ->condition('og.state', OgMembershipInterface::STATE_ACTIVE) + ->condition('og.announcements', 1) + ->condition('u.status', 1) + ->execute() + ->fetchAllKeyed(); + foreach ($domain_assigments as $domain_assigment) { + dpm($domain_assigment); + // if (isset($membership[$domain_assigment])) { + // $membership[$domain_assigment->field_user_professional_domain_target_id] = []; + // } + // + // if (!in_array($domain_assigment->uid, $membership[$domain_assigment->field_user_professional_domain_target_id])) { + // $membership[$domain_assigment->field_user_professional_domain_target_id][] = $domain_assigment->uid; + // } + } + + dpm($membership); + return []; + + $query = \Drupal::database()->select('og_membership', 'og'); + $query->join('users_field_data', 'u', 'og.uid = u.uid'); + //$query->join('entity_legal_document_acceptance', 'a', 'og.uid = a.uid'); + $query->join('user__field_user_professional_domain', 'pd', 'pd.entity_id = og.uid'); + $query->addExpression('COUNT(pd.entity_id)', 'users'); + $query->groupBy('pd.field_user_professional_domain_target_id'); + $query->fields('pd', ['field_user_professional_domain_target_id']); + + return $query->condition('og.entity_type', 'rdf_entity') + ->condition('og.entity_bundle', $group->bundle()) + ->condition('og.entity_id', $group->id()) + ->condition('og.state', OgMembershipInterface::STATE_ACTIVE) + ->condition('og.announcements', 1) + ->condition('u.status', 1) + ->execute() + ->fetchAllKeyed(); + } + } -- GitLab From fe40129d946ec22dff6fc4adeae38eb4b13c12d3 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 11 Sep 2024 13:58:43 +0200 Subject: [PATCH 053/149] ISAICP-8816: Update queries for field creation. --- .../src/Form/AnnouncementForm.php | 72 ++++++++----------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index d0ffccd26e..afb9f564d4 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -7,6 +7,7 @@ use Drupal\Component\Datetime\TimeInterface; use Drupal\Component\Render\MarkupInterface; use Drupal\Core\Cache\CacheableMetadata; +use Drupal\Core\Database\Connection; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Logger\LoggerChannelInterface; @@ -40,6 +41,7 @@ public function __construct( protected JoinupMessageDeliveryInterface $messageDelivery, protected TimeInterface $time, protected LoggerChannelInterface $logger, + protected Connection $connection, ) { } @@ -51,6 +53,7 @@ public static function create(ContainerInterface $container): self { $container->get('joinup_notification.message_delivery'), $container->get('datetime.time'), $container->get('logger.channel.group_membership'), + $container->get('database'), ); } @@ -145,9 +148,9 @@ public function buildForm(array $form, FormStateInterface $form_state): array { $form['professional_domain'] = [ '#type' => 'select', '#title' => $this->t('Professional domain'), - '#description' => $this->t('description?'), + '#description' => $this->t('By picking any value, you will limit the recipients of the announcement.'), '#options' => $this->getOptions(), - '#multiple' => TRUE, // Allows multiple selections. + '#multiple' => TRUE, '#required' => FALSE, '#size' => 10, ]; @@ -364,9 +367,8 @@ protected function getArguments(): array { * Option list. */ protected function getOptions(): array { - $membership = $this->getMembershipCount(); + $topic_assignment = $this->getUsersTopicAssignment(); - $count = 0; $options = []; $definition = $this->announcement->get('professional_domain') ->getFieldDefinition(); @@ -382,66 +384,50 @@ protected function getOptions(): array { continue; } - $number_of_users = $membership[$key] ?? NULL; + $number_of_users = isset($topic_assignment[$key]) ? count($topic_assignment[$key]) : NULL; if (isset($parent) && $number_of_users) { $options[$parent][$key] = $domain . ' (' . $number_of_users . ')'; - $count += $number_of_users; } } - dpm('count:' . $count); - return $options; } - public function getMembershipCount(): array { + /** + * Gets user's topic assignment. + * + * @return array + * List of assignments. + */ + public function getUsersTopicAssignment(): array { $group = $this->announcement->getGroup(); - $query = \Drupal::database()->select('og_membership', 'og'); + $list = []; + + $query = $this->connection->select('og_membership', 'og'); $query->join('users_field_data', 'u', 'og.uid = u.uid'); $query->join('user__field_user_professional_domain', 'pd', 'pd.entity_id = og.uid'); - $query->fields('pd', ['field_user_professional_domain_target_id']); + $query->addExpression('pd.field_user_professional_domain_target_id', 'term'); $query->fields('u', ['uid']); - $membership = []; - $domain_assigments = $query->condition('og.entity_type', 'rdf_entity') + $assignments = $query->condition('og.entity_type', 'rdf_entity') ->condition('og.entity_bundle', $group->bundle()) ->condition('og.entity_id', $group->id()) ->condition('og.state', OgMembershipInterface::STATE_ACTIVE) ->condition('og.announcements', 1) ->condition('u.status', 1) - ->execute() - ->fetchAllKeyed(); - foreach ($domain_assigments as $domain_assigment) { - dpm($domain_assigment); - // if (isset($membership[$domain_assigment])) { - // $membership[$domain_assigment->field_user_professional_domain_target_id] = []; - // } - // - // if (!in_array($domain_assigment->uid, $membership[$domain_assigment->field_user_professional_domain_target_id])) { - // $membership[$domain_assigment->field_user_professional_domain_target_id][] = $domain_assigment->uid; - // } - } - - dpm($membership); - return []; + ->execute(); + foreach ($assignments as $assignment) { + if (!isset($list[$assignment->term])) { + $list[$assignment->term] = []; + } - $query = \Drupal::database()->select('og_membership', 'og'); - $query->join('users_field_data', 'u', 'og.uid = u.uid'); - //$query->join('entity_legal_document_acceptance', 'a', 'og.uid = a.uid'); - $query->join('user__field_user_professional_domain', 'pd', 'pd.entity_id = og.uid'); - $query->addExpression('COUNT(pd.entity_id)', 'users'); - $query->groupBy('pd.field_user_professional_domain_target_id'); - $query->fields('pd', ['field_user_professional_domain_target_id']); + if (!in_array($assignment->uid, $list[$assignment->term])) { + $list[$assignment->term][] = $assignment->uid; + } + } - return $query->condition('og.entity_type', 'rdf_entity') - ->condition('og.entity_bundle', $group->bundle()) - ->condition('og.entity_id', $group->id()) - ->condition('og.state', OgMembershipInterface::STATE_ACTIVE) - ->condition('og.announcements', 1) - ->condition('u.status', 1) - ->execute() - ->fetchAllKeyed(); + return $list; } } -- GitLab From 578ded7f832a7922e2afbdd8ee0b968e15b0df28 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 11 Sep 2024 14:00:25 +0200 Subject: [PATCH 054/149] ISAICP-8816: Remove docblock for constructor. --- .../custom/joinup_group/src/Form/AnnouncementForm.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index afb9f564d4..5858a5f2b2 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -27,16 +27,6 @@ class AnnouncementForm extends FormBase { */ protected AnnouncementInterface $announcement; - /** - * Builds a new form instance. - * - * @param \Drupal\joinup_notification\JoinupMessageDeliveryInterface $messageDelivery - * The message delivery service. - * @param \Drupal\Component\Datetime\TimeInterface $time - * The date/time service. - * @param \Drupal\Core\Logger\LoggerChannelInterface $logger - * The logger channel service. - */ public function __construct( protected JoinupMessageDeliveryInterface $messageDelivery, protected TimeInterface $time, -- GitLab From e65e954076e4155fd55dc4ae59b122f422e0f97f Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 11 Sep 2024 14:20:57 +0200 Subject: [PATCH 055/149] ISAICP-8816: Allow to set professional_domain. --- .../joinup_group/src/Entity/Announcement.php | 18 ++++++++++++++++++ .../src/Entity/AnnouncementInterface.php | 18 ++++++++++++++++++ .../joinup_group/src/Form/AnnouncementForm.php | 2 ++ 3 files changed, 38 insertions(+) diff --git a/web/modules/custom/joinup_group/src/Entity/Announcement.php b/web/modules/custom/joinup_group/src/Entity/Announcement.php index 6cb62fde50..c872b66eb5 100644 --- a/web/modules/custom/joinup_group/src/Entity/Announcement.php +++ b/web/modules/custom/joinup_group/src/Entity/Announcement.php @@ -139,4 +139,22 @@ protected function getRecipientsQuery(): SelectInterface { ->orderBy('og.uid'); } + /** + * {@inheritdoc} + */ + public function setProfessionalDomains(array $ids): self { + $this->set('professional_domain', $ids); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getProfessionalDomainIds(): array { + return array_map( + fn(array $value) => $value['target_id'], + $this->get('professional_domain')->getValue(), + ); + } + } diff --git a/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php b/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php index efd99fb410..b7cd6f06fe 100644 --- a/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php +++ b/web/modules/custom/joinup_group/src/Entity/AnnouncementInterface.php @@ -85,4 +85,22 @@ public function getRecipients(int $offset, int $limit): array; */ public function getRecipientsCount(): int; + /** + * Sets the professional domains reference value. + * + * @param array $ids + * The entity IDs of the topic terms. + * + * @return $this + */ + public function setProfessionalDomains(array $ids): self; + + /** + * Returns the professional domains reference value. + * + * @return array + * The IDs of the professional domain terms. + */ + public function getProfessionalDomainIds(): array; + } diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index 5858a5f2b2..1df4a1a9da 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -140,6 +140,7 @@ public function buildForm(array $form, FormStateInterface $form_state): array { '#title' => $this->t('Professional domain'), '#description' => $this->t('By picking any value, you will limit the recipients of the announcement.'), '#options' => $this->getOptions(), + '#default_value' => $this->announcement->getProfessionalDomainIds(), '#multiple' => TRUE, '#required' => FALSE, '#size' => 10, @@ -217,6 +218,7 @@ public function submitForm(array &$form, FormStateInterface $form_state): void { $this->announcement ->setSubject($form_state->getValue('subject')) + ->setProfessionalDomains($form_state->getValue('professional_domain')) ->setBody($form_state->getValue(['body', 'value'])) // Only save the arguments having a 'value' key. Some arguments depend on // the email recipient and will be dynamically set when the email is sent. -- GitLab From aa0eb51b390327ed51abad720640e42a32882ed3 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 11 Sep 2024 14:48:31 +0200 Subject: [PATCH 056/149] ISAICP-8816: Filter by professional_domain if it is set. --- .../custom/joinup_group/src/Entity/Announcement.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_group/src/Entity/Announcement.php b/web/modules/custom/joinup_group/src/Entity/Announcement.php index c872b66eb5..a1ab148847 100644 --- a/web/modules/custom/joinup_group/src/Entity/Announcement.php +++ b/web/modules/custom/joinup_group/src/Entity/Announcement.php @@ -129,14 +129,21 @@ protected function getRecipientsQuery(): SelectInterface { $query->join('users_field_data', 'u', 'og.uid = u.uid'); // Only users which accepted the 'Legal notice' are receiving announcements. $query->join('entity_legal_document_acceptance', 'a', 'og.uid = a.uid'); + + if ($professionalDomainIds = $this->getProfessionalDomainIds()) { + $query->join('user__field_user_professional_domain', 'pd', 'u.uid = pd.entity_id'); + $query->condition('pd.field_user_professional_domain_target_id', $professionalDomainIds, 'IN'); + } + return $query->condition('og.entity_type', 'rdf_entity') ->fields('u', ['mail']) + ->distinct() ->condition('og.entity_bundle', $group->bundle()) ->condition('og.entity_id', $group->id()) ->condition('og.state', OgMembershipInterface::STATE_ACTIVE) ->condition('og.announcements', 1) ->condition('u.status', 1) - ->orderBy('og.uid'); + ->orderBy('u.mail'); } /** -- GitLab From 923b3c016611484801bc183b72ebbfe5a8157f8b Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:05:54 +0200 Subject: [PATCH 057/149] ISAICP-4724: Add exception for better comprehension of permalink failure. --- tests/src/Context/JoinupContext.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/src/Context/JoinupContext.php b/tests/src/Context/JoinupContext.php index 2636110907..df7363e89f 100644 --- a/tests/src/Context/JoinupContext.php +++ b/tests/src/Context/JoinupContext.php @@ -2242,6 +2242,9 @@ public function assertRegionElementAttribute($tag, $attribute, $value, $region): */ public function thePersistentUrlShouldContain($pattern): void { $field_selector = $this->getSession()->getPage()->find('css', '.permalink'); + if (empty($field_selector)) { + throw new \Exception("The persistent url was not found."); + } $href = $field_selector->getAttribute('href'); Assert::assertStringContainsString($pattern, $href); } -- GitLab From 9c8736cf6cf515cbbcb4070ed7687230a1791931 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 21 Aug 2024 20:19:32 +0200 Subject: [PATCH 058/149] ISAICP-4724: Improve behat test used in permalink tests. --- tests/src/Context/JoinupContext.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/src/Context/JoinupContext.php b/tests/src/Context/JoinupContext.php index df7363e89f..2df6bdac73 100644 --- a/tests/src/Context/JoinupContext.php +++ b/tests/src/Context/JoinupContext.php @@ -2241,12 +2241,7 @@ public function assertRegionElementAttribute($tag, $attribute, $value, $region): * @Then the persistent url should contain :pattern */ public function thePersistentUrlShouldContain($pattern): void { - $field_selector = $this->getSession()->getPage()->find('css', '.permalink'); - if (empty($field_selector)) { - throw new \Exception("The persistent url was not found."); - } - $href = $field_selector->getAttribute('href'); - Assert::assertStringContainsString($pattern, $href); + $this->assertSession()->elementAttributeContains('css', '.permalink', 'href', $pattern); } /** -- GitLab From 55a517520831362005d495a48118a75ce6315569 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:07:35 +0200 Subject: [PATCH 059/149] ISAICP-4724: Fix typo in OutdatedContentTrait. --- .../custom/joinup_core/src/Entity/OutdatedContentTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_core/src/Entity/OutdatedContentTrait.php b/web/modules/custom/joinup_core/src/Entity/OutdatedContentTrait.php index 586beb47b1..8a03da719e 100644 --- a/web/modules/custom/joinup_core/src/Entity/OutdatedContentTrait.php +++ b/web/modules/custom/joinup_core/src/Entity/OutdatedContentTrait.php @@ -5,7 +5,7 @@ namespace Drupal\joinup_core\Entity; /** - * Reusable code for classed implementing OutdatedContentInterface interface. + * Reusable code for classes implementing OutdatedContentInterface interface. * * @see \Drupal\joinup_core\Entity\OutdatedContentInterface */ -- GitLab From 344d01a926503d124075e0edfbbe86f3f857337d Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:08:46 +0200 Subject: [PATCH 060/149] ISAICP-4724: Create trait for permalinks. --- .../src/Entity/PermalinkInterface.php | 20 ++++++++++ .../joinup_core/src/Entity/PermalinkTrait.php | 40 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php create mode 100644 web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php diff --git a/web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php b/web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php new file mode 100644 index 0000000000..66d0287c0e --- /dev/null +++ b/web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php @@ -0,0 +1,20 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\joinup_core\Entity; + +/** + * Entity with a permalink. + */ +interface PermalinkInterface { + + /** + * Returns the permalink for the entity. + * + * @return string|null + * The permalink if it exists. + */ + public function getPermalink(): ?string; + +} diff --git a/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php b/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php new file mode 100644 index 0000000000..0cc0461703 --- /dev/null +++ b/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php @@ -0,0 +1,40 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\joinup_core\Entity; + +use Drupal\joinup_core\Controller\IdRedirect; +use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; + +/** + * Reusable code for classes implementing PermalinkInterface interface. + * + * @see \Drupal\joinup_core\Entity\PermalinkInterface + */ +trait PermalinkTrait { + + /** + * {@inheritdoc} + */ + public function getPermalink(): ?string { + // Entity ID is pointing to the publication office redirect. + $namespaces = implode('|', array_keys(IdRedirect::getEntityTypeFromPersistentUriNamespace())); + $uri = $this instanceof RdfSyncEntityInterface ? $this->getUri() : $this->id(); + if (preg_match('{^http://data.europa.eu/(?:' . $namespaces . ')/}', $uri)) { + return $uri; + } + + try { + // Don't process the path to avoid pathauto aliasing. + return $this->toUrl('canonical', [ + 'path_processing' => FALSE, + 'absolute' => TRUE, + ])->toString(); + } + catch (\Exception $e) { + return NULL; + } + } + +} -- GitLab From 8693e3168b09cb99ec6b3b4470bad721d0d9ad21 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:14:21 +0200 Subject: [PATCH 061/149] ISAICP-4724: Declare usage of trait for permalinks. --- web/modules/custom/custom_page/src/Entity/CustomPage.php | 2 ++ .../custom/custom_page/src/Entity/CustomPageInterface.php | 3 ++- .../src/Entity/CommunityContentBase.php | 2 ++ .../src/Entity/CommunityContentInterface.php | 3 ++- .../custom/joinup_group/src/Entity/GroupContentInterface.php | 3 ++- .../custom/joinup_group/src/Entity/GroupContentTrait.php | 2 ++ 6 files changed, 12 insertions(+), 3 deletions(-) diff --git a/web/modules/custom/custom_page/src/Entity/CustomPage.php b/web/modules/custom/custom_page/src/Entity/CustomPage.php index 448f9a3cc1..0e44f4f53d 100644 --- a/web/modules/custom/custom_page/src/Entity/CustomPage.php +++ b/web/modules/custom/custom_page/src/Entity/CustomPage.php @@ -8,6 +8,7 @@ use Drupal\joinup_bundle_class\DescriptionTrait; use Drupal\joinup_bundle_class\JoinupBundleClassFieldAccessTrait; use Drupal\joinup_bundle_class\LogoTrait; +use Drupal\joinup_core\Entity\PermalinkTrait; use Drupal\joinup_group\GroupArchivableEntityTrait; use Drupal\joinup_publication_date\Entity\EntityPublicationTimeTrait; use Drupal\joinup_workflow\ArchivableEntityTrait; @@ -29,6 +30,7 @@ class CustomPage extends Node implements CustomPageInterface { use LogoTrait; use NodeCollectionContentTrait; use TopicReferencingEntityTrait; + use PermalinkTrait; /** * {@inheritdoc} diff --git a/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php b/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php index 1ee2dd17e4..3c11b7c5a9 100644 --- a/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php +++ b/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php @@ -7,6 +7,7 @@ use Drupal\collection\Entity\CollectionContentInterface; use Drupal\joinup_bundle_class\DescriptionInterface; use Drupal\joinup_bundle_class\LogoInterface; +use Drupal\joinup_core\Entity\PermalinkInterface; use Drupal\joinup_group\Entity\GroupContentInterface; use Drupal\joinup_group\GroupArchivableEntityInterface; use Drupal\joinup_publication_date\Entity\EntityPublicationTimeInterface; @@ -18,7 +19,7 @@ /** * Interface for content page node entities. */ -interface CustomPageInterface extends NodeInterface, GroupContentInterface, CollectionContentInterface, EntityPublicationTimeInterface, LogoInterface, DescriptionInterface, EntityWorkflowStateInterface, ArchivableEntityInterface, GroupArchivableEntityInterface, TopicReferencingEntityInterface { +interface CustomPageInterface extends NodeInterface, GroupContentInterface, CollectionContentInterface, EntityPublicationTimeInterface, LogoInterface, DescriptionInterface, EntityWorkflowStateInterface, ArchivableEntityInterface, GroupArchivableEntityInterface, TopicReferencingEntityInterface, PermalinkInterface { /** * Checks if this custom page is set as a landing page of the group. diff --git a/web/modules/custom/joinup_community_content/src/Entity/CommunityContentBase.php b/web/modules/custom/joinup_community_content/src/Entity/CommunityContentBase.php index 7fb44984fb..6edb283ff5 100644 --- a/web/modules/custom/joinup_community_content/src/Entity/CommunityContentBase.php +++ b/web/modules/custom/joinup_community_content/src/Entity/CommunityContentBase.php @@ -9,6 +9,7 @@ use Drupal\joinup_bundle_class\DescriptionTrait; use Drupal\joinup_bundle_class\JoinupBundleClassMetaEntityTrait; use Drupal\joinup_core\Entity\OutdatedContentTrait; +use Drupal\joinup_core\Entity\PermalinkTrait; use Drupal\joinup_featured\FeaturedContentTrait; use Drupal\joinup_group\Entity\PinnableGroupContentTrait; use Drupal\joinup_group\Exception\MissingGroupException; @@ -39,6 +40,7 @@ abstract class CommunityContentBase extends Node implements CommunityContentInte use VisitCountAwareTrait; use GroupArchivableEntityTrait; use DescriptionTrait; + use PermalinkTrait; /** * Fields populated with statistical information by the joinup_stats module. diff --git a/web/modules/custom/joinup_community_content/src/Entity/CommunityContentInterface.php b/web/modules/custom/joinup_community_content/src/Entity/CommunityContentInterface.php index b660e5e2d8..2cc9408c7f 100644 --- a/web/modules/custom/joinup_community_content/src/Entity/CommunityContentInterface.php +++ b/web/modules/custom/joinup_community_content/src/Entity/CommunityContentInterface.php @@ -7,6 +7,7 @@ use Drupal\collection\Entity\CollectionContentInterface; use Drupal\joinup_bundle_class\DescriptionInterface; use Drupal\joinup_core\Entity\OutdatedContentInterface; +use Drupal\joinup_core\Entity\PermalinkInterface; use Drupal\joinup_featured\FeaturedContentInterface; use Drupal\joinup_group\Entity\PinnableGroupContentInterface; use Drupal\joinup_group\GroupArchivableEntityInterface; @@ -19,6 +20,6 @@ /** * Interface for community content entities. */ -interface CommunityContentInterface extends NodeInterface, EntityPublicationTimeInterface, FeaturedContentInterface, CollectionContentInterface, EntityWorkflowStateInterface, OutdatedContentInterface, PinnableGroupContentInterface, TopicReferencingEntityInterface, VisitCountAwareInterface, GroupArchivableEntityInterface, DescriptionInterface { +interface CommunityContentInterface extends NodeInterface, EntityPublicationTimeInterface, FeaturedContentInterface, CollectionContentInterface, EntityWorkflowStateInterface, OutdatedContentInterface, PinnableGroupContentInterface, TopicReferencingEntityInterface, VisitCountAwareInterface, GroupArchivableEntityInterface, DescriptionInterface, PermalinkInterface { } diff --git a/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php b/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php index 2806bb5031..0f9c11e019 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php @@ -6,6 +6,7 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Field\EntityReferenceFieldItemList; +use Drupal\joinup_core\Entity\PermalinkInterface; /** * Interface for entities that are group content. @@ -14,7 +15,7 @@ * - collections: community content, custom pages, and solutions. * - solutions: asset releases and asset distributions. */ -interface GroupContentInterface extends ContentEntityInterface { +interface GroupContentInterface extends ContentEntityInterface, PermalinkInterface { /** * Returns whether or not the entity is associated with a group. diff --git a/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php b/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php index c2ff76a1f5..95bb40607b 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php @@ -6,6 +6,7 @@ use Drupal\Core\Field\EntityReferenceFieldItemList; use Drupal\joinup_bundle_class\JoinupBundleClassFieldAccessTrait; +use Drupal\joinup_core\Entity\PermalinkTrait; use Drupal\joinup_group\Exception\MissingGroupException; use Drupal\og\OgGroupAudienceHelperInterface; @@ -15,6 +16,7 @@ trait GroupContentTrait { use JoinupBundleClassFieldAccessTrait; + use PermalinkTrait; /** * {@inheritdoc} -- GitLab From 9b6c369c5bfc308e14616b9b88c6d35417186b1f Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:15:51 +0200 Subject: [PATCH 062/149] ISAICP-4724: Use trait for permalinks. --- .../templates/content/page-title--node--custom-page.html.twig | 1 + .../templates/content/page-title--node--discussion.html.twig | 1 + .../templates/content/page-title--node--document.html.twig | 1 + .../ventuno/templates/content/page-title--node--event.html.twig | 1 + .../ventuno/templates/content/page-title--node--news.html.twig | 1 + .../templates/content/page-title--node--release.html.twig | 1 + 6 files changed, 6 insertions(+) diff --git a/web/themes/ventuno/templates/content/page-title--node--custom-page.html.twig b/web/themes/ventuno/templates/content/page-title--node--custom-page.html.twig index 360e71fdeb..c62e5863f5 100644 --- a/web/themes/ventuno/templates/content/page-title--node--custom-page.html.twig +++ b/web/themes/ventuno/templates/content/page-title--node--custom-page.html.twig @@ -4,6 +4,7 @@ * Template for the page title. */ #} +{% set permalink = entity.getPermalink() %} {{ attach_library('ventuno/page-title') }} {{ title_prefix }} diff --git a/web/themes/ventuno/templates/content/page-title--node--discussion.html.twig b/web/themes/ventuno/templates/content/page-title--node--discussion.html.twig index 3aca8a7dde..ddb74273d0 100644 --- a/web/themes/ventuno/templates/content/page-title--node--discussion.html.twig +++ b/web/themes/ventuno/templates/content/page-title--node--discussion.html.twig @@ -12,6 +12,7 @@ * displayed after the main title tag that appears in the template. */ #} +{% set permalink = entity.getPermalink() %} {{ attach_library('ventuno/page-title') }} {{ title_prefix }} {% if title %} diff --git a/web/themes/ventuno/templates/content/page-title--node--document.html.twig b/web/themes/ventuno/templates/content/page-title--node--document.html.twig index f49c646685..2432108eb7 100644 --- a/web/themes/ventuno/templates/content/page-title--node--document.html.twig +++ b/web/themes/ventuno/templates/content/page-title--node--document.html.twig @@ -12,6 +12,7 @@ * displayed after the main title tag that appears in the template. */ #} +{% set permalink = entity.getPermalink() %} {{ attach_library('ventuno/page-title') }} {{ title_prefix }} {% if title %} diff --git a/web/themes/ventuno/templates/content/page-title--node--event.html.twig b/web/themes/ventuno/templates/content/page-title--node--event.html.twig index c725329162..7a994c3874 100644 --- a/web/themes/ventuno/templates/content/page-title--node--event.html.twig +++ b/web/themes/ventuno/templates/content/page-title--node--event.html.twig @@ -12,6 +12,7 @@ * displayed after the main title tag that appears in the template. */ #} +{% set permalink = entity.getPermalink() %} {{ attach_library('ventuno/page-title') }} {{ title_prefix }} {% if title %} diff --git a/web/themes/ventuno/templates/content/page-title--node--news.html.twig b/web/themes/ventuno/templates/content/page-title--node--news.html.twig index 5650f4e424..9fb4640b72 100644 --- a/web/themes/ventuno/templates/content/page-title--node--news.html.twig +++ b/web/themes/ventuno/templates/content/page-title--node--news.html.twig @@ -12,6 +12,7 @@ * displayed after the main title tag that appears in the template. */ #} +{% set permalink = entity.getPermalink() %} {{ attach_library('ventuno/page-title') }} {{ title_prefix }} {% if title %} diff --git a/web/themes/ventuno/templates/content/page-title--node--release.html.twig b/web/themes/ventuno/templates/content/page-title--node--release.html.twig index b258f63a42..f76b8fdee8 100644 --- a/web/themes/ventuno/templates/content/page-title--node--release.html.twig +++ b/web/themes/ventuno/templates/content/page-title--node--release.html.twig @@ -4,6 +4,7 @@ * Template for the page title. */ #} +{% set permalink = entity.getPermalink() %} {{ attach_library('ventuno/page-title') }} {{ title_prefix }} {% if title %} -- GitLab From 096f95f8477fac171fe60032a2a7e9f2ead4e3ef Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:16:58 +0200 Subject: [PATCH 063/149] ISAICP-4724: Use trait for permalink in page_title template. We may have an entity without the method getPermalink(), in that case we have no errors, it's not a problem. Examples: In the members page, permalink will be empty; In videos, the method is used and generates a permalink. --- web/themes/ventuno/templates/content/page-title.html.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/web/themes/ventuno/templates/content/page-title.html.twig b/web/themes/ventuno/templates/content/page-title.html.twig index ac27a9e7aa..b978611fcb 100644 --- a/web/themes/ventuno/templates/content/page-title.html.twig +++ b/web/themes/ventuno/templates/content/page-title.html.twig @@ -4,6 +4,7 @@ * Template for the page title. */ #} +{% set permalink = entity.getPermalink() %} {{ attach_library('ventuno/page-title') }} {{ title_prefix }} {% if title %} -- GitLab From b2b00919365e3916f5585e59aba249daca5d1422 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:21:19 +0200 Subject: [PATCH 064/149] ISAICP-4724: Use trait for permalinks in events. --- web/modules/custom/joinup_licence/src/Entity/Licence.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/modules/custom/joinup_licence/src/Entity/Licence.php b/web/modules/custom/joinup_licence/src/Entity/Licence.php index 6d78f4740b..b22e241485 100644 --- a/web/modules/custom/joinup_licence/src/Entity/Licence.php +++ b/web/modules/custom/joinup_licence/src/Entity/Licence.php @@ -6,6 +6,7 @@ use Drupal\joinup_bundle_class\DescriptionTrait; use Drupal\joinup_bundle_class\JoinupBundleClassFieldAccessTrait; +use Drupal\joinup_group\Entity\GroupContentTrait; use Drupal\joinup_rdf\Entity\RdfSyncEntityTrait; use Drupal\node\Entity\Node; @@ -17,6 +18,7 @@ class Licence extends Node implements LicenceInterface { use DescriptionTrait; use JoinupBundleClassFieldAccessTrait; use RdfSyncEntityTrait; + use GroupContentTrait; /** * {@inheritdoc} -- GitLab From 0549d2239c13d13a0cbf13650798e6fd4696fd10 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:22:05 +0200 Subject: [PATCH 065/149] ISAICP-4724: Remove old code for permalinks. --- web/themes/ventuno/includes/page_title.inc | 8 +--- web/themes/ventuno/includes/utility.inc | 50 ---------------------- 2 files changed, 1 insertion(+), 57 deletions(-) diff --git a/web/themes/ventuno/includes/page_title.inc b/web/themes/ventuno/includes/page_title.inc index 788dde1a77..6debf04c89 100644 --- a/web/themes/ventuno/includes/page_title.inc +++ b/web/themes/ventuno/includes/page_title.inc @@ -13,12 +13,6 @@ * Implements hook_preprocess_page_title(). */ function ventuno_preprocess_page_title(array &$variables): void { - // @todo Move the permalink computing outside the theme layer, in ISAICP-4724. - // @see https://citnet.tech.ec.europa.eu/CITnet/jira/browse/ISAICP-4724 - if ($permalink = _ventuno_build_permalink()) { - $variables['permalink'] = $permalink; - } - $entity = $variables['entity'] ?? NULL; if ($entity instanceof CommunityContentInterface) { $variables['bundle'] = $entity->get('type')->entity->bundle(); @@ -109,7 +103,7 @@ function ventuno_preprocess_page_title__node__glossary(array &$variables): void * Implements hook_preprocess_HOOK() for page-title--node--document.html.twig. */ function ventuno_preprocess_page_title__node__document(&$variables): void { - /** @var \Drupal\joinup_document\Entity\DocumentInterface $node */ + /** @var \Drupal\joinup_document\Entity\Document $node */ $node = $variables['entity']; /** @var \Drupal\Core\Entity\EntityViewBuilderInterface $view_builder */ diff --git a/web/themes/ventuno/includes/utility.inc b/web/themes/ventuno/includes/utility.inc index 99e1303e2b..958495b818 100644 --- a/web/themes/ventuno/includes/utility.inc +++ b/web/themes/ventuno/includes/utility.inc @@ -12,9 +12,7 @@ use Drupal\joinup_bundle_class\DescriptionInterface; use Drupal\joinup_bundle_class\LogoInterface; use Drupal\joinup_community_content\Entity\CommunityContentInterface; -use Drupal\joinup_core\Controller\IdRedirect; use Drupal\joinup_oss_catalogue\Entity\JoinupOssSolution; -use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; use Drupal\joinup_workflow\ArchivableEntityInterface; use Drupal\smart_trim\TruncateHTML; use Drupal\topic\Entity\TopicReferencingEntityInterface; @@ -293,54 +291,6 @@ function _ventuno_get_default_icon(string $entity_type_id, string $bundle): stri return $mapping[$entity_type_id][$bundle] ?? 'lightning-charge'; } -/** - * Builds the permalink for the given route. - * - * @return string|null - * The permalink URI. - */ -function _ventuno_build_permalink(): ?string { - $route_match = \Drupal::routeMatch(); - $route_name = $route_match->getRouteName(); - - $routes = [ - 'entity.node.canonical', - 'entity.rdf_entity.canonical', - ]; - - if (!in_array($route_name, $routes)) { - return NULL; - } - - if (!($parameters = $route_match->getRouteObject()->getOption('parameters')) || empty($parameters)) { - return NULL; - } - - foreach ($parameters as $key => $info) { - if (!empty($info['type']) && $info['type'] == "entity:$key") { - $type = $key; - break; - } - } - - if (!isset($type) || !($entity = $route_match->getParameter($type))) { - return NULL; - } - - // Entity ID is pointing to the publication office redirect. - $namespaces = implode('|', array_keys(IdRedirect::getEntityTypeFromPersistentUriNamespace())); - $uri = $entity instanceof RdfSyncEntityInterface ? $entity->getUri() : $entity->id(); - if (preg_match('{^http://data.europa.eu/(?:' . $namespaces . ')/}', $uri)) { - return $uri; - } - - // Don't process the path to avoid pathauto aliasing. - return $entity->toUrl('canonical', [ - 'path_processing' => FALSE, - 'absolute' => TRUE, - ])->toString(); -} - /** * Provides a helper to create suggestions per view mode. * -- GitLab From e78ac7cc4e1f6c2360dd4e39fc22d3df8f462117 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 14 Aug 2024 20:22:42 +0200 Subject: [PATCH 066/149] ISAICP-4724: Refactor permalinks code for comments. --- .../joinup_community_content.module | 3 ++- .../Entity/JoinupCommunityContentComment.php | 25 +++++++++++++++++++ web/themes/ventuno/includes/comment.inc | 4 --- .../templates/content/comment.html.twig | 4 ++- 4 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php diff --git a/web/modules/custom/joinup_community_content/joinup_community_content.module b/web/modules/custom/joinup_community_content/joinup_community_content.module index 99f1b62efc..9dec007bdc 100644 --- a/web/modules/custom/joinup_community_content/joinup_community_content.module +++ b/web/modules/custom/joinup_community_content/joinup_community_content.module @@ -17,6 +17,7 @@ use Drupal\Core\Url; use Drupal\joinup_community_content\CommunityContentHelper; use Drupal\joinup_community_content\Entity\CommunityContentInterface; +use Drupal\joinup_community_content\Entity\JoinupCommunityContentComment; use Drupal\joinup_community_content\JoinupCommunityContentCommentAccessControlHandler; use Drupal\joinup_community_content\Plugin\views\filter\JoinupContentState; use Drupal\joinup_discussion\Entity\DiscussionInterface; @@ -280,8 +281,8 @@ function joinup_community_content_translate_facet_arguments(array $arguments): a * Implements hook_entity_type_alter(). */ function joinup_community_content_entity_type_alter(array &$entity_types): void { - // Swap out access handler for comments. if (isset($entity_types['comment'])) { + $entity_types['comment']->setClass(JoinupCommunityContentComment::class); $entity_types['comment']->setAccessClass(JoinupCommunityContentCommentAccessControlHandler::class); } } diff --git a/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php new file mode 100644 index 0000000000..c396c28c73 --- /dev/null +++ b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php @@ -0,0 +1,25 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\joinup_community_content\Entity; + +use Drupal\comment\Entity\Comment; +use Drupal\joinup_core\Entity\PermalinkInterface; + +/** + * Entity subclass for the 'comment'. + */ +class JoinupCommunityContentComment extends Comment implements PermalinkInterface { + + /** + * {@inheritdoc} + */ + public function getPermalink(): ?string { + if (!$this->in_preview) { + return $this->permalink()->toString(); + } + return NULL; + } + +} diff --git a/web/themes/ventuno/includes/comment.inc b/web/themes/ventuno/includes/comment.inc index aec91f3a9f..bf249f6a71 100644 --- a/web/themes/ventuno/includes/comment.inc +++ b/web/themes/ventuno/includes/comment.inc @@ -62,8 +62,4 @@ function ventuno_preprocess_comment(array &$variables): void { $cache_metadata ->addCacheTags($user->getEntityType()->getListCacheTags()) ->applyTo($variables['user_picture']); - - if (!$comment->in_preview) { - $variables['permalink_raw'] = $comment->permalink(); - } } diff --git a/web/themes/ventuno/templates/content/comment.html.twig b/web/themes/ventuno/templates/content/comment.html.twig index eca3bf0c18..713a4eb49b 100644 --- a/web/themes/ventuno/templates/content/comment.html.twig +++ b/web/themes/ventuno/templates/content/comment.html.twig @@ -4,6 +4,8 @@ * Template for a comment. */ #} + +{% set permalink = comment.getPermalink() %} <article{{ attributes.addClass('js-comment', 'comment', 'my-3') }}> {# Hide the "new" indicator by default, let a piece of JavaScript ask the @@ -23,7 +25,7 @@ <span class="comment__detail">{{ created }}</span> {% if permalink %} <span class="comment__detail"> - <a class="permalink" href="{{ permalink_raw }}" title="{{ 'Permalink'|t }}"> + <a class="permalink" href="{{ permalink }}" title="{{ 'Permalink'|t }}"> {{ pattern('icon', { name: 'link-45deg', size: 's' -- GitLab From 9d180a25da2af6791535470ab37f367a44c2c708 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Thu, 22 Aug 2024 09:17:15 +0200 Subject: [PATCH 067/149] ISAICP-4724: Return Url object instead of string in permalink methods. --- .../src/Entity/JoinupCommunityContentComment.php | 5 +++-- .../custom/joinup_core/src/Entity/PermalinkInterface.php | 6 ++++-- .../custom/joinup_core/src/Entity/PermalinkTrait.php | 7 ++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php index c396c28c73..2f8e0ce791 100644 --- a/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php +++ b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php @@ -4,6 +4,7 @@ namespace Drupal\joinup_community_content\Entity; +use Drupal\Core\Url; use Drupal\comment\Entity\Comment; use Drupal\joinup_core\Entity\PermalinkInterface; @@ -15,9 +16,9 @@ class JoinupCommunityContentComment extends Comment implements PermalinkInterfac /** * {@inheritdoc} */ - public function getPermalink(): ?string { + public function getPermalink(): ?Url { if (!$this->in_preview) { - return $this->permalink()->toString(); + return $this->permalink(); } return NULL; } diff --git a/web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php b/web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php index 66d0287c0e..b3fff16633 100644 --- a/web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php +++ b/web/modules/custom/joinup_core/src/Entity/PermalinkInterface.php @@ -4,6 +4,8 @@ namespace Drupal\joinup_core\Entity; +use Drupal\Core\Url; + /** * Entity with a permalink. */ @@ -12,9 +14,9 @@ interface PermalinkInterface { /** * Returns the permalink for the entity. * - * @return string|null + * @return \Drupal\Core\Url|null * The permalink if it exists. */ - public function getPermalink(): ?string; + public function getPermalink(): ?Url; } diff --git a/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php b/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php index 0cc0461703..5133cbd5a7 100644 --- a/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php +++ b/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php @@ -4,6 +4,7 @@ namespace Drupal\joinup_core\Entity; +use Drupal\Core\Url; use Drupal\joinup_core\Controller\IdRedirect; use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; @@ -17,12 +18,12 @@ trait PermalinkTrait { /** * {@inheritdoc} */ - public function getPermalink(): ?string { + public function getPermalink(): ?Url { // Entity ID is pointing to the publication office redirect. $namespaces = implode('|', array_keys(IdRedirect::getEntityTypeFromPersistentUriNamespace())); $uri = $this instanceof RdfSyncEntityInterface ? $this->getUri() : $this->id(); if (preg_match('{^http://data.europa.eu/(?:' . $namespaces . ')/}', $uri)) { - return $uri; + return Url::fromUri($uri); } try { @@ -30,7 +31,7 @@ public function getPermalink(): ?string { return $this->toUrl('canonical', [ 'path_processing' => FALSE, 'absolute' => TRUE, - ])->toString(); + ]); } catch (\Exception $e) { return NULL; -- GitLab From 0f93dd01f93bf881564de94f1c1861090ebcd226 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Thu, 22 Aug 2024 09:18:07 +0200 Subject: [PATCH 068/149] ISAICP-4724: Handle exceptions in permalink method for comments. --- .../src/Entity/JoinupCommunityContentComment.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php index 2f8e0ce791..29e2c17caa 100644 --- a/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php +++ b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php @@ -17,10 +17,12 @@ class JoinupCommunityContentComment extends Comment implements PermalinkInterfac * {@inheritdoc} */ public function getPermalink(): ?Url { - if (!$this->in_preview) { + try { return $this->permalink(); } - return NULL; + catch (\Exception $e) { + return NULL; + } } } -- GitLab From e0ed6e06656b4feec2cbe255ec3f075182bda546 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Mon, 9 Sep 2024 18:35:51 +0200 Subject: [PATCH 069/149] ISAICP-4724: Move EntityOwnerTrait usage declaration from GroupContent to the entitiy class that need it. --- .../custom/joinup_distribution/src/Entity/Distribution.php | 4 +++- .../joinup_distribution/src/Entity/DistributionInterface.php | 3 ++- .../custom/joinup_group/src/Entity/GroupContentInterface.php | 3 +-- .../custom/joinup_group/src/Entity/GroupContentTrait.php | 2 -- web/modules/custom/joinup_licence/src/Entity/Licence.php | 4 ++-- .../custom/joinup_licence/src/Entity/LicenceInterface.php | 3 ++- web/modules/custom/joinup_release/src/Entity/Release.php | 5 +++-- .../custom/joinup_release/src/Entity/ReleaseInterface.php | 3 ++- 8 files changed, 15 insertions(+), 12 deletions(-) diff --git a/web/modules/custom/joinup_distribution/src/Entity/Distribution.php b/web/modules/custom/joinup_distribution/src/Entity/Distribution.php index a4482b84aa..b2459d2b7e 100644 --- a/web/modules/custom/joinup_distribution/src/Entity/Distribution.php +++ b/web/modules/custom/joinup_distribution/src/Entity/Distribution.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\file_url\FileUrlHandler; use Drupal\joinup_bundle_class\DescriptionTrait; +use Drupal\joinup_core\Entity\PermalinkTrait; use Drupal\joinup_distribution\Exception\MissingDistributionParentException; use Drupal\joinup_group\Entity\GroupContentTrait; use Drupal\joinup_publication_date\Entity\EntityPublicationTimeFallbackTrait; @@ -29,11 +30,12 @@ class Distribution extends Node implements DistributionInterface { use ArchivableEntityTrait; use DescriptionTrait; use DownloadCountAwareTrait; + use EntityPublicationTimeFallbackTrait; use EntityWorkflowStateTrait; use GroupContentTrait; + use PermalinkTrait; use RdfSyncEntityTrait; use SolutionContentTrait; - use EntityPublicationTimeFallbackTrait; /** * Fields populated with statistical information by the joinup_stats module. diff --git a/web/modules/custom/joinup_distribution/src/Entity/DistributionInterface.php b/web/modules/custom/joinup_distribution/src/Entity/DistributionInterface.php index 273ab2aab9..f026060738 100644 --- a/web/modules/custom/joinup_distribution/src/Entity/DistributionInterface.php +++ b/web/modules/custom/joinup_distribution/src/Entity/DistributionInterface.php @@ -6,6 +6,7 @@ use Drupal\collection\Entity\CollectionContentInterface; use Drupal\joinup_bundle_class\DescriptionInterface; +use Drupal\joinup_core\Entity\PermalinkInterface; use Drupal\joinup_publication_date\Entity\EntityPublicationTimeInterface; use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; use Drupal\joinup_stats\Entity\DownloadCountAwareInterface; @@ -17,7 +18,7 @@ /** * Interface for distributions. */ -interface DistributionInterface extends NodeInterface, RdfSyncEntityInterface, CollectionContentInterface, SolutionContentInterface, DownloadCountAwareInterface, DescriptionInterface, EntityPublicationTimeInterface, EntityWorkflowStateInterface, ArchivableEntityInterface { +interface DistributionInterface extends NodeInterface, RdfSyncEntityInterface, CollectionContentInterface, SolutionContentInterface, DownloadCountAwareInterface, DescriptionInterface, EntityPublicationTimeInterface, EntityWorkflowStateInterface, ArchivableEntityInterface, PermalinkInterface { /** * Return the distribution's parent, either a release or a solution. diff --git a/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php b/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php index 0f9c11e019..2806bb5031 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupContentInterface.php @@ -6,7 +6,6 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Field\EntityReferenceFieldItemList; -use Drupal\joinup_core\Entity\PermalinkInterface; /** * Interface for entities that are group content. @@ -15,7 +14,7 @@ * - collections: community content, custom pages, and solutions. * - solutions: asset releases and asset distributions. */ -interface GroupContentInterface extends ContentEntityInterface, PermalinkInterface { +interface GroupContentInterface extends ContentEntityInterface { /** * Returns whether or not the entity is associated with a group. diff --git a/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php b/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php index 95bb40607b..c2ff76a1f5 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupContentTrait.php @@ -6,7 +6,6 @@ use Drupal\Core\Field\EntityReferenceFieldItemList; use Drupal\joinup_bundle_class\JoinupBundleClassFieldAccessTrait; -use Drupal\joinup_core\Entity\PermalinkTrait; use Drupal\joinup_group\Exception\MissingGroupException; use Drupal\og\OgGroupAudienceHelperInterface; @@ -16,7 +15,6 @@ trait GroupContentTrait { use JoinupBundleClassFieldAccessTrait; - use PermalinkTrait; /** * {@inheritdoc} diff --git a/web/modules/custom/joinup_licence/src/Entity/Licence.php b/web/modules/custom/joinup_licence/src/Entity/Licence.php index b22e241485..882bb20dc5 100644 --- a/web/modules/custom/joinup_licence/src/Entity/Licence.php +++ b/web/modules/custom/joinup_licence/src/Entity/Licence.php @@ -6,7 +6,7 @@ use Drupal\joinup_bundle_class\DescriptionTrait; use Drupal\joinup_bundle_class\JoinupBundleClassFieldAccessTrait; -use Drupal\joinup_group\Entity\GroupContentTrait; +use Drupal\joinup_core\Entity\PermalinkTrait; use Drupal\joinup_rdf\Entity\RdfSyncEntityTrait; use Drupal\node\Entity\Node; @@ -17,8 +17,8 @@ class Licence extends Node implements LicenceInterface { use DescriptionTrait; use JoinupBundleClassFieldAccessTrait; + use PermalinkTrait; use RdfSyncEntityTrait; - use GroupContentTrait; /** * {@inheritdoc} diff --git a/web/modules/custom/joinup_licence/src/Entity/LicenceInterface.php b/web/modules/custom/joinup_licence/src/Entity/LicenceInterface.php index fa7513bdd8..7d39e51ea5 100644 --- a/web/modules/custom/joinup_licence/src/Entity/LicenceInterface.php +++ b/web/modules/custom/joinup_licence/src/Entity/LicenceInterface.php @@ -5,13 +5,14 @@ namespace Drupal\joinup_licence\Entity; use Drupal\joinup_bundle_class\DescriptionInterface; +use Drupal\joinup_core\Entity\PermalinkInterface; use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; use Drupal\node\NodeInterface; /** * Interface for licence nodes. */ -interface LicenceInterface extends NodeInterface, RdfSyncEntityInterface, DescriptionInterface { +interface LicenceInterface extends NodeInterface, RdfSyncEntityInterface, DescriptionInterface, PermalinkInterface { /** * Returns the legal types to which this licence conforms. diff --git a/web/modules/custom/joinup_release/src/Entity/Release.php b/web/modules/custom/joinup_release/src/Entity/Release.php index b94efccf3c..8fc00da79e 100644 --- a/web/modules/custom/joinup_release/src/Entity/Release.php +++ b/web/modules/custom/joinup_release/src/Entity/Release.php @@ -6,6 +6,7 @@ use Drupal\joinup_bundle_class\DescriptionTrait; use Drupal\joinup_bundle_class\JoinupBundleClassFieldAccessTrait; +use Drupal\joinup_core\Entity\PermalinkTrait; use Drupal\joinup_distribution\Entity\DistributionParentTrait; use Drupal\joinup_group\Entity\GroupContentTrait; use Drupal\joinup_group\Exception\MissingGroupException; @@ -26,14 +27,14 @@ class Release extends Node implements ReleaseInterface { use ArchivableEntityTrait; use DescriptionTrait; use DistributionParentTrait; + use EntityOwnerTrait; use EntityPublicationTimeFallbackTrait; use EntityWorkflowStateTrait; use GroupContentTrait; use JoinupBundleClassFieldAccessTrait; + use PermalinkTrait; use RdfSyncEntityTrait; use SolutionContentTrait; - use EntityOwnerTrait; - use EntityPublicationTimeFallbackTrait; /** * {@inheritdoc} diff --git a/web/modules/custom/joinup_release/src/Entity/ReleaseInterface.php b/web/modules/custom/joinup_release/src/Entity/ReleaseInterface.php index 511c1bf2a8..647c2fe686 100644 --- a/web/modules/custom/joinup_release/src/Entity/ReleaseInterface.php +++ b/web/modules/custom/joinup_release/src/Entity/ReleaseInterface.php @@ -6,6 +6,7 @@ use Drupal\collection\Entity\CollectionContentInterface; use Drupal\joinup_bundle_class\DescriptionInterface; +use Drupal\joinup_core\Entity\PermalinkInterface; use Drupal\joinup_distribution\Entity\DistributionsParentInterface; use Drupal\joinup_publication_date\Entity\EntityPublicationTimeInterface; use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; @@ -18,7 +19,7 @@ /** * Interface for asset release entities in Joinup. */ -interface ReleaseInterface extends NodeInterface, RdfSyncEntityInterface, CollectionContentInterface, SolutionContentInterface, EntityPublicationTimeInterface, EntityWorkflowStateInterface, DistributionsParentInterface, DescriptionInterface, ArchivableEntityInterface { +interface ReleaseInterface extends NodeInterface, RdfSyncEntityInterface, CollectionContentInterface, SolutionContentInterface, EntityPublicationTimeInterface, EntityWorkflowStateInterface, DistributionsParentInterface, DescriptionInterface, ArchivableEntityInterface, PermalinkInterface { /** * Checks whether this release is the latest release of the parent solution. -- GitLab From 7d14b70e28f47dfc49e0158efd3d8f8bd77f2ea5 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 11 Sep 2024 16:53:32 +0200 Subject: [PATCH 070/149] ISAICP-4724: Make permalink a computed field for nodes. --- .../custom/joinup_core/joinup_core.module | 23 ++++++++ .../joinup_core/src/Entity/PermalinkTrait.php | 21 +------ .../FieldType/PermalinkFieldItemList.php | 57 +++++++++++++++++++ 3 files changed, 83 insertions(+), 18 deletions(-) create mode 100644 web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php diff --git a/web/modules/custom/joinup_core/joinup_core.module b/web/modules/custom/joinup_core/joinup_core.module index 71a29139dc..2734989b8e 100644 --- a/web/modules/custom/joinup_core/joinup_core.module +++ b/web/modules/custom/joinup_core/joinup_core.module @@ -24,9 +24,11 @@ use Drupal\joinup_core\Element\Datetime; use Drupal\joinup_core\Entity\OutdatedContentInterface; use Drupal\joinup_core\Plugin\Field\FieldType\OutdatedContentFieldItemList; +use Drupal\joinup_core\Plugin\Field\FieldType\PermalinkFieldItemList; use Drupal\joinup_core\Plugin\Field\FieldWidget\ImageLibraryWidget; use Drupal\joinup_group\Entity\GroupInterface; use Drupal\joinup_workflow\ArchivableEntityInterface; +use Drupal\link\LinkItemInterface; use Drupal\node\NodeInterface; use Drupal\symfony_mailer_lite\Plugin\Mail\SymfonyMailer; @@ -412,6 +414,27 @@ function joinup_core_entity_bundle_field_info(EntityTypeInterface $entity_type, ->setCardinality(1) ->setDefaultValue(NULL); } + + $permalink_bundles = [ + 'node' => ['custom_page', 'discussion', 'distribution', 'document', 'event', 'licence', 'news', 'release'], + ]; + if (in_array($bundle, $permalink_bundles[$entity_type->id()] ?? [])) { + $fields['permalink'] = BaseFieldDefinition::create('link') + ->setLabel(t('Permalink')) + ->setDescription(t('The permalink for the entity.')) + ->setComputed(TRUE) + ->setRequired(FALSE) + ->setClass(PermalinkFieldItemList::class) + ->setCardinality(1) + ->setDefaultValue(NULL) + ->setSettings([ + 'link_type' => LinkItemInterface::LINK_INTERNAL, + 'title' => DRUPAL_DISABLED, + ]) + ->setDisplayConfigurable('form', FALSE) + ->setDisplayConfigurable('display', FALSE); + } + return $fields; } diff --git a/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php b/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php index 5133cbd5a7..f38a2aebdc 100644 --- a/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php +++ b/web/modules/custom/joinup_core/src/Entity/PermalinkTrait.php @@ -5,8 +5,6 @@ namespace Drupal\joinup_core\Entity; use Drupal\Core\Url; -use Drupal\joinup_core\Controller\IdRedirect; -use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; /** * Reusable code for classes implementing PermalinkInterface interface. @@ -19,23 +17,10 @@ trait PermalinkTrait { * {@inheritdoc} */ public function getPermalink(): ?Url { - // Entity ID is pointing to the publication office redirect. - $namespaces = implode('|', array_keys(IdRedirect::getEntityTypeFromPersistentUriNamespace())); - $uri = $this instanceof RdfSyncEntityInterface ? $this->getUri() : $this->id(); - if (preg_match('{^http://data.europa.eu/(?:' . $namespaces . ')/}', $uri)) { - return Url::fromUri($uri); - } - - try { - // Don't process the path to avoid pathauto aliasing. - return $this->toUrl('canonical', [ - 'path_processing' => FALSE, - 'absolute' => TRUE, - ]); - } - catch (\Exception $e) { - return NULL; + if ($this->hasField('permalink') && !$this->get('permalink')->isEmpty()) { + return $this->get('permalink')->first()->getUrl(); } + return NULL; } } diff --git a/web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php b/web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php new file mode 100644 index 0000000000..db4811da10 --- /dev/null +++ b/web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php @@ -0,0 +1,57 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\joinup_core\Plugin\Field\FieldType; + +use Drupal\Core\Field\FieldItemList; +use Drupal\Core\TypedData\ComputedItemListTrait; +use Drupal\Core\Url; +use Drupal\joinup_core\Controller\IdRedirect; +use Drupal\joinup_core\Entity\PermalinkInterface; +use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; + +/** + * Field item list class for the 'permalink' bundle base field. + * + * @see joinup_core_entity_bundle_field_info() + */ +class PermalinkFieldItemList extends FieldItemList { + + use ComputedItemListTrait; + + /** + * {@inheritdoc} + */ + protected function computeValue(): void { + $entity = $this->getEntity(); + assert($entity instanceof PermalinkInterface); + + if ($entity->isNew()) { + $this->list[0] = $this->createItem(0, NULL); + return; + } + + // Entity ID is pointing to the publication office redirect. + $namespaces = implode('|', array_keys(IdRedirect::getEntityTypeFromPersistentUriNamespace())); + $uri = $entity instanceof RdfSyncEntityInterface ? $entity->getUri() : $entity->id(); + if ($uri && preg_match('{^http://data.europa.eu/(?:' . $namespaces . ')/}', $uri)) { + $value = Url::fromUri($uri)->toString(); + } + else { + try { + // Don't process the path to avoid pathauto aliasing. + $value = $entity->toUrl('canonical', [ + 'path_processing' => FALSE, + 'absolute' => TRUE, + ])->toString(); + } + catch (\Exception $e) { + $value = NULL; + } + } + + $this->list[0] = $this->createItem(0, $value); + } + +} -- GitLab From 4e6b2147e8b80c357bf7ef89002f8a612cfcb71f Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 12 Sep 2024 08:22:20 +0200 Subject: [PATCH 071/149] ISAICP-8816: Dont display field if it does not have any values. --- .../src/Form/AnnouncementForm.php | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index 1df4a1a9da..943d6a05ff 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -135,16 +135,19 @@ public function buildForm(array $form, FormStateInterface $form_state): array { }, array_keys($arguments))), ]; - $form['professional_domain'] = [ - '#type' => 'select', - '#title' => $this->t('Professional domain'), - '#description' => $this->t('By picking any value, you will limit the recipients of the announcement.'), - '#options' => $this->getOptions(), - '#default_value' => $this->announcement->getProfessionalDomainIds(), - '#multiple' => TRUE, - '#required' => FALSE, - '#size' => 10, - ]; + $domain_options = $this->getOptions(); + if ($domain_options) { + $form['professional_domain'] = [ + '#type' => 'select', + '#title' => $this->t('Professional domain'), + '#description' => $this->t('By picking any value, you will limit the recipients of the announcement.'), + '#options' => $this->getOptions(), + '#default_value' => $this->announcement->getProfessionalDomainIds(), + '#multiple' => TRUE, + '#required' => FALSE, + '#size' => 10, + ]; + } $form['state'] = [ '#type' => 'item', @@ -218,7 +221,7 @@ public function submitForm(array &$form, FormStateInterface $form_state): void { $this->announcement ->setSubject($form_state->getValue('subject')) - ->setProfessionalDomains($form_state->getValue('professional_domain')) + ->setProfessionalDomains($form_state->getValue('professional_domain', [])) ->setBody($form_state->getValue(['body', 'value'])) // Only save the arguments having a 'value' key. Some arguments depend on // the email recipient and will be dynamically set when the email is sent. -- GitLab From ee5a6f1e5a1853914f8ee657d71b5bc5fd2a9ebb Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 12 Sep 2024 10:31:07 +0200 Subject: [PATCH 072/149] ISAICP-8816: Add tests. --- .../joinup_group/announcements.feature | 1 + .../announcements.professional_domain.feature | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/features/joinup_group/announcements.professional_domain.feature diff --git a/tests/features/joinup_group/announcements.feature b/tests/features/joinup_group/announcements.feature index f74503c58e..4702c5ebde 100644 --- a/tests/features/joinup_group/announcements.feature +++ b/tests/features/joinup_group/announcements.feature @@ -68,6 +68,7 @@ Feature: Messaging group announcements When I go to the members page of "Fail pension" And I click "Add announcement" Then the following fields should be present "Subject,Body" + But the following fields should not be present "Professional domain" And I should see the following lines of text: | Select dynamic placeholders for your announcement | | Copy and paste, in the message body, one or more placeholder(s) (e.g. @recipient_name) and the corresponding shortcut link(s) will be displayed in the announcement email. Available placeholders: | diff --git a/tests/features/joinup_group/announcements.professional_domain.feature b/tests/features/joinup_group/announcements.professional_domain.feature new file mode 100644 index 0000000000..f6cf92d1d9 --- /dev/null +++ b/tests/features/joinup_group/announcements.professional_domain.feature @@ -0,0 +1,71 @@ +@api @group-e +Feature: Filter announcements by professional domain + + Scenario Outline: User can narrow down targeted users based on the business domains. + Given the following <group>s: + | title | state | + | Pension funds | published | + And users: + | Username | E-mail | Professional domain | Status | + | Mogul | mogul@example.com | Demography, E-health, E-justice, HR, HR | active | + | Greedy | greedy@example.com | Demography, E-health, E-justice | active | + | Envious | envy@example.com | Demography, E-health | active | + | Coward | coward@example.com | Demography | active | + | Nick | nick@example.com | Demography | active | + | Mark | mark@example.com | Demography | active | + | Anthony | mark@example.com | Demography | active | + | Frank | frank@example.com | Demography | blocked | + And the following <group> user membership: + | <group> | user | announcements | state | + | Pension funds | Mogul | 1 | active | + | Pension funds | Greedy | 1 | active | + | Pension funds | Envious | 1 | active | + | Pension funds | Coward | 1 | active | + | Pension funds | Nick | 1 | active | + | Pension funds | Mark | 0 | active | + | Pension funds | Anthony | 1 | blocked | + | Pension funds | Frank | 1 | active | + And the following legal document version: + | Document | Label | Published | Acceptance label | Content | + | Legal notice | 1.1 | yes | I have read and accept | The information on this site is ... | + And the following "Legal notice" acceptances: + | Mogul | + | Greedy | + | Envious | + | Coward | + # Nick has not accepted legal notice. + | Mark | + | Anthony | + | Frank | + And the following "Legal notice" acceptances: + | Mogul | + | Greedy | + And the following announcements: + | group | subject | body | state | + | Pension funds | Demography announcement | Body for Demography | sent | + | Pension funds | E-health and E-justice announcement | Body for E-health and E-justice | sent | + + Given I am logged in as a moderator + + When I go to the "Demography announcement" announcement of "Pension funds" <group> + Then the following fields should be present "Professional domain" + And the "Professional domain" field should contain the "E-health Dpt., HR Dpt., Law and Justice, Social and Political" option groups + And the "Professional domain" select should contain the following options: + | -E-health (3) | + | -HR (1) | + | -E-justice (2) | + | -Demography (6) | + When I select "-Demography (6)" from "Professional domain" + And I press "Approve" + Then 5 e-mails should have been sent + + When I mark all emails as read + And I go to the "E-health and E-justice announcement" announcement of "Pension funds" <group> + And I select "-E-justice (2)" from "Professional domain" + And I press "Approve" + Then 2 e-mails should have been sent + + Examples: + | group | + | collection | + | solution | -- GitLab From 3eea75d48c71ff356e7622202f9112b0c7392ce6 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Wed, 11 Sep 2024 18:53:52 +0200 Subject: [PATCH 073/149] ISAICP-4724: Make permalink a computed field for comments. --- .../Entity/JoinupCommunityContentComment.php | 14 +------ .../custom/joinup_core/joinup_core.module | 1 + .../FieldType/PermalinkFieldItemList.php | 38 ++++++++++++------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php index 29e2c17caa..d7341d7efa 100644 --- a/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php +++ b/web/modules/custom/joinup_community_content/src/Entity/JoinupCommunityContentComment.php @@ -4,25 +4,15 @@ namespace Drupal\joinup_community_content\Entity; -use Drupal\Core\Url; use Drupal\comment\Entity\Comment; use Drupal\joinup_core\Entity\PermalinkInterface; +use Drupal\joinup_core\Entity\PermalinkTrait; /** * Entity subclass for the 'comment'. */ class JoinupCommunityContentComment extends Comment implements PermalinkInterface { - /** - * {@inheritdoc} - */ - public function getPermalink(): ?Url { - try { - return $this->permalink(); - } - catch (\Exception $e) { - return NULL; - } - } + use PermalinkTrait; } diff --git a/web/modules/custom/joinup_core/joinup_core.module b/web/modules/custom/joinup_core/joinup_core.module index 2734989b8e..5571705c66 100644 --- a/web/modules/custom/joinup_core/joinup_core.module +++ b/web/modules/custom/joinup_core/joinup_core.module @@ -417,6 +417,7 @@ function joinup_core_entity_bundle_field_info(EntityTypeInterface $entity_type, $permalink_bundles = [ 'node' => ['custom_page', 'discussion', 'distribution', 'document', 'event', 'licence', 'news', 'release'], + 'comment' => ['comment', 'reply'], ]; if (in_array($bundle, $permalink_bundles[$entity_type->id()] ?? [])) { $fields['permalink'] = BaseFieldDefinition::create('link') diff --git a/web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php b/web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php index db4811da10..b67c005cfb 100644 --- a/web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php +++ b/web/modules/custom/joinup_core/src/Plugin/Field/FieldType/PermalinkFieldItemList.php @@ -7,9 +7,11 @@ use Drupal\Core\Field\FieldItemList; use Drupal\Core\TypedData\ComputedItemListTrait; use Drupal\Core\Url; +use Drupal\comment\CommentInterface; use Drupal\joinup_core\Controller\IdRedirect; use Drupal\joinup_core\Entity\PermalinkInterface; use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface; +use Drupal\node\NodeInterface; /** * Field item list class for the 'permalink' bundle base field. @@ -32,24 +34,32 @@ protected function computeValue(): void { return; } - // Entity ID is pointing to the publication office redirect. - $namespaces = implode('|', array_keys(IdRedirect::getEntityTypeFromPersistentUriNamespace())); - $uri = $entity instanceof RdfSyncEntityInterface ? $entity->getUri() : $entity->id(); - if ($uri && preg_match('{^http://data.europa.eu/(?:' . $namespaces . ')/}', $uri)) { - $value = Url::fromUri($uri)->toString(); - } - else { - try { - // Don't process the path to avoid pathauto aliasing. - $value = $entity->toUrl('canonical', [ - 'path_processing' => FALSE, - 'absolute' => TRUE, - ])->toString(); + try { + if ($entity instanceof NodeInterface) { + // Entity ID is pointing to the publication office redirect. + $namespaces = implode('|', array_keys(IdRedirect::getEntityTypeFromPersistentUriNamespace())); + $uri = $entity instanceof RdfSyncEntityInterface ? $entity->getUri() : $entity->id(); + if ($uri && preg_match('{^http://data.europa.eu/(?:' . $namespaces . ')/}', $uri)) { + $value = Url::fromUri($uri)->toString(); + } + else { + // Don't process the path to avoid pathauto aliasing. + $value = $entity->toUrl('canonical', [ + 'path_processing' => FALSE, + 'absolute' => TRUE, + ])->toString(); + } + } + elseif ($entity instanceof CommentInterface) { + $value = $entity->permalink()->setOption('absolute', TRUE)->toString(); } - catch (\Exception $e) { + else { $value = NULL; } } + catch (\Exception $e) { + $value = NULL; + } $this->list[0] = $this->createItem(0, $value); } -- GitLab From 7d4b89f344572c5e4e74976d0cb0497498c3ae03 Mon Sep 17 00:00:00 2001 From: Diogo Vargas <diogo.vargas@ext.ec.europa.eu> Date: Thu, 12 Sep 2024 10:10:13 +0200 Subject: [PATCH 074/149] ISAICP-4724: Fix test, permalink should be considered an external url. --- web/modules/custom/joinup_core/joinup_core.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_core/joinup_core.module b/web/modules/custom/joinup_core/joinup_core.module index 5571705c66..518a214062 100644 --- a/web/modules/custom/joinup_core/joinup_core.module +++ b/web/modules/custom/joinup_core/joinup_core.module @@ -429,7 +429,7 @@ function joinup_core_entity_bundle_field_info(EntityTypeInterface $entity_type, ->setCardinality(1) ->setDefaultValue(NULL) ->setSettings([ - 'link_type' => LinkItemInterface::LINK_INTERNAL, + 'link_type' => LinkItemInterface::LINK_EXTERNAL, 'title' => DRUPAL_DISABLED, ]) ->setDisplayConfigurable('form', FALSE) -- GitLab From 929402c05438232c9e0b4e366c2754f6d949c82f Mon Sep 17 00:00:00 2001 From: "micha.jakubowski" <micha.jakubowski@ffwagency.com> Date: Thu, 12 Sep 2024 14:24:28 +0200 Subject: [PATCH 075/149] patch video_embed_field #3469668 "AssertionError: "media" must be defined in MODULE_NAME.field_type_categories.yml" --- composer.json | 3 +- .../drupal/video_embed_field/3469668.patch | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 resources/patch/php/drupal/video_embed_field/3469668.patch diff --git a/composer.json b/composer.json index d3bca6053b..4246709411 100644 --- a/composer.json +++ b/composer.json @@ -447,7 +447,8 @@ "Extend support for embed URLs. Option to force privacy @see https://www.drupal.org/project/video_embed_field/issues/3060201 (originally on https://www.drupal.org/node/2899093)": "resources/patch/php/drupal/video_embed_field/3060201.patch", "WYSIWYG Video URL max length limited to 128 characters @see https://www.drupal.org/project/video_embed_field/issues/2908562": "resources/patch/php/drupal/video_embed_field/2908562.patch", "Add support for Ckeditor 5. @see https://www.drupal.org/project/video_embed_field/issues/3311063": "resources/patch/php/drupal/video_embed_field/3311063_42.patch", - "Deprecation warning: translatable category in field definition @see https://www.drupal.org/project/video_embed_field/issues/3460603": "resources/patch/php/drupal/video_embed_field/3460603.patch" + "Deprecation warning: translatable category in field definition @see https://www.drupal.org/project/video_embed_field/issues/3460603": "resources/patch/php/drupal/video_embed_field/3460603.patch", + "AssertionError: \"media\" must be defined in MODULE_NAME.field_type_categories.yml @see https://www.drupal.org/project/video_embed_field/issues/3469668": "resources/patch/php/drupal/video_embed_field/3469668.patch" }, "drupal/views_autosubmit": { "Stop auto submitting first character entered in an Autocomplete Filter field. @see https://www.drupal.org/project/views_autosubmit/issues/3160600" : "resources/patch/php/drupal/views_autosubmit/3160600.patch" diff --git a/resources/patch/php/drupal/video_embed_field/3469668.patch b/resources/patch/php/drupal/video_embed_field/3469668.patch new file mode 100644 index 0000000000..b48188f0ee --- /dev/null +++ b/resources/patch/php/drupal/video_embed_field/3469668.patch @@ -0,0 +1,37 @@ +From f50e823e8f1bb4d048457d93e05c6423442bd55a Mon Sep 17 00:00:00 2001 +From: Pravin Gaikwad <33942-Rajeshreeputra@users.noreply.drupalcode.org> +Date: Mon, 26 Aug 2024 05:22:03 +0000 +Subject: [PATCH] Add field type categories file + +--- + src/Plugin/Field/FieldType/VideoEmbedField.php | 2 +- + video_embed_field.field_type_categories.yml | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + create mode 100644 video_embed_field.field_type_categories.yml + +diff --git a/src/Plugin/Field/FieldType/VideoEmbedField.php b/src/Plugin/Field/FieldType/VideoEmbedField.php +index 48b1b54..6b8b3de 100644 +--- a/src/Plugin/Field/FieldType/VideoEmbedField.php ++++ b/src/Plugin/Field/FieldType/VideoEmbedField.php +@@ -15,7 +15,7 @@ use Drupal\Core\TypedData\TraversableTypedDataInterface; + * id = "video_embed_field", + * label = @Translation("Video Embed"), + * description = @Translation("Stores a video and then outputs some embed code."), +- * category = @Translation("Media"), ++ * category = "Media", + * default_widget = "video_embed_field_textfield", + * default_formatter = "video_embed_field_video", + * constraints = {"VideoEmbedValidation" = {}} +diff --git a/video_embed_field.field_type_categories.yml b/video_embed_field.field_type_categories.yml +new file mode 100644 +index 0000000..38e27c3 +--- /dev/null ++++ b/video_embed_field.field_type_categories.yml +@@ -0,0 +1,4 @@ ++Media: ++ label: 'Video Embed' ++ description: 'Stores a video and then outputs some embed code.' ++ weight: -50 +\ No newline at end of file +-- +GitLab \ No newline at end of file -- GitLab From 4e3db66d39fcbc85128533eac263be9f4f3e9797 Mon Sep 17 00:00:00 2001 From: "micha.jakubowski" <micha.jakubowski@ffwagency.com> Date: Thu, 12 Sep 2024 14:49:17 +0200 Subject: [PATCH 076/149] patch video_embed_field #3469668 "AssertionError: "media" must be defined in MODULE_NAME.field_type_categories.yml" --- composer.json | 30 ++++++++++++++----- .../drupal/video_embed_field/3469668.patch | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 4246709411..8fb6753909 100644 --- a/composer.json +++ b/composer.json @@ -240,13 +240,27 @@ }, "extra": { "installer-paths": { - "drush/Commands/{$name}": ["type:drupal-drush"], - "drush/contrib/{$name}": ["type:drupal-drush"], - "web/core": ["type:drupal-core"], - "web/libraries/{$name}": ["type:drupal-library"], - "web/modules/contrib/{$name}": ["type:drupal-module"], - "web/profiles/contrib/{$name}": ["type:drupal-profile"], - "web/themes/contrib/{$name}": ["type:drupal-theme"] + "drush/Commands/{$name}": [ + "type:drupal-drush" + ], + "drush/contrib/{$name}": [ + "type:drupal-drush" + ], + "web/core": [ + "type:drupal-core" + ], + "web/libraries/{$name}": [ + "type:drupal-library" + ], + "web/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "web/profiles/contrib/{$name}": [ + "type:drupal-profile" + ], + "web/themes/contrib/{$name}": [ + "type:drupal-theme" + ] }, "drupal-scaffold": { "locations": { @@ -451,7 +465,7 @@ "AssertionError: \"media\" must be defined in MODULE_NAME.field_type_categories.yml @see https://www.drupal.org/project/video_embed_field/issues/3469668": "resources/patch/php/drupal/video_embed_field/3469668.patch" }, "drupal/views_autosubmit": { - "Stop auto submitting first character entered in an Autocomplete Filter field. @see https://www.drupal.org/project/views_autosubmit/issues/3160600" : "resources/patch/php/drupal/views_autosubmit/3160600.patch" + "Stop auto submitting first character entered in an Autocomplete Filter field. @see https://www.drupal.org/project/views_autosubmit/issues/3160600": "resources/patch/php/drupal/views_autosubmit/3160600.patch" }, "drupal/webform": { "Radios or Checkboxes inside Composite not saved @see https://www.drupal.org/project/webform/issues/3216923": "resources/patch/php/drupal/webform/368.diff", diff --git a/resources/patch/php/drupal/video_embed_field/3469668.patch b/resources/patch/php/drupal/video_embed_field/3469668.patch index b48188f0ee..20021a2bfe 100644 --- a/resources/patch/php/drupal/video_embed_field/3469668.patch +++ b/resources/patch/php/drupal/video_embed_field/3469668.patch @@ -34,4 +34,4 @@ index 0000000..38e27c3 + weight: -50 \ No newline at end of file -- -GitLab \ No newline at end of file +GitLabz \ No newline at end of file -- GitLab From f3f9351498bc1d79bd0b13c9ed532bb8a7d019a5 Mon Sep 17 00:00:00 2001 From: "micha.jakubowski" <micha.jakubowski@ffwagency.com> Date: Thu, 12 Sep 2024 15:03:53 +0200 Subject: [PATCH 077/149] patch video_embed_field #3469668 update --- composer.json | 1 - composer.lock | 2 +- .../php/drupal/video_embed_field/3460603.patch | 13 ------------- 3 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 resources/patch/php/drupal/video_embed_field/3460603.patch diff --git a/composer.json b/composer.json index 8fb6753909..6ff57d2717 100644 --- a/composer.json +++ b/composer.json @@ -461,7 +461,6 @@ "Extend support for embed URLs. Option to force privacy @see https://www.drupal.org/project/video_embed_field/issues/3060201 (originally on https://www.drupal.org/node/2899093)": "resources/patch/php/drupal/video_embed_field/3060201.patch", "WYSIWYG Video URL max length limited to 128 characters @see https://www.drupal.org/project/video_embed_field/issues/2908562": "resources/patch/php/drupal/video_embed_field/2908562.patch", "Add support for Ckeditor 5. @see https://www.drupal.org/project/video_embed_field/issues/3311063": "resources/patch/php/drupal/video_embed_field/3311063_42.patch", - "Deprecation warning: translatable category in field definition @see https://www.drupal.org/project/video_embed_field/issues/3460603": "resources/patch/php/drupal/video_embed_field/3460603.patch", "AssertionError: \"media\" must be defined in MODULE_NAME.field_type_categories.yml @see https://www.drupal.org/project/video_embed_field/issues/3469668": "resources/patch/php/drupal/video_embed_field/3469668.patch" }, "drupal/views_autosubmit": { diff --git a/composer.lock b/composer.lock index 3ba336768d..6b17f70f6b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7e56945cd869c86d68dd6f18a9cdf822", + "content-hash": "ad7a14f341be9f05de92f5b324b99667", "packages": [ { "name": "asm89/stack-cors", diff --git a/resources/patch/php/drupal/video_embed_field/3460603.patch b/resources/patch/php/drupal/video_embed_field/3460603.patch deleted file mode 100644 index 2a25801b72..0000000000 --- a/resources/patch/php/drupal/video_embed_field/3460603.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/Plugin/Field/FieldType/VideoEmbedField.php b/src/Plugin/Field/FieldType/VideoEmbedField.php -index 48b1b541731b25dc41667fa30883e2c0ac0ac7d5..6b8b3deb362e1781cddda73a7d812d411685ee76 100644 ---- a/src/Plugin/Field/FieldType/VideoEmbedField.php -+++ b/src/Plugin/Field/FieldType/VideoEmbedField.php -@@ -15,7 +15,7 @@ use Drupal\Core\TypedData\TraversableTypedDataInterface; - * id = "video_embed_field", - * label = @Translation("Video Embed"), - * description = @Translation("Stores a video and then outputs some embed code."), -- * category = @Translation("Media"), -+ * category = "Media", - * default_widget = "video_embed_field_textfield", - * default_formatter = "video_embed_field_video", - * constraints = {"VideoEmbedValidation" = {}} -- GitLab From ec5410421e847ccde2977dd11a098857110606f8 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 08:02:13 +0200 Subject: [PATCH 078/149] ISAICP-8816: Update title and description. --- tests/features/joinup_group/announcements.feature | 2 +- .../announcements.professional_domain.feature | 10 +++++----- .../custom/joinup_group/src/Form/AnnouncementForm.php | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/features/joinup_group/announcements.feature b/tests/features/joinup_group/announcements.feature index 4702c5ebde..7675da786e 100644 --- a/tests/features/joinup_group/announcements.feature +++ b/tests/features/joinup_group/announcements.feature @@ -68,7 +68,7 @@ Feature: Messaging group announcements When I go to the members page of "Fail pension" And I click "Add announcement" Then the following fields should be present "Subject,Body" - But the following fields should not be present "Professional domain" + But the following fields should not be present "Professional domain filter" And I should see the following lines of text: | Select dynamic placeholders for your announcement | | Copy and paste, in the message body, one or more placeholder(s) (e.g. @recipient_name) and the corresponding shortcut link(s) will be displayed in the announcement email. Available placeholders: | diff --git a/tests/features/joinup_group/announcements.professional_domain.feature b/tests/features/joinup_group/announcements.professional_domain.feature index f6cf92d1d9..f6b6cfcfc3 100644 --- a/tests/features/joinup_group/announcements.professional_domain.feature +++ b/tests/features/joinup_group/announcements.professional_domain.feature @@ -48,20 +48,20 @@ Feature: Filter announcements by professional domain Given I am logged in as a moderator When I go to the "Demography announcement" announcement of "Pension funds" <group> - Then the following fields should be present "Professional domain" - And the "Professional domain" field should contain the "E-health Dpt., HR Dpt., Law and Justice, Social and Political" option groups - And the "Professional domain" select should contain the following options: + Then the following fields should be present "Professional domain filter" + And the "Professional domain filter" field should contain the "E-health Dpt., HR Dpt., Law and Justice, Social and Political" option groups + And the "Professional domain filter" select should contain the following options: | -E-health (3) | | -HR (1) | | -E-justice (2) | | -Demography (6) | - When I select "-Demography (6)" from "Professional domain" + When I select "-Demography (6)" from "Professional domain filter" And I press "Approve" Then 5 e-mails should have been sent When I mark all emails as read And I go to the "E-health and E-justice announcement" announcement of "Pension funds" <group> - And I select "-E-justice (2)" from "Professional domain" + And I select "-E-justice (2)" from "Professional domain filter" And I press "Approve" Then 2 e-mails should have been sent diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index 943d6a05ff..63c6221133 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -139,8 +139,8 @@ public function buildForm(array $form, FormStateInterface $form_state): array { if ($domain_options) { $form['professional_domain'] = [ '#type' => 'select', - '#title' => $this->t('Professional domain'), - '#description' => $this->t('By picking any value, you will limit the recipients of the announcement.'), + '#title' => $this->t('Professional domain filter'), + '#description' => $this->t('Narrow your announcement\'s audience by targeting only members based on their professional domain.'), '#options' => $this->getOptions(), '#default_value' => $this->announcement->getProfessionalDomainIds(), '#multiple' => TRUE, -- GitLab From 3305ae1609f9cd8aa8d60e1eac247c630c1b37f1 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 08:04:35 +0200 Subject: [PATCH 079/149] ISAICP-8816: Update title and description. --- web/modules/custom/joinup_group/src/Form/AnnouncementForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index 63c6221133..3e41134289 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -140,7 +140,7 @@ public function buildForm(array $form, FormStateInterface $form_state): array { $form['professional_domain'] = [ '#type' => 'select', '#title' => $this->t('Professional domain filter'), - '#description' => $this->t('Narrow your announcement\'s audience by targeting only members based on their professional domain.'), + '#description' => $this->t("Narrow your announcement's audience by targeting only members based on their professional domain."), '#options' => $this->getOptions(), '#default_value' => $this->announcement->getProfessionalDomainIds(), '#multiple' => TRUE, -- GitLab From f88bc03e94785a42ae602f2ae58771ed010535c2 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 12:39:16 +0200 Subject: [PATCH 080/149] ISAICP-9079: Remove: oss__documentation, oss__features and oss__long_description. --- ...view_display.node.oss_solution.default.yml | 10 +++------ ...y_view_display.node.oss_solution.modal.yml | 4 ---- ...display.node.oss_solution.search_index.yml | 3 --- ...splay.node.oss_solution.view_mode_tile.yml | 4 ---- ...oss_solution.view_mode_tile_horizontal.yml | 4 ---- .../sync/search_api.index.oss_catalogue.yml | 4 ++-- .../eu_oss_catalogue/eu_oss_catalogue.module | 21 ++----------------- .../Functional/DevelopersItaliaFetchTest.php | 2 +- 8 files changed, 8 insertions(+), 44 deletions(-) diff --git a/config/sync/core.entity_view_display.node.oss_solution.default.yml b/config/sync/core.entity_view_display.node.oss_solution.default.yml index 45fbbce587..5c1f3aa708 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.default.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.default.yml @@ -114,7 +114,7 @@ third_party_settings: uuid: f6501de4-478f-49fe-adbb-2e541ba9d0c3 region: aside configuration: - id: 'field_block:node:oss_solution:oss__documentation' + id: 'field_block:node:oss_solution:oss_documentation' label: Documentation label_display: '0' provider: layout_builder @@ -491,7 +491,7 @@ third_party_settings: uuid: 7e17db81-4af4-4c6b-b6df-2b052f018e25 region: first configuration: - id: 'field_block:node:oss_solution:oss__long_description' + id: 'field_block:node:oss_solution:oss_long_description' label: Description label_display: visible provider: layout_builder @@ -519,7 +519,7 @@ third_party_settings: uuid: eb1487bc-7a20-40e5-9c0f-d4b997f0e11b region: second configuration: - id: 'field_block:node:oss_solution:oss__features' + id: 'field_block:node:oss_solution:oss_features' label: Features label_display: visible provider: layout_builder @@ -867,11 +867,7 @@ hidden: langcode: true links: true oss__description: true - oss__documentation: true - oss__features: true - oss__long_description: true oss__screenshots: true - oss__short_description: true oss_archived: true oss_available_languages: true oss_categories: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.modal.yml b/config/sync/core.entity_view_display.node.oss_solution.modal.yml index cfc6381a1b..09dd8200e1 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.modal.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.modal.yml @@ -94,11 +94,7 @@ hidden: langcode: true links: true oss__description: true - oss__documentation: true - oss__features: true - oss__long_description: true oss__screenshots: true - oss__short_description: true oss_archived: true oss_categories: true oss_default_branch: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.search_index.yml b/config/sync/core.entity_view_display.node.oss_solution.search_index.yml index 3169d3b066..e6ff7f7351 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.search_index.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.search_index.yml @@ -198,9 +198,6 @@ hidden: langcode: true links: true oss__description: true - oss__documentation: true - oss__features: true - oss__long_description: true oss__screenshots: true oss_archived: true oss_available_languages: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml index f8eb9228ce..e8cde331a9 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml @@ -124,11 +124,7 @@ content: hidden: langcode: true links: true - oss__documentation: true - oss__features: true - oss__long_description: true oss__screenshots: true - oss__short_description: true oss_archived: true oss_available_languages: true oss_categories: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml index 0f9027844a..aed8277f51 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml @@ -126,11 +126,7 @@ content: hidden: langcode: true links: true - oss__documentation: true - oss__features: true - oss__long_description: true oss__screenshots: true - oss__short_description: true oss_archived: true oss_available_languages: true oss_categories: true diff --git a/config/sync/search_api.index.oss_catalogue.yml b/config/sync/search_api.index.oss_catalogue.yml index 57467a5616..1c75c8046c 100644 --- a/config/sync/search_api.index.oss_catalogue.yml +++ b/config/sync/search_api.index.oss_catalogue.yml @@ -91,10 +91,10 @@ field_settings: indexed_locked: true type_locked: true hidden: true - oss__features: + oss_features: label: Features datasource_id: 'entity:node' - property_path: oss__features + property_path: oss_features type: string dependencies: module: diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index cf81480be1..684ea04bb8 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -87,34 +87,17 @@ function eu_oss_catalogue_entity_bundle_field_info_alter(array &$fields, EntityT return; } - $computedFieldCandidates = array_filter( - $fields, - function (FieldDefinitionInterface $definition) { - // Include every translatable field which is not computed and can be - // configured on entity view display. - return $definition->isTranslatable() - && !$definition->isComputed() - && $definition->isDisplayConfigurable('view') - // Short description already has a relevant field with fallback. - && $definition->getName() !== 'oss_short_description'; - } - ); - // If there are field candidates, also add the richest language code computed // field. - if (!empty($computedFieldCandidates)) { - $fields[RelevantLanguageCode::FIELD_NAME] = BaseFieldDefinition::create('language') + $fields[RelevantLanguageCode::FIELD_NAME] = BaseFieldDefinition::create('language') ->setName(RelevantLanguageCode::FIELD_NAME) ->setTargetEntityTypeId($entityType->id()) ->setTargetBundle($bundle) ->setLabel(t('Relevant language code')) ->setComputed(TRUE) ->setClass(RelevantLanguageCode::class); - } - // Create a computed field for every translatable fields which than will - // display the field value fetched from the richest language code. - foreach ($computedFieldCandidates as $originalFieldName => $fieldDefinition) { + foreach (['oss_screenshots' => $fields['oss_screenshots']] as $originalFieldName => $fieldDefinition) { \assert($fieldDefinition instanceof FieldDefinitionInterface); $computedName = preg_replace('#^oss_(.*)$#', 'oss__$1', $originalFieldName); diff --git a/web/modules/custom/eu_oss_catalogue/tests/src/Functional/DevelopersItaliaFetchTest.php b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/DevelopersItaliaFetchTest.php index 46d1f0c62e..282eb47ec0 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/src/Functional/DevelopersItaliaFetchTest.php +++ b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/DevelopersItaliaFetchTest.php @@ -187,7 +187,7 @@ public function testMarkDownResolver(): void { $this->assertStringContainsString('[EN] Solution 1: <strong>Short description</strong>', $rendered); // Assert that markdown is converted for long description. - $field_items = $solution->get('oss__long_description'); + $field_items = $solution->get('oss_long_description'); $render_array = $entity_view_builder->viewField($field_items); $rendered = (string) $renderer->renderInIsolation($render_array); $this->assertStringContainsString('<strong>Some bold text</strong>', $rendered); -- GitLab From da6e2636ea101ec3534983096fc091e9f58fe646 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 12:40:22 +0200 Subject: [PATCH 081/149] ISAICP-9079: Fix coding issue. --- .../custom/eu_oss_catalogue/eu_oss_catalogue.module | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index 684ea04bb8..c6bf7c33c0 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -90,12 +90,12 @@ function eu_oss_catalogue_entity_bundle_field_info_alter(array &$fields, EntityT // If there are field candidates, also add the richest language code computed // field. $fields[RelevantLanguageCode::FIELD_NAME] = BaseFieldDefinition::create('language') - ->setName(RelevantLanguageCode::FIELD_NAME) - ->setTargetEntityTypeId($entityType->id()) - ->setTargetBundle($bundle) - ->setLabel(t('Relevant language code')) - ->setComputed(TRUE) - ->setClass(RelevantLanguageCode::class); + ->setName(RelevantLanguageCode::FIELD_NAME) + ->setTargetEntityTypeId($entityType->id()) + ->setTargetBundle($bundle) + ->setLabel(t('Relevant language code')) + ->setComputed(TRUE) + ->setClass(RelevantLanguageCode::class); foreach (['oss_screenshots' => $fields['oss_screenshots']] as $originalFieldName => $fieldDefinition) { \assert($fieldDefinition instanceof FieldDefinitionInterface); -- GitLab From 6a278125e107ade6b8d4417aef5b4347590bc89b Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 13:45:21 +0200 Subject: [PATCH 082/149] ISAICP-9079: reexport search index. --- config/sync/search_api.index.oss_catalogue.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/sync/search_api.index.oss_catalogue.yml b/config/sync/search_api.index.oss_catalogue.yml index 1c75c8046c..cccea31bc9 100644 --- a/config/sync/search_api.index.oss_catalogue.yml +++ b/config/sync/search_api.index.oss_catalogue.yml @@ -6,6 +6,7 @@ dependencies: - field.storage.node.oss_archived - field.storage.node.oss_categories - field.storage.node.oss_development_status + - field.storage.node.oss_features - field.storage.node.oss_git_description - field.storage.node.oss_release_date - field.storage.node.oss_scope @@ -14,7 +15,6 @@ dependencies: - field.storage.node.oss_vitality_index - search_api.server.joinup module: - - field - joinup_flag - joinup_oss_catalogue - joinup_search @@ -91,14 +91,6 @@ field_settings: indexed_locked: true type_locked: true hidden: true - oss_features: - label: Features - datasource_id: 'entity:node' - property_path: oss_features - type: string - dependencies: - module: - - field oss_archived: label: Archived datasource_id: 'entity:node' @@ -125,6 +117,14 @@ field_settings: dependencies: config: - field.storage.node.oss_development_status + oss_features: + label: Features + datasource_id: 'entity:node' + property_path: oss_features + type: string + dependencies: + config: + - field.storage.node.oss_features oss_git_description: label: 'GIT Description' datasource_id: 'entity:node' -- GitLab From d06a185f79dc97fa11436c7d8dd121e5a2c194ff Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 14:15:54 +0200 Subject: [PATCH 083/149] ISAICP-9079: Revert oss__documentation. --- .../core.entity_view_display.node.oss_solution.default.yml | 4 ++-- .../core.entity_view_display.node.oss_solution.modal.yml | 2 +- ...e.entity_view_display.node.oss_solution.search_index.yml | 2 +- ...entity_view_display.node.oss_solution.view_mode_tile.yml | 2 +- ..._display.node.oss_solution.view_mode_tile_horizontal.yml | 2 +- web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module | 6 +++++- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/config/sync/core.entity_view_display.node.oss_solution.default.yml b/config/sync/core.entity_view_display.node.oss_solution.default.yml index 5c1f3aa708..c28d4c062e 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.default.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.default.yml @@ -46,7 +46,6 @@ dependencies: - joinup_layout - layout_builder - layout_discovery - - user third_party_settings: layout_builder: enabled: true @@ -114,7 +113,7 @@ third_party_settings: uuid: f6501de4-478f-49fe-adbb-2e541ba9d0c3 region: aside configuration: - id: 'field_block:node:oss_solution:oss_documentation' + id: 'field_block:node:oss_solution:oss__documentation' label: Documentation label_display: '0' provider: layout_builder @@ -867,6 +866,7 @@ hidden: langcode: true links: true oss__description: true + oss__documentation: true oss__screenshots: true oss_archived: true oss_available_languages: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.modal.yml b/config/sync/core.entity_view_display.node.oss_solution.modal.yml index 09dd8200e1..1eea9e3e4f 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.modal.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.modal.yml @@ -48,7 +48,6 @@ dependencies: - joinup_oss_catalogue - layout_builder - template_suggestion - - user third_party_settings: layout_builder: enabled: false @@ -94,6 +93,7 @@ hidden: langcode: true links: true oss__description: true + oss__documentation: true oss__screenshots: true oss_archived: true oss_categories: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.search_index.yml b/config/sync/core.entity_view_display.node.oss_solution.search_index.yml index e6ff7f7351..e1dc2a5ba4 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.search_index.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.search_index.yml @@ -47,7 +47,6 @@ dependencies: - field_formatter_range - layout_builder - template_suggestion - - user third_party_settings: layout_builder: enabled: false @@ -198,6 +197,7 @@ hidden: langcode: true links: true oss__description: true + oss__documentation: true oss__screenshots: true oss_archived: true oss_available_languages: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml index e8cde331a9..ab5ea17867 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile.yml @@ -48,7 +48,6 @@ dependencies: - joinup_html_stripper - layout_builder - template_suggestion - - user third_party_settings: layout_builder: enabled: false @@ -124,6 +123,7 @@ content: hidden: langcode: true links: true + oss__documentation: true oss__screenshots: true oss_archived: true oss_available_languages: true diff --git a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml index aed8277f51..102931d046 100644 --- a/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml +++ b/config/sync/core.entity_view_display.node.oss_solution.view_mode_tile_horizontal.yml @@ -48,7 +48,6 @@ dependencies: - joinup_html_stripper - layout_builder - template_suggestion - - user third_party_settings: layout_builder: enabled: false @@ -126,6 +125,7 @@ content: hidden: langcode: true links: true + oss__documentation: true oss__screenshots: true oss_archived: true oss_available_languages: true diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index c6bf7c33c0..163c2f6f37 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -97,7 +97,11 @@ function eu_oss_catalogue_entity_bundle_field_info_alter(array &$fields, EntityT ->setComputed(TRUE) ->setClass(RelevantLanguageCode::class); - foreach (['oss_screenshots' => $fields['oss_screenshots']] as $originalFieldName => $fieldDefinition) { + $computedFieldCandidates = [ + 'oss_screenshots' => $fields['oss_screenshots'], + 'oss_documentation' => $fields['oss_documentation'], + ]; + foreach ($computedFieldCandidates as $originalFieldName => $fieldDefinition) { \assert($fieldDefinition instanceof FieldDefinitionInterface); $computedName = preg_replace('#^oss_(.*)$#', 'oss__$1', $originalFieldName); -- GitLab From 1b6aa5b0ec06df10d4cbd4cd6bb3a0fb7abc219a Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 14:26:42 +0200 Subject: [PATCH 084/149] ISAICP-9079: Rename templates afeter switching back to default fields. --- ...=> field--node--oss-features--oss-solution--default.html.twig} | 0 ...--node--oss-long-description--oss-solution--default.html.twig} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename web/themes/ventuno/templates/field/{field--node--oss--features--oss-solution--default.html.twig => field--node--oss-features--oss-solution--default.html.twig} (100%) rename web/themes/ventuno/templates/field/{field--node--oss--long-description--oss-solution--default.html.twig => field--node--oss-long-description--oss-solution--default.html.twig} (100%) diff --git a/web/themes/ventuno/templates/field/field--node--oss--features--oss-solution--default.html.twig b/web/themes/ventuno/templates/field/field--node--oss-features--oss-solution--default.html.twig similarity index 100% rename from web/themes/ventuno/templates/field/field--node--oss--features--oss-solution--default.html.twig rename to web/themes/ventuno/templates/field/field--node--oss-features--oss-solution--default.html.twig diff --git a/web/themes/ventuno/templates/field/field--node--oss--long-description--oss-solution--default.html.twig b/web/themes/ventuno/templates/field/field--node--oss-long-description--oss-solution--default.html.twig similarity index 100% rename from web/themes/ventuno/templates/field/field--node--oss--long-description--oss-solution--default.html.twig rename to web/themes/ventuno/templates/field/field--node--oss-long-description--oss-solution--default.html.twig -- GitLab From 67c4907f96f024fc24491db7cd2613b67faf5418 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 14:28:42 +0200 Subject: [PATCH 085/149] ISAICP-9079: Update class name and rebuild. --- web/themes/ventuno/assets/css/oss-solution-full.min.css | 2 +- web/themes/ventuno/src/scss/pages/oss-solution-full.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/themes/ventuno/assets/css/oss-solution-full.min.css b/web/themes/ventuno/assets/css/oss-solution-full.min.css index 7265f69651..d24dabf6ef 100644 --- a/web/themes/ventuno/assets/css/oss-solution-full.min.css +++ b/web/themes/ventuno/assets/css/oss-solution-full.min.css @@ -1,2 +1,2 @@ -.eu-oss-catalogue .btn-secondary{background-color:#e8f3f0;color:#19764f}.eu-oss-catalogue .btn-secondary:hover{background-color:#e8f3f0}.eu-oss-catalogue .bg-brand{background-color:#19764f!important}.eu-oss-catalogue .bg-secondary{background-color:#e8f3f0!important}.eu-oss-catalogue .btn-link,.eu-oss-catalogue .button--link{color:#19764f!important}.eu-oss-catalogue .btn-brand,.eu-oss-catalogue .btn-primary{background-color:#249866!important;border:1px solid #1f8358}.eu-oss-catalogue .btn-outline-brand{border:1px solid #249866;color:#249866}.eu-oss-catalogue .btn-outline-brand:hover{background-color:#249866;color:#fff}.eu-oss-catalogue .text-bg-primary{background-color:#e8f3f0!important}.eu-oss-catalogue .text-bg-primary.badge{color:#249866!important}.eu-oss-catalogue .text-secondary{color:#19764f!important}.eu-oss-catalogue .oss__instructions .layout__region--first:before{background-color:#e8f3f0}.eu-oss-catalogue .oss__instructions .layout__region--first .paragraph h3:before{background-color:#19764f}.eu-oss-catalogue .oss__social .paragraph--call-to-action a{background-color:transparent!important}.eu-oss-catalogue .oss__social .paragraph--call-to-action a:before{background-color:#249866}.eu-oss-catalogue .joinup-search-filters .facets-checkbox{-webkit-appearance:none;-moz-appearance:none;appearance:none}.eu-oss-catalogue .joinup-search-filters .facets-checkbox:checked[type=checkbox]{background-color:#249866;border-color:#1f8358}.eu-oss-catalogue .joinup-search-filters .facets-soft-limit-link{color:#249866}.eu-oss-catalogue .joinup-search-filters .facets-soft-limit-link:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23249866' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");display:inline-block}.eu-oss-catalogue .view-search-oss-catalogue .js-form-item .btn-search{background-color:#249866}.eu-oss-catalogue .pagination .page-item .page-link{color:#249866}.eu-oss-catalogue .pagination .page-item .page-link:hover{background-color:#e8f3f0}.eu-oss-catalogue .pagination .page-item .page-link .bi{color:#249866}.eu-oss-catalogue .pagination .page-item.active .page-link{background-color:#e8f3f0;color:#249866}.oss-solution a:link,.oss-solution a:visited{color:#249866}.oss-solution__header{position:relative}.oss-solution__header:before{background:#f8f9fa;content:"";display:block;height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}.oss-solution__header-logo div:not(:empty){width:100px}.oss-solution__header-logo div:not(:empty) img{height:auto;max-width:100%}@media (min-width:992px){.oss-solution__header-logo div:not(:empty){margin-right:1rem}}.oss-solution__header h1{font-weight:700;margin-bottom:0}.oss-solution .l-oss-heading{padding-block:0;position:relative}.oss-solution .l-oss-heading:before{background:#f8f9fa;content:"";display:block;height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}.oss-solution .l-oss-heading__right{position:relative}.oss-solution .l-oss-heading__right:after{background:#e8f3f0;content:"";height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}@media (min-width:768px){.oss-solution .l-oss-heading__right:after{inset-inline-start:0;left:0;margin-inline-start:0}}.oss-solution .l-oss-heading__right .block:not([class*=oss-vitality-index-range]){margin-bottom:2rem}.oss-solution .l-oss-heading__row--branding{flex-direction:column;gap:1rem;justify-content:center}@media (min-width:768px){.oss-solution .l-oss-heading__row--branding{flex-direction:row;flex-wrap:nowrap;gap:2rem;justify-content:flex-start}}.oss-solution .l-oss-heading__indicator .block:not(:last-child){margin-right:2rem}.oss-solution .l-oss-heading__indicator .git-indicator span{font-size:1rem}.oss-solution .l-oss-heading__indicator .git-indicator:after{height:2.2em;width:2.2em}.oss-solution .l-oss-heading__aside{position:relative}.oss-solution .l-oss-heading__aside .modal-dialog{align-items:center;display:flex;min-height:calc(100% - var(--bs-modal-margin)*2)}.oss-solution .l-oss-heading__vitality{align-items:center;display:flex;gap:1rem}.oss-solution .l-oss-heading__vitality div{color:#249866;font-size:1.5rem;margin-bottom:.5rem}@media (min-width:768px){.oss-solution .l-oss-heading__top-left{flex:0 1 100px}.oss-solution .l-oss-heading__top-right{flex:1 3 auto}}.oss-solution .l-oss-heading__third-left .block{margin-right:3rem}.oss-solution__oss-vitality-index{color:#249866;font-size:1.5rem}.oss-solution__oss-vitality-index-range .vitality-index-info-button{position:absolute;right:calc(100% - 11rem);top:0}.oss-solution__oss-software-version{margin-bottom:1rem;margin-right:2rem}.oss-solution__oss-software-version .field__label{margin-bottom:.5rem}.oss-solution__oss-software-version .field__item{background-color:#19764f;border-radius:50rem;color:#fff;display:inline;font-weight:700;padding:.25rem .75rem}.oss-solution__oss-categories{margin-bottom:1rem}.oss-solution__oss-categories .field__label{margin-bottom:.5rem}.oss-solution__oss-categories a{background-color:#e8f3f0;border-radius:50rem;font-weight:700;padding:.25rem .75rem;white-space:nowrap}.oss-solution__oss-categories a:hover{text-decoration:none}.oss-solution__description{color:#858a8c;font-size:1.25rem;margin-block-end:1rem}.oss-solution__oss-source .field__item{font-weight:700}.oss-solution__oss-git-url{margin-block-end:.5rem}.oss-solution__oss-git-url a{font-weight:700}.oss-solution__oss-git-url a:before{background-color:#249866;content:"";display:inline-block;height:1.2em;margin-inline-end:.5rem;-webkit-mask-image:url(../icons/folder2-open.svg);mask-image:url(../icons/folder2-open.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;width:1.2em}.oss-solution__oss-landing-url{margin-block-end:.5rem}.oss-solution__oss-landing-url a{font-weight:700}.oss-solution__oss-landing-url a:before{background-color:#249866;content:"";display:inline-block;height:1.5em;margin-inline-end:.3rem;-webkit-mask-image:url(../icons/link-45deg.svg);mask-image:url(../icons/link-45deg.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;width:1.5em}.oss-solution__oss__documentation a{font-weight:700}.oss-solution__oss__documentation a:before{background-color:#249866;content:"";display:inline-block;height:1.3em;margin-inline-end:.4rem;-webkit-mask-image:url(../icons/file-earmark-text.svg);mask-image:url(../icons/file-earmark-text.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;width:1.3em}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description{padding-block:3rem;position:relative}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description:before{background:#f8f9fa;content:"";display:block;height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description .oss-solution__long-description--long{display:-webkit-box!important;font-size:1.25rem;min-height:60px;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description .oss-solution__long-description--long.collapsing,.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description .oss-solution__long-description--long.show{-webkit-line-clamp:unset}.oss-solution__illustration{aspect-ratio:4/3;background:url(../images/oss-illustration.svg) no-repeat top;background-size:contain;height:auto;width:100%}@media (min-width:992px){.oss-solution__illustration{background-size:auto}}.oss-solution__oss__features{list-style:none;margin-left:0}.oss-solution__oss__features li{color:#858a8c;font-size:1.25rem;margin-bottom:.5rem}.oss-solution__oss__features li:before{background-color:#249866;content:"";display:inline-block;height:1em;height:1.8em;margin-inline-end:.8rem;-webkit-mask-image:url(../icons/check-lg.svg);mask-image:url(../icons/check-lg.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;vertical-align:-.5em;width:1em;width:1.8em}.oss-solution__oss-scope{display:flex;flex-wrap:wrap;gap:.5rem}.oss-solution__oss-scope a{background-color:#e8f3f0;border-radius:50rem;color:#249866;font-weight:700;padding:.25rem .75rem;white-space:nowrap}.oss-solution__oss-scope a:hover{text-decoration:none}.oss-solution .l-ventuno--joinup_layout_four_column_grid--section-label-detailed-information__region-content{background-color:#f8f9fa;padding:1rem}.oss-solution .l-ventuno--joinup_layout_four_column_grid--section-label-detailed-information__region-content .block-layout-builder .field__items{display:flex;flex-wrap:wrap;gap:.5rem}.oss-solution .oss-solution__oss-screenshots{background-color:#f8f9fa;padding:1rem}.oss-solution .oss-solution__oss-screenshots .field__item a{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.oss-solution .layout .block-layout-builder+.block-layout-builder{margin-block-start:2rem}.oss-solution .btn-secondary{background-color:#e8f3f0;color:#19764f}.oss-solution .btn-secondary:hover{background-color:#e8f3f0} +.eu-oss-catalogue .btn-secondary{background-color:#e8f3f0;color:#19764f}.eu-oss-catalogue .btn-secondary:hover{background-color:#e8f3f0}.eu-oss-catalogue .bg-brand{background-color:#19764f!important}.eu-oss-catalogue .bg-secondary{background-color:#e8f3f0!important}.eu-oss-catalogue .btn-link,.eu-oss-catalogue .button--link{color:#19764f!important}.eu-oss-catalogue .btn-brand,.eu-oss-catalogue .btn-primary{background-color:#249866!important;border:1px solid #1f8358}.eu-oss-catalogue .btn-outline-brand{border:1px solid #249866;color:#249866}.eu-oss-catalogue .btn-outline-brand:hover{background-color:#249866;color:#fff}.eu-oss-catalogue .text-bg-primary{background-color:#e8f3f0!important}.eu-oss-catalogue .text-bg-primary.badge{color:#249866!important}.eu-oss-catalogue .text-secondary{color:#19764f!important}.eu-oss-catalogue .oss__instructions .layout__region--first:before{background-color:#e8f3f0}.eu-oss-catalogue .oss__instructions .layout__region--first .paragraph h3:before{background-color:#19764f}.eu-oss-catalogue .oss__social .paragraph--call-to-action a{background-color:transparent!important}.eu-oss-catalogue .oss__social .paragraph--call-to-action a:before{background-color:#249866}.eu-oss-catalogue .joinup-search-filters .facets-checkbox{-webkit-appearance:none;-moz-appearance:none;appearance:none}.eu-oss-catalogue .joinup-search-filters .facets-checkbox:checked[type=checkbox]{background-color:#249866;border-color:#1f8358}.eu-oss-catalogue .joinup-search-filters .facets-soft-limit-link{color:#249866}.eu-oss-catalogue .joinup-search-filters .facets-soft-limit-link:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23249866' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");display:inline-block}.eu-oss-catalogue .view-search-oss-catalogue .js-form-item .btn-search{background-color:#249866}.eu-oss-catalogue .pagination .page-item .page-link{color:#249866}.eu-oss-catalogue .pagination .page-item .page-link:hover{background-color:#e8f3f0}.eu-oss-catalogue .pagination .page-item .page-link .bi{color:#249866}.eu-oss-catalogue .pagination .page-item.active .page-link{background-color:#e8f3f0;color:#249866}.oss-solution a:link,.oss-solution a:visited{color:#249866}.oss-solution__header{position:relative}.oss-solution__header:before{background:#f8f9fa;content:"";display:block;height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}.oss-solution__header-logo div:not(:empty){width:100px}.oss-solution__header-logo div:not(:empty) img{height:auto;max-width:100%}@media (min-width:992px){.oss-solution__header-logo div:not(:empty){margin-right:1rem}}.oss-solution__header h1{font-weight:700;margin-bottom:0}.oss-solution .l-oss-heading{padding-block:0;position:relative}.oss-solution .l-oss-heading:before{background:#f8f9fa;content:"";display:block;height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}.oss-solution .l-oss-heading__right{position:relative}.oss-solution .l-oss-heading__right:after{background:#e8f3f0;content:"";height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}@media (min-width:768px){.oss-solution .l-oss-heading__right:after{inset-inline-start:0;left:0;margin-inline-start:0}}.oss-solution .l-oss-heading__right .block:not([class*=oss-vitality-index-range]){margin-bottom:2rem}.oss-solution .l-oss-heading__row--branding{flex-direction:column;gap:1rem;justify-content:center}@media (min-width:768px){.oss-solution .l-oss-heading__row--branding{flex-direction:row;flex-wrap:nowrap;gap:2rem;justify-content:flex-start}}.oss-solution .l-oss-heading__indicator .block:not(:last-child){margin-right:2rem}.oss-solution .l-oss-heading__indicator .git-indicator span{font-size:1rem}.oss-solution .l-oss-heading__indicator .git-indicator:after{height:2.2em;width:2.2em}.oss-solution .l-oss-heading__aside{position:relative}.oss-solution .l-oss-heading__aside .modal-dialog{align-items:center;display:flex;min-height:calc(100% - var(--bs-modal-margin)*2)}.oss-solution .l-oss-heading__vitality{align-items:center;display:flex;gap:1rem}.oss-solution .l-oss-heading__vitality div{color:#249866;font-size:1.5rem;margin-bottom:.5rem}@media (min-width:768px){.oss-solution .l-oss-heading__top-left{flex:0 1 100px}.oss-solution .l-oss-heading__top-right{flex:1 3 auto}}.oss-solution .l-oss-heading__third-left .block{margin-right:3rem}.oss-solution__oss-vitality-index{color:#249866;font-size:1.5rem}.oss-solution__oss-vitality-index-range .vitality-index-info-button{position:absolute;right:calc(100% - 11rem);top:0}.oss-solution__oss-software-version{margin-bottom:1rem;margin-right:2rem}.oss-solution__oss-software-version .field__label{margin-bottom:.5rem}.oss-solution__oss-software-version .field__item{background-color:#19764f;border-radius:50rem;color:#fff;display:inline;font-weight:700;padding:.25rem .75rem}.oss-solution__oss-categories{margin-bottom:1rem}.oss-solution__oss-categories .field__label{margin-bottom:.5rem}.oss-solution__oss-categories a{background-color:#e8f3f0;border-radius:50rem;font-weight:700;padding:.25rem .75rem;white-space:nowrap}.oss-solution__oss-categories a:hover{text-decoration:none}.oss-solution__description{color:#858a8c;font-size:1.25rem;margin-block-end:1rem}.oss-solution__oss-source .field__item{font-weight:700}.oss-solution__oss-git-url{margin-block-end:.5rem}.oss-solution__oss-git-url a{font-weight:700}.oss-solution__oss-git-url a:before{background-color:#249866;content:"";display:inline-block;height:1.2em;margin-inline-end:.5rem;-webkit-mask-image:url(../icons/folder2-open.svg);mask-image:url(../icons/folder2-open.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;width:1.2em}.oss-solution__oss-landing-url{margin-block-end:.5rem}.oss-solution__oss-landing-url a{font-weight:700}.oss-solution__oss-landing-url a:before{background-color:#249866;content:"";display:inline-block;height:1.5em;margin-inline-end:.3rem;-webkit-mask-image:url(../icons/link-45deg.svg);mask-image:url(../icons/link-45deg.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;width:1.5em}.oss-solution__oss__documentation a{font-weight:700}.oss-solution__oss__documentation a:before{background-color:#249866;content:"";display:inline-block;height:1.3em;margin-inline-end:.4rem;-webkit-mask-image:url(../icons/file-earmark-text.svg);mask-image:url(../icons/file-earmark-text.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;width:1.3em}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description{padding-block:3rem;position:relative}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description:before{background:#f8f9fa;content:"";display:block;height:100%;inset-inline-start:50%;margin-inline-start:-50vw;position:absolute;top:0;width:100vw;z-index:-1}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description .oss-solution__long-description--long{display:-webkit-box!important;font-size:1.25rem;min-height:60px;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical}.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description .oss-solution__long-description--long.collapsing,.oss-solution .l-ventuno--layout_twocol_section--section-label-long-description .oss-solution__long-description--long.show{-webkit-line-clamp:unset}.oss-solution__illustration{aspect-ratio:4/3;background:url(../images/oss-illustration.svg) no-repeat top;background-size:contain;height:auto;width:100%}@media (min-width:992px){.oss-solution__illustration{background-size:auto}}.oss-solution__oss-features{list-style:none;margin-left:0}.oss-solution__oss-features li{color:#858a8c;font-size:1.25rem;margin-bottom:.5rem}.oss-solution__oss-features li:before{background-color:#249866;content:"";display:inline-block;height:1em;height:1.8em;margin-inline-end:.8rem;-webkit-mask-image:url(../icons/check-lg.svg);mask-image:url(../icons/check-lg.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.125em;vertical-align:-.5em;width:1em;width:1.8em}.oss-solution__oss-scope{display:flex;flex-wrap:wrap;gap:.5rem}.oss-solution__oss-scope a{background-color:#e8f3f0;border-radius:50rem;color:#249866;font-weight:700;padding:.25rem .75rem;white-space:nowrap}.oss-solution__oss-scope a:hover{text-decoration:none}.oss-solution .l-ventuno--joinup_layout_four_column_grid--section-label-detailed-information__region-content{background-color:#f8f9fa;padding:1rem}.oss-solution .l-ventuno--joinup_layout_four_column_grid--section-label-detailed-information__region-content .block-layout-builder .field__items{display:flex;flex-wrap:wrap;gap:.5rem}.oss-solution .oss-solution__oss-screenshots{background-color:#f8f9fa;padding:1rem}.oss-solution .oss-solution__oss-screenshots .field__item a{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.oss-solution .layout .block-layout-builder+.block-layout-builder{margin-block-start:2rem}.oss-solution .btn-secondary{background-color:#e8f3f0;color:#19764f}.oss-solution .btn-secondary:hover{background-color:#e8f3f0} /*# sourceMappingURL=oss-solution-full.min.css.map */ \ No newline at end of file diff --git a/web/themes/ventuno/src/scss/pages/oss-solution-full.scss b/web/themes/ventuno/src/scss/pages/oss-solution-full.scss index 592c812598..eccf5535ea 100644 --- a/web/themes/ventuno/src/scss/pages/oss-solution-full.scss +++ b/web/themes/ventuno/src/scss/pages/oss-solution-full.scss @@ -276,7 +276,7 @@ } } - &__oss__features { + &__oss-features { margin-left: 0; list-style: none; -- GitLab From 9eec1b9dab0873d90908392d9deb5826c80a85f1 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 15:44:51 +0200 Subject: [PATCH 086/149] ISAICP-9079: Disable richest option for oss__description. --- .../eu_oss_catalogue/eu_oss_catalogue.module | 2 + .../src/Plugin/Field/RelevantField.php | 41 +++++++++++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index 163c2f6f37..f014593b93 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -74,6 +74,7 @@ function eu_oss_catalogue_entity_bundle_field_info(EntityTypeInterface $entityTy 'oss_git_description', ] ) + ->setSetting(RelevantField::RICHEST_FIELDS_SETTING_KEY, FALSE) ->setClass(RelevantField::class); } return $fields; @@ -113,6 +114,7 @@ function eu_oss_catalogue_entity_bundle_field_info_alter(array &$fields, EntityT ->setName($computedName) ->setLabel($relevantLabel) ->setSetting(RelevantField::SOURCE_FIELDS_SETTING_KEY, [$originalFieldName]) + ->setSetting(RelevantField::RICHEST_FIELDS_SETTING_KEY, TRUE) ->setComputed(TRUE) ->setDisplayConfigurable('view', TRUE) ->setClass(RelevantField::class); diff --git a/web/modules/custom/eu_oss_catalogue/src/Plugin/Field/RelevantField.php b/web/modules/custom/eu_oss_catalogue/src/Plugin/Field/RelevantField.php index 10734a794c..1cd612ed7e 100644 --- a/web/modules/custom/eu_oss_catalogue/src/Plugin/Field/RelevantField.php +++ b/web/modules/custom/eu_oss_catalogue/src/Plugin/Field/RelevantField.php @@ -28,7 +28,14 @@ class RelevantField extends FieldItemList { * * @const string */ - const SOURCE_FIELDS_SETTING_KEY = 'eu_oss_catalogue_source_fields'; + const string SOURCE_FIELDS_SETTING_KEY = 'eu_oss_catalogue_source_fields'; + + /** + * The configuration key storing the name of the richest option. + * + * @const string + */ + const string RICHEST_FIELDS_SETTING_KEY = 'eu_oss_catalogue_source_richest'; /** * {@inheritdoc} @@ -49,13 +56,16 @@ protected function computeValue(): void { * entity or the field definition is not properly configured. */ protected function getSourceField(): ?FieldItemListInterface { - if ($fieldName = $this->getSourceFieldName()) { - return $this->getEntity() - ->getTranslation($this->getRichestLanguageCode()) - ->get($fieldName); + if (!$fieldName = $this->getSourceFieldName()) { + return NULL; } - return NULL; + $entity = $this->getEntity(); + if ($this->useRichestTranslation()) { + $entity = $entity->getTranslation($this->getRichestLanguageCode()); + } + + return $entity->get($fieldName); } /** @@ -69,8 +79,11 @@ protected function getSourceField(): ?FieldItemListInterface { * If an invalid field name is configured. */ protected function getSourceFieldName(): ?string { - $languageCode = $this->getRichestLanguageCode(); - $ossSolution = $this->getEntity()->getTranslation($languageCode); + $ossSolution = $this->getEntity(); + if ($this->useRichestTranslation()) { + $ossSolution = $ossSolution + ->getTranslation($this->getRichestLanguageCode()); + } \assert($ossSolution instanceof OssSolutionInterface); foreach ((array) $this->definition->getSetting(static::SOURCE_FIELDS_SETTING_KEY) as $fieldName) { if ($ossSolution->get($fieldName)->isEmpty()) { @@ -96,10 +109,20 @@ protected function getRichestLanguageCode(): string { * {@inheritdoc} */ public function postSave($update): bool { - // Force recompute after save. + // Force re-compute after save. $this->valueComputed = FALSE; $this->list = []; return parent::postSave($update); } + /** + * Checks if we want to use the richest translation. + * + * @return bool + * TRUE in case use the richest translation. + */ + protected function useRichestTranslation(): bool { + return (bool) $this->definition->getSetting(static::RICHEST_FIELDS_SETTING_KEY); + } + } -- GitLab From 3fdb0c44d12e818006621713e32b057c36801a5f Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 13 Sep 2024 16:05:05 +0200 Subject: [PATCH 087/149] ISAICP-9079: Simplify code a bit. --- .../custom/eu_oss_catalogue/eu_oss_catalogue.module | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index f014593b93..a22a3e44b9 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -99,12 +99,12 @@ function eu_oss_catalogue_entity_bundle_field_info_alter(array &$fields, EntityT ->setClass(RelevantLanguageCode::class); $computedFieldCandidates = [ - 'oss_screenshots' => $fields['oss_screenshots'], - 'oss_documentation' => $fields['oss_documentation'], + $fields['oss_screenshots'], + $fields['oss_documentation'], ]; - foreach ($computedFieldCandidates as $originalFieldName => $fieldDefinition) { + foreach ($computedFieldCandidates as $fieldDefinition) { \assert($fieldDefinition instanceof FieldDefinitionInterface); - $computedName = preg_replace('#^oss_(.*)$#', 'oss__$1', $originalFieldName); + $computedName = preg_replace('#^oss_(.*)$#', 'oss__$1', $fieldDefinition->getName()); // Field config labels have the " [stored]" suffix, what we remove here. // This original label might be a string or a (translatable) @@ -113,7 +113,7 @@ function eu_oss_catalogue_entity_bundle_field_info_alter(array &$fields, EntityT $fields[$computedName] = BaseFieldDefinition::createFromFieldStorageDefinition($fieldDefinition->getFieldStorageDefinition()) ->setName($computedName) ->setLabel($relevantLabel) - ->setSetting(RelevantField::SOURCE_FIELDS_SETTING_KEY, [$originalFieldName]) + ->setSetting(RelevantField::SOURCE_FIELDS_SETTING_KEY, [$fieldDefinition->getName()]) ->setSetting(RelevantField::RICHEST_FIELDS_SETTING_KEY, TRUE) ->setComputed(TRUE) ->setDisplayConfigurable('view', TRUE) -- GitLab From b15e01bec3c9a120c43d7cd540cd810d116326b7 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 16 Sep 2024 08:09:39 +0200 Subject: [PATCH 088/149] ISAICP-8816: remove not needed space. --- .../joinup_group/announcements.professional_domain.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/features/joinup_group/announcements.professional_domain.feature b/tests/features/joinup_group/announcements.professional_domain.feature index f6b6cfcfc3..5c010b219d 100644 --- a/tests/features/joinup_group/announcements.professional_domain.feature +++ b/tests/features/joinup_group/announcements.professional_domain.feature @@ -49,7 +49,7 @@ Feature: Filter announcements by professional domain When I go to the "Demography announcement" announcement of "Pension funds" <group> Then the following fields should be present "Professional domain filter" - And the "Professional domain filter" field should contain the "E-health Dpt., HR Dpt., Law and Justice, Social and Political" option groups + And the "Professional domain filter" field should contain the "E-health Dpt., HR Dpt., Law and Justice, Social and Political" option groups And the "Professional domain filter" select should contain the following options: | -E-health (3) | | -HR (1) | -- GitLab From a8d1d998add7e694c2af49ed81ef7f855ced5c1a Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 16 Sep 2024 08:19:02 +0200 Subject: [PATCH 089/149] ISAICP-8816: Update email. --- .../announcements.professional_domain.feature | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/features/joinup_group/announcements.professional_domain.feature b/tests/features/joinup_group/announcements.professional_domain.feature index 5c010b219d..6e7b4fb32e 100644 --- a/tests/features/joinup_group/announcements.professional_domain.feature +++ b/tests/features/joinup_group/announcements.professional_domain.feature @@ -6,15 +6,15 @@ Feature: Filter announcements by professional domain | title | state | | Pension funds | published | And users: - | Username | E-mail | Professional domain | Status | - | Mogul | mogul@example.com | Demography, E-health, E-justice, HR, HR | active | - | Greedy | greedy@example.com | Demography, E-health, E-justice | active | - | Envious | envy@example.com | Demography, E-health | active | - | Coward | coward@example.com | Demography | active | - | Nick | nick@example.com | Demography | active | - | Mark | mark@example.com | Demography | active | - | Anthony | mark@example.com | Demography | active | - | Frank | frank@example.com | Demography | blocked | + | Username | E-mail | Professional domain | Status | + | Mogul | mogul@example.com | Demography, E-health, E-justice, HR, HR | active | + | Greedy | greedy@example.com | Demography, E-health, E-justice | active | + | Envious | envy@example.com | Demography, E-health | active | + | Coward | coward@example.com | Demography | active | + | Nick | nick@example.com | Demography | active | + | Mark | mark@example.com | Demography | active | + | Anthony | anthony@example.com | Demography | active | + | Frank | frank@example.com | Demography | blocked | And the following <group> user membership: | <group> | user | announcements | state | | Pension funds | Mogul | 1 | active | -- GitLab From 40a354d028b74ec50287763c89ca446e9049d264 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 16 Sep 2024 08:45:09 +0200 Subject: [PATCH 090/149] ISAICP-8816: Fix how announcements is set. --- .../announcements.professional_domain.feature | 25 ++++++++++--------- .../my_subscriptions.feature | 2 ++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/features/joinup_group/announcements.professional_domain.feature b/tests/features/joinup_group/announcements.professional_domain.feature index 6e7b4fb32e..93e2bf41cb 100644 --- a/tests/features/joinup_group/announcements.professional_domain.feature +++ b/tests/features/joinup_group/announcements.professional_domain.feature @@ -16,15 +16,16 @@ Feature: Filter announcements by professional domain | Anthony | anthony@example.com | Demography | active | | Frank | frank@example.com | Demography | blocked | And the following <group> user membership: - | <group> | user | announcements | state | - | Pension funds | Mogul | 1 | active | - | Pension funds | Greedy | 1 | active | - | Pension funds | Envious | 1 | active | - | Pension funds | Coward | 1 | active | - | Pension funds | Nick | 1 | active | - | Pension funds | Mark | 0 | active | - | Pension funds | Anthony | 1 | blocked | - | Pension funds | Frank | 1 | active | + | <group> | user | state | + | Pension funds | Mogul | active | + | Pension funds | Greedy | active | + | Pension funds | Envious | active | + | Pension funds | Coward | active | + | Pension funds | Nick | active | + | Pension funds | Mark | active | + | Pension funds | Anthony | blocked | + | Pension funds | Frank | active | + And the "Mark" user unsubscribes from "Pension funds" <group> announcements And the following legal document version: | Document | Label | Published | Acceptance label | Content | | Legal notice | 1.1 | yes | I have read and accept | The information on this site is ... | @@ -54,10 +55,10 @@ Feature: Filter announcements by professional domain | -E-health (3) | | -HR (1) | | -E-justice (2) | - | -Demography (6) | - When I select "-Demography (6)" from "Professional domain filter" + | -Demography (5) | + When I select "-Demography (5)" from "Professional domain filter" And I press "Approve" - Then 5 e-mails should have been sent + Then 4 e-mails should have been sent When I mark all emails as read And I go to the "E-health and E-justice announcement" announcement of "Pension funds" <group> diff --git a/tests/features/joinup_subscription/my_subscriptions.feature b/tests/features/joinup_subscription/my_subscriptions.feature index 40634ef861..584417ff72 100644 --- a/tests/features/joinup_subscription/my_subscriptions.feature +++ b/tests/features/joinup_subscription/my_subscriptions.feature @@ -129,6 +129,7 @@ Feature: My subscriptions And I uncheck the "News" checkbox of the "Alpha Centauri" subscription Then the "Save changes" button on the "Alpha Centauri" subscription card should be disabled + Given I check the "Discussion" checkbox of the "Alpha Centauri" subscription And I check the "Announcements" checkbox of the "Alpha Centauri" subscription When I press "Save changes" on the "Alpha Centauri" subscription card @@ -262,6 +263,7 @@ Feature: My subscriptions | Fireblade | Announcements | | Lopitopes | Announcements | + When I uncheck the "Announcements" checkbox of the "Fireblade" subscription And I press "Save changes" on the "Fireblade" subscription card And I uncheck the "Announcements" checkbox of the "Lopitopes" subscription -- GitLab From c407f15a03272ccfe7a14fc90253d5d255261238 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 16 Sep 2024 08:48:07 +0200 Subject: [PATCH 091/149] ISAICP-8816: Revert changes. --- tests/features/joinup_subscription/my_subscriptions.feature | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/features/joinup_subscription/my_subscriptions.feature b/tests/features/joinup_subscription/my_subscriptions.feature index 584417ff72..40634ef861 100644 --- a/tests/features/joinup_subscription/my_subscriptions.feature +++ b/tests/features/joinup_subscription/my_subscriptions.feature @@ -129,7 +129,6 @@ Feature: My subscriptions And I uncheck the "News" checkbox of the "Alpha Centauri" subscription Then the "Save changes" button on the "Alpha Centauri" subscription card should be disabled - Given I check the "Discussion" checkbox of the "Alpha Centauri" subscription And I check the "Announcements" checkbox of the "Alpha Centauri" subscription When I press "Save changes" on the "Alpha Centauri" subscription card @@ -263,7 +262,6 @@ Feature: My subscriptions | Fireblade | Announcements | | Lopitopes | Announcements | - When I uncheck the "Announcements" checkbox of the "Fireblade" subscription And I press "Save changes" on the "Fireblade" subscription card And I uncheck the "Announcements" checkbox of the "Lopitopes" subscription -- GitLab From 0d76614e3d902de9d417979d92bb06fe16d7b855 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 16 Sep 2024 08:56:30 +0200 Subject: [PATCH 092/149] ISAICP-8816: Update count. --- .../joinup_group/announcements.professional_domain.feature | 4 ++-- web/modules/custom/joinup_group/src/Form/AnnouncementForm.php | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/features/joinup_group/announcements.professional_domain.feature b/tests/features/joinup_group/announcements.professional_domain.feature index 93e2bf41cb..02ab2e9dd6 100644 --- a/tests/features/joinup_group/announcements.professional_domain.feature +++ b/tests/features/joinup_group/announcements.professional_domain.feature @@ -55,8 +55,8 @@ Feature: Filter announcements by professional domain | -E-health (3) | | -HR (1) | | -E-justice (2) | - | -Demography (5) | - When I select "-Demography (5)" from "Professional domain filter" + | -Demography (4) | + When I select "-Demography (4)" from "Professional domain filter" And I press "Approve" Then 4 e-mails should have been sent diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index 3e41134289..5e6aca713e 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -404,6 +404,8 @@ public function getUsersTopicAssignment(): array { $query->join('user__field_user_professional_domain', 'pd', 'pd.entity_id = og.uid'); $query->addExpression('pd.field_user_professional_domain_target_id', 'term'); $query->fields('u', ['uid']); + // Only users which accepted the 'Legal notice' are receiving announcements. + $query->join('entity_legal_document_acceptance', 'a', 'og.uid = a.uid'); $assignments = $query->condition('og.entity_type', 'rdf_entity') ->condition('og.entity_bundle', $group->bundle()) -- GitLab From b3bb4a20d073bfddc30a6fef9417847b12ea6c36 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 16 Sep 2024 10:37:37 +0200 Subject: [PATCH 093/149] ISAICP-9079: "richest content" feature was disbled for oss__description but we have still the fallback: it displays oss_short_description if it is not empty, otherwise the value of oss_git_description is used. --- .../tests/src/Functional/OssSolutionListingPageTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/tests/src/Functional/OssSolutionListingPageTest.php b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/OssSolutionListingPageTest.php index 09f5497bfc..5a842ae8e7 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/src/Functional/OssSolutionListingPageTest.php +++ b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/OssSolutionListingPageTest.php @@ -104,7 +104,7 @@ public function testAdministrativeOssSolutionPage(): void { 'Project 1.1', 'Project 1.1', 'https://limited.self-hosted.gitlab.example.com/group1/project-1-1', - '[IT] Group1: Project 1: Short description', + 'Group 1: Project 1: description', 'Developers Italia', 'EN, DE, IT', 'Yes', @@ -115,7 +115,7 @@ public function testAdministrativeOssSolutionPage(): void { 'Project 1.2', 'Project 1.2', 'https://limited.self-hosted.gitlab.example.com/group1/project-1-2', - '[DE] Group1: Project 2: Short description', + '[EN] Group1: Project 2: Short description', 'Developers Italia', 'EN, DE, IT', 'Yes', @@ -126,7 +126,7 @@ public function testAdministrativeOssSolutionPage(): void { 'Project 1.4', 'Project 1.4', 'https://limited.self-hosted.gitlab.example.com/group1/project-1-4', - '[DE] Group1: Project 4: Short description', + 'Group 1: Project 4: description', 'Developers Italia', 'EN, DE', 'Yes', @@ -137,7 +137,7 @@ public function testAdministrativeOssSolutionPage(): void { 'Project 1', 'Project 1', 'https://limited.self-hosted.gitlab.example.com/user1/project-1', - '[DE] User 1: Project 1: Short description', + 'User 1: Project 1: description', 'Developers Italia', 'EN, DE', 'Yes', -- GitLab From 1289e5fa3527b65eab6a5cbaa2f5c583f49fa0b3 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 16 Sep 2024 11:10:10 +0200 Subject: [PATCH 094/149] ISAICP-9079: Follow changes related to oss__features, oss__screenshots and oss__description. --- .../oss_catalogue.relevant_language.feature | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/features/communities/oss_catalogue/oss_catalogue.relevant_language.feature b/tests/features/communities/oss_catalogue/oss_catalogue.relevant_language.feature index b4c5fb9ce1..18fac97e49 100644 --- a/tests/features/communities/oss_catalogue/oss_catalogue.relevant_language.feature +++ b/tests/features/communities/oss_catalogue/oss_catalogue.relevant_language.feature @@ -12,11 +12,11 @@ Feature: | | | 1690000000 | | | it | 0 | IT Feature 1,IT Feature 2 | ~~~ | IT Short description | IT file 1.jpg | ~~~ | ~~~ | When I go to the content page of the type "oss_solution" with the title "EN Title" Then I should see the heading "EN Title" - And I should not see the following lines of text: + And I should see the following lines of text: | En Feature 1 | | EN Short description | | EN Long description | - But I should see the following lines of text: + But I should not see the following lines of text: | IT Short description | | IT Feature 1 | | IT Feature 2 | @@ -27,11 +27,11 @@ Feature: When I visit "/eu-oss-catalogue" Then I should see the "EN Title" tile - And I should see the text "IT Short description" + And I should see the text "EN Short description" When I visit "/eu-oss-catalogue/solutions" Then I should see the "EN Title" tile - And I should see the text "IT Short description" + And I should see the text "EN Short description" Given I am logged in as a user with the "administrator" role And I accept the "Legal notice" agreement @@ -40,7 +40,7 @@ Feature: And I should see the "EU OSS Catalogue administration" table And the "EU OSS Catalogue administration" table should contain the following columns: | Title | URL | Short description | Source Catalogue | Languages | Published | Changed | - | EN Title | https://github.com | IT Short description | Developers Italia | EN, IT | Yes | 22/07/2023 - 04:26 | + | EN Title | https://github.com | EN Short description | Developers Italia | EN, IT | Yes | 22/07/2023 - 04:26 | # Ensures content translation edit forms can be accessed. Given I am logged in as a user with the "developer" role @@ -67,7 +67,6 @@ Feature: | EL Short description | | EL Feature 1 | | EL Feature 2 | - But I should see the following lines of text: | DE Feature 1 | | DE Feature 2 | -- GitLab From 2eee3ebfb5c5c22ec2cf9939ea05fad3a748ec1c Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Mon, 9 Sep 2024 12:46:34 +0200 Subject: [PATCH 095/149] ISAICP-9059: Disable config_readonly, remove related code. --- .ddev/commands/host/install | 2 - .ddev/commands/host/rebuild | 2 - .gitignore | 2 - .opts.yml | 6 -- README.md | 7 +- config/sync/core.extension.yml | 1 - config/sync/user.mail.yml | 2 +- resources/runner/config_readonly.yml | 16 ---- resources/runner/dev.yml | 8 -- resources/runner/drupal.yml | 1 - resources/runner/toolkit.yml | 9 -- tests/features/eulogin/eulogin.feature | 6 -- tests/src/Context/ContentTypeContext.php | 7 -- tests/src/Context/EuplContext.php | 2 - tests/src/Context/FeatureContext.php | 4 - .../src/Context/JoinupNotificationContext.php | 2 - tests/src/Context/LogRecordsContext.php | 5 -- .../Context/OeNewsroomNewsletterContext.php | 12 --- tests/src/Context/SolutionContext.php | 6 -- tests/src/Traits/AntispamTrait.php | 2 - tests/src/Traits/ConfigReadOnlyTrait.php | 84 ------------------- .../config/schema/joinup_core.schema.yml | 1 - .../custom/joinup_core/joinup_core.install | 28 ++----- .../custom/joinup_core/joinup_core.module | 24 ------ .../joinup_core/joinup_core.services.yml | 4 - .../src/ConfigReadOnlyInterface.php | 30 ------- .../joinup_core/src/FileConfigReadOnly.php | 56 ------------- .../ExistingSite/VocabularyLockingTest.php | 4 - .../JoinupExistingSiteTestBase.php | 4 - .../src/Plugin/Block/WarningMessageBlock.php | 26 +----- 30 files changed, 8 insertions(+), 355 deletions(-) delete mode 100644 resources/runner/config_readonly.yml delete mode 100644 tests/src/Traits/ConfigReadOnlyTrait.php delete mode 100644 web/modules/custom/joinup_core/src/ConfigReadOnlyInterface.php delete mode 100644 web/modules/custom/joinup_core/src/FileConfigReadOnly.php diff --git a/.ddev/commands/host/install b/.ddev/commands/host/install index 745623f7ba..afad80183b 100755 --- a/.ddev/commands/host/install +++ b/.ddev/commands/host/install @@ -6,6 +6,4 @@ ddev solr:empty ddev exec vendor/bin/run toolkit:install-clean -ddev exec vendor/bin/run config-readonly:disable ddev exec vendor/bin/run dev:install-modules -ddev exec vendor/bin/run config-readonly:enable diff --git a/.ddev/commands/host/rebuild b/.ddev/commands/host/rebuild index 95cd7825de..f18406733b 100755 --- a/.ddev/commands/host/rebuild +++ b/.ddev/commands/host/rebuild @@ -7,7 +7,5 @@ ddev solr:restore ddev virtuoso:restore ddev run toolkit:install-clone -ddev run config-readonly:disable ddev run dev:install-modules ddev drush user:unblock --uid=1 -ddev run config-readonly:enable diff --git a/.gitignore b/.gitignore index a38f1aa36e..f5e9d58a87 100644 --- a/.gitignore +++ b/.gitignore @@ -43,8 +43,6 @@ /.vscode/ /.devcontainer/ -# Ignore the config_readonly killswitch. -/disable-config-readonly # Ignore the cookie consent killswitch. /disable-cookie-consent diff --git a/.opts.yml b/.opts.yml index 1ae028cf44..5cfa6783c9 100644 --- a/.opts.yml +++ b/.opts.yml @@ -5,26 +5,20 @@ # See \EcEuropa\Toolkit\TaskRunner\Commands\CloneCommands::runDeploy(). upgrade_commands: default: - - touch disable-config-readonly - vendor/bin/drush deploy --yes - vendor/bin/drush search-api:reset-tracker --yes - vendor/bin/drush joinup:node-access-rebuild - vendor/bin/drush joinup:search-api-tasks - vendor/bin/drush twigc --yes - - rm disable-config-readonly - vendor/bin/drush joinup:unpublish-alert --category - scripts/check_status_report.php append: acceptance: - - touch disable-config-readonly - vendor/bin/drush joinup:acc - vendor/bin/drush cache:rebuild - - rm disable-config-readonly ephemeral: - - touch disable-config-readonly - vendor/bin/drush joinup:acc - vendor/bin/drush cache:rebuild - - rm disable-config-readonly php_version: 8.3 extra_pkgs: - php8.3-apcu diff --git a/README.md b/README.md index 812a443623..7c6101a945 100644 --- a/README.md +++ b/README.md @@ -235,12 +235,7 @@ Note that Toolkit uses its own configuration. Few aspects: * Apart from configuration provided by Toolkit, Joinup exposes its own configuration under `resources/runner`. * You can override any configuration by creating a `runner.yml` file in the - project's root directory. Note that this file is not under VCS control. For - instance, you may want to disable the "config read-only" feature while you - work on the project. All you need to do is to add this line in `runner.yml`: - ```yaml - config_readonly: false - ``` + project's root directory. Note that this file is not under VCS control. * You can inspect the configuration. Find out how by running this command: ```yaml ddev run config --help diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 9bc01aab90..a24fc96558 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -20,7 +20,6 @@ module: comment: 0 config: 0 config_ignore: 0 - config_readonly: 0 contact_form: 0 contact_information: 0 contextual: 0 diff --git a/config/sync/user.mail.yml b/config/sync/user.mail.yml index 514477272c..7e1b070e9e 100644 --- a/config/sync/user.mail.yml +++ b/config/sync/user.mail.yml @@ -125,4 +125,4 @@ status_canceled: Kind regards, - The Joinup Support Team + The Joinup Support Team \ No newline at end of file diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml deleted file mode 100644 index da4e29a358..0000000000 --- a/resources/runner/config_readonly.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Config readonly settings and commands. - -# Set this config to `false` in your runner.yml to permanently disable the -# config read-only feature on your development environment. -config_readonly: true - -commands: - - # Config readonly kill-switch. - config-readonly:enable: - - task: exec - command: (test "${config_readonly}" = "1" && rm -f ${joinup.dir}/disable-config-readonly) || true - - config-readonly:disable: - - task: touch - file: ${joinup.dir}/disable-config-readonly diff --git a/resources/runner/dev.yml b/resources/runner/dev.yml index 1639e5ba02..33e64dec3d 100644 --- a/resources/runner/dev.yml +++ b/resources/runner/dev.yml @@ -32,17 +32,11 @@ commands: command: solr:download-snapshot dev:install-modules: - - task: run - command: config-readonly:disable - task: run command: drush:module-install arguments: ${dev.modules} - - task: run - command: config-readonly:enable dev:demo-users: - - task: run - command: config-readonly:disable # Make sure CAS mock server module is installed. - task: run command: drush:module-install @@ -194,8 +188,6 @@ commands: options: yes: null root: ${joinup.site_dir} - - task: run - command: config-readonly:enable dev:import-sparql-fixtures: - task: run diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml index 883e0cc29c..c35d82be03 100644 --- a/resources/runner/drupal.yml +++ b/resources/runner/drupal.yml @@ -245,7 +245,6 @@ drupal: ]; // Location of the site configuration files. $settings['config_sync_directory'] = '../config/sync'; - $settings['config_readonly'] = !file_exists(getcwd() . '/../disable-config-readonly'); Testing configuration alters: | // The video from the home page interacts with Selenium tests. $config['page_manager.page_variant.homepage-layout_builder-0']['variant_settings']['sections'][4]['components']['6ab0ceea-4541-4153-8b64-227e02369d30']['configuration']['text'] = 'Some joinup video'; diff --git a/resources/runner/toolkit.yml b/resources/runner/toolkit.yml index fb5b5164db..82654f513f 100644 --- a/resources/runner/toolkit.yml +++ b/resources/runner/toolkit.yml @@ -51,9 +51,6 @@ toolkit: arguments: - install after: - # The `toolkit:run-deploy` command has enabled config read-only. - - task: run - command: config-readonly:disable - task: run command: testing:install-modules - task: exec @@ -72,8 +69,6 @@ toolkit: command: drupal:settings arguments: - site-clone - - task: run - command: config-readonly:enable - task: exec command: test ! -z "$CI" || vendor/bin/run solr:build-core-config @@ -113,8 +108,6 @@ commands: command: drupal:settings arguments: - install - - task: run - command: config-readonly:disable - task: run command: drupal:site-install options: @@ -146,8 +139,6 @@ commands: arguments: - php:eval - if (node_access_needs_rebuild()) { node_access_rebuild(); } - - task: run - command: config-readonly:enable - task: exec command: test ! -z "$CI" || vendor/bin/run solr:build-core-config diff --git a/tests/features/eulogin/eulogin.feature b/tests/features/eulogin/eulogin.feature index db96a511c1..cc5342b769 100644 --- a/tests/features/eulogin/eulogin.feature +++ b/tests/features/eulogin/eulogin.feature @@ -329,8 +329,6 @@ Feature: Log in through EU Login When I go to "/user/password" Then the response status code should be 404 - # TODO: Re-enable this test in ISAICP-9059 - @wip Scenario: As a developer I can temporary disable the site registration. Given CAS users: | Username | E-mail | Password | @@ -340,8 +338,6 @@ Feature: Log in through EU Login | dev | developer | Given I am logged in as dev - And I go to "/dashboard" - And I press "Disable config readonly" And I visit "/admin/config/people/cas" And I uncheck "Automatically register users" And I press "Save configuration" @@ -362,8 +358,6 @@ Feature: Log in through EU Login And I check "Automatically register users" And I press "Save configuration" Then I should see the message "The configuration options have been saved." - And I go to "/dashboard" - And I press "Enable config readonly" Given I am an anonymous user And I am on the homepage diff --git a/tests/src/Context/ContentTypeContext.php b/tests/src/Context/ContentTypeContext.php index 9a229bc96c..a516165952 100644 --- a/tests/src/Context/ContentTypeContext.php +++ b/tests/src/Context/ContentTypeContext.php @@ -6,15 +6,12 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\DrupalExtension\Context\RawDrupalContext; -use Drupal\joinup\Traits\ConfigReadOnlyTrait; /** * Behat context to clean up bundle entity types created during tests. */ class ContentTypeContext extends RawDrupalContext { - use ConfigReadOnlyTrait; - /** * List of entity bundle IDs before the test grouped by bundle entity type ID. * @@ -28,7 +25,6 @@ class ContentTypeContext extends RawDrupalContext { * @BeforeScenario @content_type */ public function takeNodeTypeSnapshot(): void { - self::bypassReadOnlyConfig(); $this->bundleTypeIds = $this->getEntityBundleTypes(); } @@ -55,9 +51,6 @@ public function cleanupTestNodeTypes(): void { $storage->delete($storage->loadMultiple($idsToDelete)); } } - - // Restore config readonly status. - self::restoreReadOnlyConfig(); } /** diff --git a/tests/src/Context/EuplContext.php b/tests/src/Context/EuplContext.php index 99d388bd7b..1428febbdf 100644 --- a/tests/src/Context/EuplContext.php +++ b/tests/src/Context/EuplContext.php @@ -9,7 +9,6 @@ use Drupal\DrupalExtension\Context\RawDrupalContext; use Drupal\eupl\Eupl; use Drupal\joinup\HtmlManipulator; -use Drupal\joinup\Traits\ConfigReadOnlyTrait; use Drupal\joinup\Traits\EntityTrait; use Drupal\joinup\Traits\JavascriptTrait; use Drupal\joinup\Traits\TestingEntitiesTrait; @@ -23,7 +22,6 @@ */ class EuplContext extends RawDrupalContext { - use ConfigReadOnlyTrait; use EntityTrait; use JavascriptTrait; use TestingEntitiesTrait; diff --git a/tests/src/Context/FeatureContext.php b/tests/src/Context/FeatureContext.php index a303b7baf0..6c75b00d7f 100644 --- a/tests/src/Context/FeatureContext.php +++ b/tests/src/Context/FeatureContext.php @@ -1731,9 +1731,7 @@ public function setSiteErrorLevel(?string $error_level = NULL): void { $error_level = $error_level ?: $original_error_level; if ($current_error_level !== $error_level) { - static::bypassReadOnlyConfig(); $config->set('error_level', $error_level)->save(); - static::restoreReadOnlyConfig(); } } @@ -2341,9 +2339,7 @@ protected static function toggleModule(string $method, array $module_name): void $settings = ['extension_discovery_scan_tests' => TRUE] + Settings::getAll(); new Settings($settings); - static::bypassReadOnlyConfig(); \Drupal::service('module_installer')->$method($module_name); - static::restoreReadOnlyConfig(); } /** diff --git a/tests/src/Context/JoinupNotificationContext.php b/tests/src/Context/JoinupNotificationContext.php index 3faffe013e..0399a853ff 100644 --- a/tests/src/Context/JoinupNotificationContext.php +++ b/tests/src/Context/JoinupNotificationContext.php @@ -8,7 +8,6 @@ use Drupal\Component\Render\MarkupInterface; use Drupal\DrupalExtension\Context\RawDrupalContext; use Drupal\DrupalExtension\TagTrait; -use Drupal\joinup\Traits\ConfigReadOnlyTrait; use Drupal\joinup\Traits\MailCollectorTrait; use Drupal\joinup\Traits\UserTrait; use Drupal\joinup\Traits\UtilityTrait; @@ -23,7 +22,6 @@ */ class JoinupNotificationContext extends RawDrupalContext { - use ConfigReadOnlyTrait; use MailCollectorTrait; use TagTrait; use UserTrait; diff --git a/tests/src/Context/LogRecordsContext.php b/tests/src/Context/LogRecordsContext.php index 0e496617bf..2ebaccd726 100644 --- a/tests/src/Context/LogRecordsContext.php +++ b/tests/src/Context/LogRecordsContext.php @@ -7,7 +7,6 @@ use Drupal\Component\Utility\Variable; use Drupal\Core\Logger\RfcLogLevel; use Drupal\DrupalExtension\Context\RawDrupalContext; -use Drupal\joinup\Traits\ConfigReadOnlyTrait; use PHPUnit\Framework\Assert; /** @@ -15,8 +14,6 @@ */ class LogRecordsContext extends RawDrupalContext { - use ConfigReadOnlyTrait; - /** * Whether Database Log module was originally enabled or not. */ @@ -174,7 +171,6 @@ protected function getLogRecords(?string $type = NULL): array { * @BeforeScenario @loggedErrors */ public function ensureLogger(): void { - self::bypassReadOnlyConfig(); $this->dblogStatusOriginal = \Drupal::moduleHandler()->moduleExists('dblog'); $this->timeStamp = time(); \Drupal::service('module_installer')->install(['dblog']); @@ -200,7 +196,6 @@ public function cleanupLoggerIfNeeded(): void { else { \Drupal::service('module_installer')->uninstall(['dblog']); } - self::restoreReadOnlyConfig(); } /** diff --git a/tests/src/Context/OeNewsroomNewsletterContext.php b/tests/src/Context/OeNewsroomNewsletterContext.php index 638adfe0fe..bf10bbe388 100644 --- a/tests/src/Context/OeNewsroomNewsletterContext.php +++ b/tests/src/Context/OeNewsroomNewsletterContext.php @@ -6,7 +6,6 @@ use Drupal\DrupalExtension\Context\RawDrupalContext; use Drupal\DrupalExtension\TagTrait; -use Drupal\joinup\Traits\ConfigReadOnlyTrait; use Drupal\oe_newsroom_newsletter\NewsletterSubscriber\MockNewsletterSubscriber; use PHPUnit\Framework\Assert; @@ -15,7 +14,6 @@ */ class OeNewsroomNewsletterContext extends RawDrupalContext { - use ConfigReadOnlyTrait; use TagTrait; /** @@ -71,13 +69,9 @@ public function beforeNewsletterScenario(): void { // Set up the mock subscriber. This is only needed if we aren't already // using it. if (!$mock_subscriber_is_used) { - self::bypassReadOnlyConfig(); - $config = \Drupal::configFactory()->getEditable('oe_newsroom_newsletter.subscriber'); $this->originalNewsletterSubscriber = $config->get('class'); $config->set('class', MockNewsletterSubscriber::class)->save(); - - self::restoreReadOnlyConfig(); } } @@ -89,14 +83,8 @@ public function beforeNewsletterScenario(): void { public function afterNewsletterScenario(): void { $config = \Drupal::configFactory()->get('oe_newsroom_newsletter.subscriber'); if ($config->get('class') !== $this->originalNewsletterSubscriber) { - // Temporarily bypass read only config so that we can disable the mock - // service. - self::bypassReadOnlyConfig(); - $config = \Drupal::configFactory()->getEditable('oe_newsroom_newsletter.subscriber'); $config->set('class', $this->originalNewsletterSubscriber)->save(); - - self::restoreReadOnlyConfig(); } // Clear out any subscriptions that might be left behind by the scenario. diff --git a/tests/src/Context/SolutionContext.php b/tests/src/Context/SolutionContext.php index af33d5f634..563a19107a 100644 --- a/tests/src/Context/SolutionContext.php +++ b/tests/src/Context/SolutionContext.php @@ -10,7 +10,6 @@ use Drupal\Core\Url; use Drupal\DrupalExtension\Context\RawDrupalContext; use Drupal\file_url\FileUrlHandler; -use Drupal\joinup\Traits\ConfigReadOnlyTrait; use Drupal\joinup\Traits\EntityReferenceTrait; use Drupal\joinup\Traits\EntityTrait; use Drupal\joinup\Traits\FileTrait; @@ -37,7 +36,6 @@ */ class SolutionContext extends RawDrupalContext { - use ConfigReadOnlyTrait; use EntityReferenceTrait; use EntityTrait; use FileTrait; @@ -706,11 +704,7 @@ public function languageEnabled(string $langcode): void { // Create the needed language. $language_manager = \Drupal::languageManager(); if (!$language_manager->getLanguage($langcode)) { - // Temporarily bypass the read only config functionality so that we can - // enable the language for testing. - $this->bypassReadOnlyConfig(); ConfigurableLanguage::createFromLangcode($langcode)->save(); - $this->restoreReadOnlyConfig(); } } diff --git a/tests/src/Traits/AntispamTrait.php b/tests/src/Traits/AntispamTrait.php index 088c4a4be9..2a4fc8d9a7 100644 --- a/tests/src/Traits/AntispamTrait.php +++ b/tests/src/Traits/AntispamTrait.php @@ -9,8 +9,6 @@ */ trait AntispamTrait { - use ConfigReadOnlyTrait; - /** * Checks if the current form is protected by Antibot. * diff --git a/tests/src/Traits/ConfigReadOnlyTrait.php b/tests/src/Traits/ConfigReadOnlyTrait.php deleted file mode 100644 index 54e258b40d..0000000000 --- a/tests/src/Traits/ConfigReadOnlyTrait.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\joinup\Traits; - -use Drupal\Core\Site\Settings; - -/** - * Methods to help circumvent read only config during testing. - * - * When the Config Read Only module is enabled it is no longer possible to - * change configuration, but sometimes this is required during testing, for - * example to enable temporary test services, or to test different variations of - * a certain feature. - */ -trait ConfigReadOnlyTrait { - - /** - * The initial state of config_readonly. - * - * @var bool - */ - protected static $isConfigReadonlyEnabled; - - /** - * Temporarily disables read only configuration. - * - * Make sure to call restoreReadOnlyConfig() after making the necessary config - * changes. - */ - public static function bypassReadOnlyConfig(): void { - static::checkConfigReadOnlyKillSwitch(); - - /** @var \Drupal\joinup_core\ConfigReadOnlyInterface $fileReadOnly */ - $fileReadOnly = \Drupal::service('joinup_core.file_config_read_only'); - - if (!isset(static::$isConfigReadonlyEnabled)) { - // Save the initial state of config_readonly kill-switch. - static::$isConfigReadonlyEnabled = $fileReadOnly->isReadOnlyEnabled(); - } - - $fileReadOnly->disableReadOnly(); - - // Ensure the new value also for the current request. - new Settings(['config_readonly' => FALSE] + Settings::getAll()); - } - - /** - * Restores the read only configuration functionality if available. - */ - public static function restoreReadOnlyConfig(): void { - /** @var \Drupal\joinup_core\ConfigReadOnlyInterface $fileReadOnly */ - $fileReadOnly = \Drupal::service('joinup_core.file_config_read_only'); - - // Restore as enabled only if initially has been enabled. This allows to - // keep config_readonly disabled on a local development environment (i.e. - // where the Task Runner config `config_readonly` was set to `false`), after - // the tests had finished. - if (static::$isConfigReadonlyEnabled) { - $fileReadOnly->enableReadOnly(); - // Ensure the new value also for the current request. - new Settings(['config_readonly' => TRUE] + Settings::getAll()); - } - } - - /** - * Checks if the `$settings['config_readonly']` kill-switch exists. - * - * @throws \Exception - * If the kill-switch is missed. - */ - protected static function checkConfigReadOnlyKillSwitch(): void { - /** @var \Drupal\Core\DrupalKernelInterface $kernel */ - $kernel = \Drupal::service('kernel'); - $site_path = $kernel->getSitePath(); - $needle = "\$settings['config_readonly'] = !file_exists(getcwd() . '/../disable-config-readonly');"; - $settings_php = file_get_contents("{$site_path}/settings.php"); - if (strpos($settings_php, $needle) === FALSE) { - throw new \Exception("The following line is missing from web/sites/default/settings.php\n$needle"); - } - } - -} diff --git a/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml b/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml index d5ab4e3ede..580626857c 100644 --- a/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml +++ b/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml @@ -2,7 +2,6 @@ # third-party settings. As the active config store is locked in production, we # don't want the bundle config entities to be editable, so we keep these # settings in a centralized config object which is editable. -# See joinup_core_config_readonly_whitelist_patterns(). joinup_core.outdated_content_threshold: type: config_object label: 'Entity types' diff --git a/web/modules/custom/joinup_core/joinup_core.install b/web/modules/custom/joinup_core/joinup_core.install index 823aea261c..5fdda9e198 100644 --- a/web/modules/custom/joinup_core/joinup_core.install +++ b/web/modules/custom/joinup_core/joinup_core.install @@ -7,7 +7,6 @@ declare(strict_types=1); -use Drupal\Core\Site\Settings; use Drupal\user\Entity\User; /** @@ -35,32 +34,15 @@ function joinup_core_requirements($phase): array { ]; } - // Check that the Config Read Only module is enabled and activated. This - // module ensures that the site configuration is immutable. This greatly - // enhances the security of the production environment, and ensures that no - // changes are made on production which can be overwritten on a subsequent - // update. /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ $module_handler = \Drupal::service('module_handler'); - if (!$module_handler->moduleExists('config_readonly') || !Settings::get('config_readonly')) { - $requirements['joinup_core_config_readonly'] = [ - 'title' => t('Config Read Only'), - 'description' => t('On production environments the site configuration should be read-only.'), + if ($module_handler->moduleExists('dblog')) { + $requirements['joinup_core_dblog'] = [ + 'title' => t('Database logging'), + 'description' => t('On production environments logs should be written to a file, not to the database.'), 'severity' => REQUIREMENT_ERROR, - 'value' => t('Config is writable'), + 'value' => t('Database logging is enabled'), ]; - - // Check that database logging is disabled on production. Writing log - // entries to the database on every request puts unnecessary load on the - // database server. - if ($module_handler->moduleExists('dblog')) { - $requirements['joinup_core_dblog'] = [ - 'title' => t('Database logging'), - 'description' => t('On production environments logs should be written to a file, not to the database.'), - 'severity' => REQUIREMENT_ERROR, - 'value' => t('Database logging is enabled'), - ]; - } } $requirements_helper = \Drupal::getContainer() diff --git a/web/modules/custom/joinup_core/joinup_core.module b/web/modules/custom/joinup_core/joinup_core.module index 71a29139dc..d9871024b1 100644 --- a/web/modules/custom/joinup_core/joinup_core.module +++ b/web/modules/custom/joinup_core/joinup_core.module @@ -207,30 +207,6 @@ function joinup_core_preprocess_responsive_image_formatter(&$variables): void { } } -/** - * Implements hook_config_readonly_whitelist_patterns(). - */ -function joinup_core_config_readonly_whitelist_patterns(): array { - return [ - // The 'support' and footer menus are editable by moderators. This includes - // the menu links static overrides config. - 'system.menu.footer-about-us', - 'system.menu.footer-european-commission', - 'system.menu.footer-follow-us', - 'system.menu.footer-help-and-support', - 'system.menu.support', - 'system.menu.navbar', - // The outdated content threshold is editable by moderators. - 'joinup_core.outdated_content_threshold', - 'core.menu.static_menu_link_overrides', - // Moderators can create webforms. - 'webform.webform.*', - // Prevent simple sitemap to interfere with webform deletion. - /* @see \Drupal\simple_sitemap\Entity\SimpleSitemapStorage::doDelete */ - 'simple_sitemap.bundle_settings.*.webform_submission.*', - ]; -} - /** * Implements hook_module_implements_alter(). */ diff --git a/web/modules/custom/joinup_core/joinup_core.services.yml b/web/modules/custom/joinup_core/joinup_core.services.yml index 9ed58a6e57..25cc8bcb44 100644 --- a/web/modules/custom/joinup_core/joinup_core.services.yml +++ b/web/modules/custom/joinup_core/joinup_core.services.yml @@ -42,10 +42,6 @@ services: tags: - { name: event_subscriber } - joinup_core.file_config_read_only: - class: Drupal\joinup_core\FileConfigReadOnly - arguments: [ '@file_system' ] - # Prevent errors in twigc by implementing the missing get_dummy_text function, # which is referenced in BCL component templates. joinup_core.twig_extension: diff --git a/web/modules/custom/joinup_core/src/ConfigReadOnlyInterface.php b/web/modules/custom/joinup_core/src/ConfigReadOnlyInterface.php deleted file mode 100644 index e74bce804d..0000000000 --- a/web/modules/custom/joinup_core/src/ConfigReadOnlyInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\joinup_core; - -/** - * Config read-only interface. - */ -interface ConfigReadOnlyInterface { - - /** - * Checks if read-only mode is enabled. - * - * @return bool - * Returns true if read-only mode is enabled, false otherwise. - */ - public function isReadOnlyEnabled(): bool; - - /** - * Disables read-only mode. - */ - public function disableReadOnly(): void; - - /** - * Enables read-only mode. - */ - public function enableReadOnly(): void; - -} diff --git a/web/modules/custom/joinup_core/src/FileConfigReadOnly.php b/web/modules/custom/joinup_core/src/FileConfigReadOnly.php deleted file mode 100644 index 7ff9241f8d..0000000000 --- a/web/modules/custom/joinup_core/src/FileConfigReadOnly.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\joinup_core; - -use Drupal\Core\File\FileSystemInterface; - -/** - * Represents a file-based implementation of the ConfigReadOnlyInterface. - */ -class FileConfigReadOnly implements ConfigReadOnlyInterface { - - /** - * File name of the disabled config readonly. - * - * @var string - */ - protected const string FILE_NAME = 'disable-config-readonly'; - - public function __construct(protected FileSystemInterface $fileSystem) {} - - /** - * {@inheritdoc} - */ - public function isReadOnlyEnabled(): bool { - return !file_exists($this->pathToReadOnlyFile()); - } - - /** - * {@inheritdoc} - */ - public function enableReadOnly(): void { - if (!$this->isReadOnlyEnabled()) { - $this->fileSystem->unlink($this->pathToReadOnlyFile()); - } - } - - /** - * {@inheritdoc} - */ - public function disableReadOnly(): void { - touch($this->pathToReadOnlyFile()); - } - - /** - * Returns the file path to disable the config readonly flag. - * - * @return string - * The file path - */ - protected function pathToReadOnlyFile(): string { - return DRUPAL_ROOT . '/../' . self::FILE_NAME; - } - -} diff --git a/web/modules/custom/joinup_taxonomy/tests/src/ExistingSite/VocabularyLockingTest.php b/web/modules/custom/joinup_taxonomy/tests/src/ExistingSite/VocabularyLockingTest.php index 5917d9e94a..ce43c8d374 100644 --- a/web/modules/custom/joinup_taxonomy/tests/src/ExistingSite/VocabularyLockingTest.php +++ b/web/modules/custom/joinup_taxonomy/tests/src/ExistingSite/VocabularyLockingTest.php @@ -23,7 +23,6 @@ public function testVocabularyLocking(): void { $session = $this->getSession(); $assert = $this->assertSession(); - $this->bypassReadOnlyConfig(); $vocabulary = $this->createVocabulary(); $vocabulary->setThirdPartySetting('joinup_taxonomy', 'locked', FALSE)->save(); $account = $this->createUser([ @@ -34,7 +33,6 @@ public function testVocabularyLocking(): void { // Bypass the legal notice form. 'administer entity legal', ]); - $this->restoreReadOnlyConfig(); $oneTimeLoginUrl = $this->user_pass_reset_url($account) . '/login'; $session->visit($oneTimeLoginUrl); @@ -54,9 +52,7 @@ public function testVocabularyLocking(): void { $this->drupalGet($term->toUrl('delete-form')); $assert->statusCodeEquals(200); - $this->bypassReadOnlyConfig(); $vocabulary->setThirdPartySetting('joinup_taxonomy', 'locked', TRUE)->save(); - $this->restoreReadOnlyConfig(); // Check that create route is not accessible. $this->drupalGet("admin/structure/taxonomy/manage/{$vocabulary->id()}/add"); diff --git a/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php b/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php index 4f260e45cc..670c39c78c 100644 --- a/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php +++ b/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php @@ -8,7 +8,6 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; use Drupal\Tests\joinup_test\Traits\RdfEntityCreationTrait; -use Drupal\joinup\Traits\ConfigReadOnlyTrait; use Drupal\taxonomy\VocabularyInterface; use weitzman\DrupalTestTraits\ExistingSiteBase; @@ -26,7 +25,6 @@ abstract class JoinupExistingSiteTestBase extends ExistingSiteBase { */ protected array $casUsers = []; - use ConfigReadOnlyTrait; use RdfEntityCreationTrait; /** @@ -75,9 +73,7 @@ public function tearDown(): void { \Drupal::getContainer()->get('cas_mock_server.user_manager')->deleteUsers($this->casUsers); // The parent method might cleanup config entities. - $this->bypassReadOnlyConfig(); parent::tearDown(); - $this->restoreReadOnlyConfig(); // Delete the OG group content orphans now because parent::tearDown() is // destroying the container and the registered shutdown callback will fail. diff --git a/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php b/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php index eb54e480d4..a89da4cd46 100644 --- a/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php +++ b/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php @@ -8,11 +8,8 @@ use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Block\Attribute\Block; use Drupal\Core\Block\BlockBase; -use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; -use Drupal\joinup_core\ConfigReadOnlyInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a developers warning message block. @@ -22,28 +19,7 @@ admin_label: new TranslatableMarkup("Developers warning message"), category: new TranslatableMarkup("Joinup"), )] -final class WarningMessageBlock extends BlockBase implements ContainerFactoryPluginInterface { - - public function __construct( - array $configuration, - string $pluginId, - mixed $pluginDefinition, - protected ConfigReadOnlyInterface $fileConfigReadOnly, - ) { - parent::__construct($configuration, $pluginId, $pluginDefinition); - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('joinup_core.file_config_read_only') - ); - } +final class WarningMessageBlock extends BlockBase { /** * {@inheritdoc} -- GitLab From 6ed721b854ec762ab88159d5083d801488a8d237 Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Mon, 9 Sep 2024 16:51:20 +0200 Subject: [PATCH 096/149] ISAICP-9059: Remove "administer matomo integration" and related form (but keep config). Leftover from 733156d4. --- config/sync/user.role.moderator.yml | 1 - .../joinup_core/joinup_core.permissions.yml | 3 -- .../joinup_stats/joinup_stats.routing.yml | 9 ---- .../src/Form/JoinupStatsSettingsForm.php | 52 ------------------- 4 files changed, 65 deletions(-) delete mode 100644 web/modules/custom/joinup_stats/joinup_stats.routing.yml delete mode 100644 web/modules/custom/joinup_stats/src/Form/JoinupStatsSettingsForm.php diff --git a/config/sync/user.role.moderator.yml b/config/sync/user.role.moderator.yml index e3948869e1..6f6924eb40 100644 --- a/config/sync/user.role.moderator.yml +++ b/config/sync/user.role.moderator.yml @@ -96,7 +96,6 @@ permissions: - 'administer footer-european-commission menu items' - 'administer footer-follow-us menu items' - 'administer footer-help-and-support menu items' - - 'administer matomo integration' - 'administer navbar menu items' - 'administer nodes' - 'administer organic groups' diff --git a/web/modules/custom/joinup_core/joinup_core.permissions.yml b/web/modules/custom/joinup_core/joinup_core.permissions.yml index fb341ee7c0..5504bc8270 100644 --- a/web/modules/custom/joinup_core/joinup_core.permissions.yml +++ b/web/modules/custom/joinup_core/joinup_core.permissions.yml @@ -1,8 +1,5 @@ access uri converter: title: 'Access URI encoder/decoder' description: 'Allow a user to use the web-based RDF ID/URI encoder and decoder.' -administer matomo integration: - title: 'Administer Matomo integration' - description: 'Grants access to the Matomo Integration settings form.' administer outdated content threshold: title: 'Administer outdated content thresholds' diff --git a/web/modules/custom/joinup_stats/joinup_stats.routing.yml b/web/modules/custom/joinup_stats/joinup_stats.routing.yml deleted file mode 100644 index 6d33367ca3..0000000000 --- a/web/modules/custom/joinup_stats/joinup_stats.routing.yml +++ /dev/null @@ -1,9 +0,0 @@ -joinup_stats.settings: - path: '/admin/statistics/settings' - defaults: - _form: Drupal\joinup_stats\Form\JoinupStatsSettingsForm - _title: 'Statistics settings' - requirements: - _permission: 'administer matomo integration' - options: - _admin_route: TRUE diff --git a/web/modules/custom/joinup_stats/src/Form/JoinupStatsSettingsForm.php b/web/modules/custom/joinup_stats/src/Form/JoinupStatsSettingsForm.php deleted file mode 100644 index b54afca5a0..0000000000 --- a/web/modules/custom/joinup_stats/src/Form/JoinupStatsSettingsForm.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\joinup_stats\Form; - -use Drupal\Core\Form\ConfigFormBase; -use Drupal\Core\Form\FormStateInterface; - -/** - * Settings form for integration with the Matomo analytics platform. - */ -class JoinupStatsSettingsForm extends ConfigFormBase { - - /** - * {@inheritdoc} - */ - protected function getEditableConfigNames(): array { - return ['joinup_stats.settings']; - } - - /** - * {@inheritdoc} - */ - public function getFormId(): string { - return 'joinup_stats_settings'; - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, FormStateInterface $form_state): array { - $form['launch_date'] = [ - '#type' => 'date', - '#title' => $this->t('Launch date'), - '#description' => $this->t('The date when the website was launched. This is used as the start date for the "All time" option.'), - '#default_value' => $this->config('joinup_stats.settings')->get('launch_date'), - ]; - return parent::buildForm($form, $form_state); - } - - /** - * {@inheritdoc} - */ - public function submitForm(array &$form, FormStateInterface $form_state): void { - parent::submitForm($form, $form_state); - $this->config('joinup_stats.settings') - ->set('launch_date', $form_state->getValue('launch_date')) - ->save(); - } - -} -- GitLab From c8af28bb758da13f303f68d1a5d9fe3029f382ac Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Wed, 11 Sep 2024 18:13:50 +0200 Subject: [PATCH 097/149] ISAICP-9059: Resolve "administer entity legal" permission. - Update drupal/entity_legal (4.0.0-alpha3 => 4.0.0-alpha4). - New 'administer entity legal document versions' in joinup_legal - Revoke 'administer entity legal' to moderators and assign both new permissions. --- composer.lock | 14 +++++++------- config/sync/user.role.moderator.yml | 3 ++- web/modules/custom/legal/joinup_legal.module | 12 ++++++++++++ .../custom/legal/joinup_legal.permissions.yml | 2 ++ web/modules/custom/legal/joinup_legal.routing.yml | 4 ++-- 5 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 web/modules/custom/legal/joinup_legal.permissions.yml diff --git a/composer.lock b/composer.lock index 6b17f70f6b..5efe627278 100644 --- a/composer.lock +++ b/composer.lock @@ -3441,17 +3441,17 @@ }, { "name": "drupal/entity_legal", - "version": "4.0.0-alpha3", + "version": "4.0.0-alpha4", "source": { "type": "git", "url": "https://git.drupalcode.org/project/entity_legal.git", - "reference": "4.0.0-alpha3" + "reference": "4.0.0-alpha4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entity_legal-4.0.0-alpha3.zip", - "reference": "4.0.0-alpha3", - "shasum": "685723ce9b58c2c3faf098c6f945a800880fd923" + "url": "https://ftp.drupal.org/files/projects/entity_legal-4.0.0-alpha4.zip", + "reference": "4.0.0-alpha4", + "shasum": "898df201afc638c1c1f4863ebb865e1135b76c5d" }, "require": { "drupal/core": "^9 || ^10", @@ -3460,8 +3460,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "4.0.0-alpha3", - "datestamp": "1702595381", + "version": "4.0.0-alpha4", + "datestamp": "1726076418", "security-coverage": { "status": "not-covered", "message": "Alpha releases are not covered by Drupal security advisories." diff --git a/config/sync/user.role.moderator.yml b/config/sync/user.role.moderator.yml index 6f6924eb40..a3a00f5392 100644 --- a/config/sync/user.role.moderator.yml +++ b/config/sync/user.role.moderator.yml @@ -91,7 +91,7 @@ permissions: - 'add sitewide alert entities' - 'administer collection ownership' - 'administer comments' - - 'administer entity legal' + - 'administer entity legal document versions' - 'administer footer-about-us menu items' - 'administer footer-european-commission menu items' - 'administer footer-follow-us menu items' @@ -109,6 +109,7 @@ permissions: - 'administer webform element access' - 'administer webform submission' - 'assign licence_manager role' + - 'bypass entity legal acceptance' - 'create collection rdf entity' - 'create collection_logo media' - 'create contact_information content' diff --git a/web/modules/custom/legal/joinup_legal.module b/web/modules/custom/legal/joinup_legal.module index 8791c20a81..c52851a6e3 100644 --- a/web/modules/custom/legal/joinup_legal.module +++ b/web/modules/custom/legal/joinup_legal.module @@ -7,7 +7,11 @@ declare(strict_types=1); +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Access\AccessResultInterface; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\entity_legal\Entity\EntityLegalDocument; use Drupal\entity_legal\Entity\EntityLegalDocumentAcceptance; @@ -137,3 +141,11 @@ function joinup_legal_form_cas_account_link_form_submit(array &$form, FormStateI ])->save(); } } + +/** + * Implements hook_ENTITY_TYPE_access() for entity_legal_document_version. + */ +function joinup_legal_entity_legal_document_version_access(EntityInterface $entity, $operation, AccountInterface $account): AccessResultInterface { + // Allow moderators to manage document versions. + return AccessResult::allowedIfHasPermission($account, 'administer entity legal document versions'); +} diff --git a/web/modules/custom/legal/joinup_legal.permissions.yml b/web/modules/custom/legal/joinup_legal.permissions.yml new file mode 100644 index 0000000000..a27326b05b --- /dev/null +++ b/web/modules/custom/legal/joinup_legal.permissions.yml @@ -0,0 +1,2 @@ +administer entity legal document versions: + title: 'Administer entity legal document versions' diff --git a/web/modules/custom/legal/joinup_legal.routing.yml b/web/modules/custom/legal/joinup_legal.routing.yml index 2a538fe22e..b2238bde8e 100644 --- a/web/modules/custom/legal/joinup_legal.routing.yml +++ b/web/modules/custom/legal/joinup_legal.routing.yml @@ -4,7 +4,7 @@ joinup_legal.version.collection: _form: Drupal\joinup_legal\Form\JoinupLegalVersionsForm _title: 'Legal notice versions' requirements: - _permission: 'administer entity legal' + _permission: 'administer entity legal document versions' joinup_legal.version.add: path: '/admin/legal-notice/add' @@ -13,7 +13,7 @@ joinup_legal.version.add: _title_callback: Drupal\entity_legal\Controller\EntityLegalController::documentVersionAddFormTitle entity_legal_document: legal_notice requirements: - _permission: 'administer entity legal' + _permission: 'administer entity legal document versions' joinup_legal.version.edit: path: '/admin/legal-notice/manage/{entity_legal_document_version}' -- GitLab From 4824a976beee14ed33c5df5988bf9565a06a3060 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 08:22:56 +0200 Subject: [PATCH 098/149] ISAICP-9003: Translate functionality. --- config/sync/core.extension.yml | 1 + .../modules/eu_oss_translate/eu_oss_translate.info.yml | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translate/eu_oss_translate.info.yml diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 3dc37b0a49..28ed82091a 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -50,6 +50,7 @@ module: entityqueue_block: 0 error_page: 0 eu_oss_catalogue: 0 + eu_oss_translate: 0 eu_oss_vitality_index: 0 eupl: 0 facets: 0 diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translate/eu_oss_translate.info.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translate/eu_oss_translate.info.yml new file mode 100644 index 0000000000..6ad1c84b50 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translate/eu_oss_translate.info.yml @@ -0,0 +1,7 @@ +name: EU OSS Translate +type: module +description: Translate functionality +package: EU OSS Catalogue +core_version_requirement: ">=10.0" +dependencies: + - eu_oss_catalogue:eu_oss_catalogue -- GitLab From 4cea1353b35f97a3ad9df2185e3f6e4e1c9499b5 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 11:47:07 +0200 Subject: [PATCH 099/149] ISAICP-9003: Dont translate metatag. --- .../joinup_oss_catalogue/joinup_oss_catalogue.module | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module index 9eedf4aabb..a740c2e6d1 100644 --- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module +++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module @@ -9,6 +9,7 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResultInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; @@ -316,3 +317,12 @@ function joinup_oss_catalogue_toggle(string $toggle): void { // The 'Explore' block caches is time-based (6h). Explicitly clear the cache. \Drupal::getContainer()->get('cache_tags.invalidator')->invalidateTags(['homepage_explore_block']); } + +/** + * Implements hook_tmgmt_translatable_fields_alter(). + */ +function joinup_oss_catalogue_tmgmt_translatable_fields_alter(ContentEntityInterface $entity, array &$translatableFields): void { + if ($entity instanceof OssSolutionInterface && isset($translatableFields['metatag'])) { + unset($translatableFields['metatag']); + } +} -- GitLab From adce65449f7c44264570f0d12e2e5434db80d5e8 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 11:52:21 +0200 Subject: [PATCH 100/149] ISAICP-9003: EU OSS Translation. --- config/sync/core.extension.yml | 2 +- config/sync/eu_oss_translation.settings.yml | 1 + .../install/eu_oss_translation.settings.yml | 1 + .../schema/eu_oss_translation.schema.yml | 9 ++ .../eu_oss_translation/drush.services.yml | 8 ++ .../eu_oss_translation.info.yml} | 5 +- .../eu_oss_translation.services.yml | 8 ++ .../src/Commands/EuOssTranslationCommands.php | 72 ++++++++++++++ .../eu_oss_translation/src/JobBuilder.php | 95 +++++++++++++++++++ .../src/JobBuilderInterface.php | 22 +++++ .../QueueWorker/TranslationRequester.php | 59 ++++++++++++ 11 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 config/sync/eu_oss_translation.settings.yml create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/install/eu_oss_translation.settings.yml create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/schema/eu_oss_translation.schema.yml create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/drush.services.yml rename web/modules/custom/eu_oss_catalogue/modules/{eu_oss_translate/eu_oss_translate.info.yml => eu_oss_translation/eu_oss_translation.info.yml} (58%) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Commands/EuOssTranslationCommands.php create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 28ed82091a..fae3e9a300 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -50,7 +50,7 @@ module: entityqueue_block: 0 error_page: 0 eu_oss_catalogue: 0 - eu_oss_translate: 0 + eu_oss_translation: 0 eu_oss_vitality_index: 0 eupl: 0 facets: 0 diff --git a/config/sync/eu_oss_translation.settings.yml b/config/sync/eu_oss_translation.settings.yml new file mode 100644 index 0000000000..65796f7f2e --- /dev/null +++ b/config/sync/eu_oss_translation.settings.yml @@ -0,0 +1 @@ +translator: 'ec_etranslation' diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/install/eu_oss_translation.settings.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/install/eu_oss_translation.settings.yml new file mode 100644 index 0000000000..65796f7f2e --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/install/eu_oss_translation.settings.yml @@ -0,0 +1 @@ +translator: 'ec_etranslation' diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/schema/eu_oss_translation.schema.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/schema/eu_oss_translation.schema.yml new file mode 100644 index 0000000000..341ad122ef --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/config/schema/eu_oss_translation.schema.yml @@ -0,0 +1,9 @@ +# Schema for the configuration files of the EU OSS Translation module. + +eu_oss_translation.settings: + type: config_object + label: 'Translation settings' + mapping: + translator: + type: string + label: 'Translator provider' diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/drush.services.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/drush.services.yml new file mode 100644 index 0000000000..6445ac185a --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/drush.services.yml @@ -0,0 +1,8 @@ +services: + eu_oss_translation.commands: + class: Drupal\eu_oss_translation\Commands\EuOssTranslationCommands + arguments: + - '@eu_oss_translation.job_builder' + - '@entity_type.manager' + tags: + - { name: drush.command } diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translate/eu_oss_translate.info.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.info.yml similarity index 58% rename from web/modules/custom/eu_oss_catalogue/modules/eu_oss_translate/eu_oss_translate.info.yml rename to web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.info.yml index 6ad1c84b50..8d05b65e29 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translate/eu_oss_translate.info.yml +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.info.yml @@ -1,7 +1,8 @@ -name: EU OSS Translate +name: EU OSS Translation type: module -description: Translate functionality +description: Translation functionality for EU OSS package: EU OSS Catalogue core_version_requirement: ">=10.0" dependencies: - eu_oss_catalogue:eu_oss_catalogue + - tmgmt:tmgmt diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml new file mode 100644 index 0000000000..5d509acc85 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml @@ -0,0 +1,8 @@ +services: + eu_oss_translation.job_builder: + class: Drupal\eu_oss_translation\JobBuilder + arguments: + - '@current_user' + - '@entity_type.manager' + - '@logger.channel.eu_oss_catalogue' + - '@config.factory' diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Commands/EuOssTranslationCommands.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Commands/EuOssTranslationCommands.php new file mode 100644 index 0000000000..cdeecf01a4 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Commands/EuOssTranslationCommands.php @@ -0,0 +1,72 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_translation\Commands; + +use Consolidation\AnnotatedCommand\CommandData; +use Consolidation\AnnotatedCommand\Hooks\HookManager; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; +use Drupal\eu_oss_translation\JobBuilderInterface; +use Drush\Attributes as CLI; +use Drush\Commands\DrushCommands; + +/** + * Drush commands. + */ +class EuOssTranslationCommands extends DrushCommands { + + public function __construct( + protected JobBuilderInterface $jobBuilder, + protected EntityTypeManagerInterface $entityTypeManager, + ) { + parent::__construct(); + } + + /** + * Generates translation job. + */ + #[CLI\Command(name: 'eu-oss:generate-translation-job')] + #[CLI\Argument(name: 'nid', description: 'The solution node ID')] + public function generate(string $nid): string { + $solution = $this->getSolution($nid); + $this->jobBuilder->create($solution); + + return dt('Generation of translation job for @url was processed.', [ + '@url' => $solution->toUrl()->setAbsolute()->toString(), + ]); + } + + /** + * Gets solution. + * + * @param string $nid + * Solution node id. + * + * @return \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface|null + * OSS solution. + */ + protected function getSolution(string $nid): ?OssSolutionInterface { + $nodeStorage = $this->entityTypeManager->getStorage('node'); + $solution = $nodeStorage->load($nid); + + return $solution instanceof OssSolutionInterface ? $solution : NULL; + } + + /** + * Validates the argument of eu-oss:generate-vitality-index. + */ + #[CLI\Hook(type: HookManager::ARGUMENT_VALIDATOR, target: 'eu-oss:generate-translation-job')] + public function validateSolutionId(CommandData $commandData): void { + $nid = $commandData->input()->getArgument('nid'); + + $solution = $this->getSolution($nid); + if (!$solution) { + throw new \Exception(dt("The solution with node id '@nid' doesn't exist", [ + '@nid' => $nid, + ])); + } + } + +} diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php new file mode 100644 index 0000000000..1bb9310d1a --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php @@ -0,0 +1,95 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_translation; + +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Config\ImmutableConfig; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Logger\LoggerChannelInterface; +use Drupal\Core\Session\AccountInterface; +use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; + +/** + * Job builder service. + */ +class JobBuilder implements JobBuilderInterface { + + /** + * Module config. + * + * @var \Drupal\Core\Config\ImmutableConfig + */ + protected ImmutableConfig $config; + + public function __construct( + protected AccountInterface $currentUser, + protected EntityTypeManagerInterface $entityTypeManager, + protected LoggerChannelInterface $logger, + ConfigFactoryInterface $configFactory, + ) { + $this->config = $configFactory->get('eu_oss_translation.settings'); + } + + /** + * {@inheritdoc} + */ + public function create(OssSolutionInterface $entity): void { + if ($this->isBeingProcessed($entity)) { + return; + } + + $this->createJob($entity); + } + + /** + * Checks if entity being processed. + * + * @param \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface $entity + * Oss solution. + * + * @return bool + * True if it is being processed. + */ + protected function isBeingProcessed(OssSolutionInterface $entity): bool { + $sourceLangCode = $entity->getRelevantLangCode(); + + return tmgmt_job_item_load_latest('content', $entity->getEntityTypeId(), $entity->id(), $sourceLangCode) !== FALSE; + } + + /** + * Creates tmgmt job. + * + * @param \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface $entity + * OSS entity. + */ + protected function createJob(OssSolutionInterface $entity): void { + try { + $jobStorage = $this->entityTypeManager->getStorage('tmgmt_job'); + + /** @var \Drupal\tmgmt\JobInterface $job */ + $job = $jobStorage->create( + [ + 'source_language' => $entity->getRelevantLangCode(), + 'target_language' => 'en', + 'uid' => $this->currentUser->id(), + 'translator' => $this->config->get('translator'), + ] + ); + $job->save(); + + $item = $job->addItem('content', $entity->getEntityTypeId(), $entity->id()); + $item->save(); + + $job->requestTranslation(); + } + catch (\Exception $e) { + $this->logger->error('An issue occurred during creating the translation job. Message: @message', [ + '@message' => $e->getMessage(), + 'oss_solution' => $entity->id(), + ]); + } + } + +} diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php new file mode 100644 index 0000000000..c45a63985f --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php @@ -0,0 +1,22 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_translation; + +use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; + +/** + * Describes job_builder service. + */ +interface JobBuilderInterface { + + /** + * Creates the tmgmt job. + * + * @param \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface $entity + * OSS solution entity. + */ + public function create(OssSolutionInterface $entity): void; + +} diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php new file mode 100644 index 0000000000..07a6d6d7fa --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php @@ -0,0 +1,59 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_translation\Plugin\QueueWorker; + +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Queue\QueueWorkerBase; +use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; +use Drupal\eu_oss_translation\JobBuilderInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Defines 'eu_oss_translation_requester' queue worker. + * + * @QueueWorker( + * id = "eu_oss_translation_requester", + * title = @Translation("Translation requester"), + * cron = {"time" = 60}, + * ) + */ +class TranslationRequester extends QueueWorkerBase implements ContainerFactoryPluginInterface { + + public function __construct( + array $configuration, + string $plugin_id, + array $plugin_definition, + protected EntityTypeManagerInterface $entityTypeManager, + protected JobBuilderInterface $jobBuilder, + ) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity_type.manager'), + $container->get('eu_oss_translation.job_builder') + ); + } + + /** + * {@inheritdoc} + */ + public function processItem(mixed $data): void { + $nodeStorage = $this->entityTypeManager->getStorage('node'); + if ($data['nid'] && ($node = $nodeStorage->load($data['nid'])) + && $node instanceof OssSolutionInterface) { + $this->jobBuilder->create($node); + } + } + +} -- GitLab From ba107ed75c49a929fa66ede2abe308adb85f128c Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 11:53:15 +0200 Subject: [PATCH 101/149] ISAICP-9003: Fix docblock. --- .../modules/eu_oss_translation/src/JobBuilderInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php index c45a63985f..27e9c9a001 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilderInterface.php @@ -15,7 +15,7 @@ interface JobBuilderInterface { * Creates the tmgmt job. * * @param \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface $entity - * OSS solution entity. + * OSS solution entity. */ public function create(OssSolutionInterface $entity): void; -- GitLab From df2f56a563c8da1741358df983461574eeeca7f6 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 13:09:05 +0200 Subject: [PATCH 102/149] ISAICP-9003: Don't translate if relevant lang code is en. --- .../eu_oss_translation/src/JobBuilder.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php index 1bb9310d1a..134d05f3e1 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php @@ -16,6 +16,11 @@ */ class JobBuilder implements JobBuilderInterface { + /** + * Target language. + */ + const string TARGET_LANGUAGE = 'en'; + /** * Module config. * @@ -40,7 +45,9 @@ public function create(OssSolutionInterface $entity): void { return; } - $this->createJob($entity); + if ($this->needsTranslation($entity)) { + $this->createJob($entity); + } } /** @@ -58,6 +65,19 @@ protected function isBeingProcessed(OssSolutionInterface $entity): bool { return tmgmt_job_item_load_latest('content', $entity->getEntityTypeId(), $entity->id(), $sourceLangCode) !== FALSE; } + /** + * Checks if node needs translation. + * + * @param \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface $entity + * Oss solution. + * + * @return bool + * True if a node needs translation. + */ + protected function needsTranslation(OssSolutionInterface $entity): bool { + return $entity->getRelevantLangCode() !== self::TARGET_LANGUAGE; + } + /** * Creates tmgmt job. * @@ -72,7 +92,7 @@ protected function createJob(OssSolutionInterface $entity): void { $job = $jobStorage->create( [ 'source_language' => $entity->getRelevantLangCode(), - 'target_language' => 'en', + 'target_language' => self::TARGET_LANGUAGE, 'uid' => $this->currentUser->id(), 'translator' => $this->config->get('translator'), ] -- GitLab From 693359bb86c720f80b6d3267a38515181266692e Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 13:16:15 +0200 Subject: [PATCH 103/149] ISAICP-9003: Update settings. --- config/sync/eu_oss_translation.settings.yml | 2 +- .../sync/tmgmt.translator.ec_etranslation.yml | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/config/sync/eu_oss_translation.settings.yml b/config/sync/eu_oss_translation.settings.yml index 65796f7f2e..eb4765918e 100644 --- a/config/sync/eu_oss_translation.settings.yml +++ b/config/sync/eu_oss_translation.settings.yml @@ -1 +1 @@ -translator: 'ec_etranslation' +translator: ec_etranslation diff --git a/config/sync/tmgmt.translator.ec_etranslation.yml b/config/sync/tmgmt.translator.ec_etranslation.yml index d2f4b9b731..1dfc21bfd0 100644 --- a/config/sync/tmgmt.translator.ec_etranslation.yml +++ b/config/sync/tmgmt.translator.ec_etranslation.yml @@ -7,12 +7,23 @@ dependencies: name: ec_etranslation label: 'European Commission eTranslation' description: "Allows the European Commission's eTranslation service to process translation jobs." -auto_accept: null +auto_accept: true weight: null plugin: ec_etranslation settings: - username: null - password: null + username: '' + password: '' domain: SPD - email: null -remote_languages_mappings: { } + email: '' +remote_languages_mappings: + cs: cs + da: da + nl: nl + en: en + et: et + fr: fr + de: de + el: el + it: it + sl: sl + es: es -- GitLab From e9a40dcb891fab420f59c333cec838cd4b6d8bb3 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 13:38:59 +0200 Subject: [PATCH 104/149] ISAICP-9003: Add README.md --- .../modules/eu_oss_translation/README.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md new file mode 100644 index 0000000000..74dc2c1324 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md @@ -0,0 +1,26 @@ +## EU OSS Translation | EU OSS Catalogue + +Module provides translations to OSS solution nodes + +### Description +When an OSS solution entity is created or updated, the system attempts to create a TMGMT job. + +### Configuration +* Configure the TMGMT translator provider: +* It is recommended to use the provider implemented by the "tmgmt_ec_etranslation" module. +* Select "Auto accept finished translations" within the provider if you want to skip the review process. +* Set the translator provider for the eu_oss_translation module (the default is set to ec_etranslation). + + +### Useful commands + +The module ships with a Drush command that allows to create the translation job. +Run the following, to create translation job: +```bash +./vendor/bin/drush eu-oss:generate-translation-job SOLUTION_ID +``` + +Use the queue system to process translations retrieved from the eTranslation service: +```bash +./vendor/bin/drush queue:run tmgmt_ec_etranslation_translation +``` -- GitLab From e41b7131c07527700aa2f2ce3c4819bdad8e7ae8 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 15:27:30 +0200 Subject: [PATCH 105/149] ISAICP-9003: Trigger a new event type. --- .../eu_oss_catalogue/src/EuOssCatalogue.php | 4 ++ .../src/Event/EuOssSolutionPostSaveEvent.php | 12 ++++++ .../src/Event/EuOssSolutionPreSaveEvent.php | 29 +------------- .../src/Event/EuOssSolutionSaveEventBase.php | 39 +++++++++++++++++++ 4 files changed, 56 insertions(+), 28 deletions(-) create mode 100644 web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPostSaveEvent.php create mode 100644 web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionSaveEventBase.php diff --git a/web/modules/custom/eu_oss_catalogue/src/EuOssCatalogue.php b/web/modules/custom/eu_oss_catalogue/src/EuOssCatalogue.php index 111506fefb..af9300fb8d 100644 --- a/web/modules/custom/eu_oss_catalogue/src/EuOssCatalogue.php +++ b/web/modules/custom/eu_oss_catalogue/src/EuOssCatalogue.php @@ -12,6 +12,7 @@ use Drupal\Core\Utility\Error; use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; use Drupal\eu_oss_catalogue\Event\EuOssPostFetchEvent; +use Drupal\eu_oss_catalogue\Event\EuOssSolutionPostSaveEvent; use Drupal\eu_oss_catalogue\Event\EuOssSolutionPreSaveEvent; use Drupal\eu_oss_catalogue\Exception\HostingPlatformFetchException; use Drupal\eu_oss_catalogue\Model\Project; @@ -193,6 +194,9 @@ public function createOrUpdateSolution(string $providerPluginId, Project $projec $solution->set('oss_archived', 0); $operationResult = $solution->save(); + + // Allow 3rd-party to act after save. + $this->eventDispatcher->dispatch(new EuOssSolutionPostSaveEvent($solution, $project)); } catch (\Exception $exception) { // The solution could not be saved. diff --git a/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPostSaveEvent.php b/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPostSaveEvent.php new file mode 100644 index 0000000000..a0fe53e083 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPostSaveEvent.php @@ -0,0 +1,12 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_catalogue\Event; + +/** + * Event triggered just after a fetched solution is saved as node. + */ +class EuOssSolutionPostSaveEvent extends EuOssSolutionSaveEventBase { + +} diff --git a/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPreSaveEvent.php b/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPreSaveEvent.php index da57d581ee..93165fbfc1 100644 --- a/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPreSaveEvent.php +++ b/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionPreSaveEvent.php @@ -4,36 +4,9 @@ namespace Drupal\eu_oss_catalogue\Event; -use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; -use Drupal\eu_oss_catalogue\Model\Project; -use Symfony\Contracts\EventDispatcher\Event; - /** * Event triggered just before a fetched solution is saved as node. */ -class EuOssSolutionPreSaveEvent extends Event { - - /** - * Constructs a new event instance. - * - * @param \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface $solution - * The OSS Solution node entity. - * @param \Drupal\eu_oss_catalogue\Model\Project $project - * The project value object. - */ - public function __construct( - protected OssSolutionInterface $solution, - public readonly Project $project, - ) {} - - /** - * Returns the OSS Solution node entity. - * - * @return \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface - * The OSS Solution node entity. - */ - public function getSolution(): OssSolutionInterface { - return $this->solution; - } +class EuOssSolutionPreSaveEvent extends EuOssSolutionSaveEventBase { } diff --git a/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionSaveEventBase.php b/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionSaveEventBase.php new file mode 100644 index 0000000000..e2d38c74ec --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/src/Event/EuOssSolutionSaveEventBase.php @@ -0,0 +1,39 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_catalogue\Event; + +use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; +use Drupal\eu_oss_catalogue\Model\Project; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * Base class for save event. + */ +abstract class EuOssSolutionSaveEventBase extends Event { + + /** + * Constructs a new event instance. + * + * @param \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface $solution + * The OSS Solution node entity. + * @param \Drupal\eu_oss_catalogue\Model\Project $project + * The project value object. + */ + public function __construct( + protected OssSolutionInterface $solution, + public readonly Project $project, + ) {} + + /** + * Returns the OSS Solution node entity. + * + * @return \Drupal\eu_oss_catalogue\Entity\OssSolutionInterface + * The OSS Solution node entity. + */ + public function getSolution(): OssSolutionInterface { + return $this->solution; + } + +} -- GitLab From b7f939fd3b6d843463a435ed98ab8490170221aa Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 17 Sep 2024 15:28:35 +0200 Subject: [PATCH 106/149] ISAICP-9003: Queue solution after fetching. --- .../modules/eu_oss_translation/README.md | 5 +++ .../eu_oss_translation.services.yml | 6 +++ .../SolutionPostSaveSubscriber.php | 40 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md index 74dc2c1324..ce168bc23e 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/README.md @@ -20,6 +20,11 @@ Run the following, to create translation job: ./vendor/bin/drush eu-oss:generate-translation-job SOLUTION_ID ``` +Use the queue system to trigger a translation job creation for all updated/created solutions: +```bash +./vendor/bin/drush queue:run eu_oss_translation_requester +``` + Use the queue system to process translations retrieved from the eTranslation service: ```bash ./vendor/bin/drush queue:run tmgmt_ec_etranslation_translation diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml index 5d509acc85..4ccf184a01 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml @@ -6,3 +6,9 @@ services: - '@entity_type.manager' - '@logger.channel.eu_oss_catalogue' - '@config.factory' + + eu_oss_translation.solution_post_save_subscriber: + class: Drupal\eu_oss_translation\EventSubscriber\SolutionPostSaveSubscriber + arguments: [ '@queue' ] + tags: + - { name: event_subscriber } diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php new file mode 100644 index 0000000000..c9de3d7ad3 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php @@ -0,0 +1,40 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_translation\EventSubscriber; + +use Drupal\Core\Queue\QueueFactory; +use Drupal\eu_oss_catalogue\Event\EuOssSolutionPostSaveEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Solution post save. + */ +class SolutionPostSaveSubscriber implements EventSubscriberInterface { + + public function __construct( + protected QueueFactory $queue, + ) {} + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents(): array { + return [ + EuOssSolutionPostSaveEvent::class => ['postSave'], + ]; + } + + /** + * Queue after solution was fetched. + */ + public function postSave(EuOssSolutionPostSaveEvent $event): void { + $solution = $event->getSolution(); + + $queue = $this->queue->get('eu_oss_translation_requester'); + $queue->createQueue(); + $queue->createItem(['nid' => $solution->id()]); + } + +} -- GitLab From 50183e8f91c5fb5a1bbc459b7e72e2da18fa3a54 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Tue, 17 Sep 2024 17:17:08 +0300 Subject: [PATCH 107/149] ISAICP-9059: Comment lefover. --- .../tests/src/ExistingSite/JoinupExistingSiteTestBase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php b/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php index 670c39c78c..7a0eee15fe 100644 --- a/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php +++ b/web/modules/custom/joinup_test/tests/src/ExistingSite/JoinupExistingSiteTestBase.php @@ -72,7 +72,6 @@ public function tearDown(): void { // Cleanup the cas mock server. \Drupal::getContainer()->get('cas_mock_server.user_manager')->deleteUsers($this->casUsers); - // The parent method might cleanup config entities. parent::tearDown(); // Delete the OG group content orphans now because parent::tearDown() is -- GitLab From 14a597b09c818ea2fffd6301c30acf1c34d97997 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 18 Sep 2024 11:30:41 +0200 Subject: [PATCH 108/149] ISAICP-9003: Translate functionality. --- .../eu_oss_translation.module | 34 +++++++++++++++++++ .../eu_oss_translation/src/JobBuilder.php | 7 +++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module new file mode 100644 index 0000000000..865027e3be --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module @@ -0,0 +1,34 @@ +<?php + +/** + * @file + * Hook implementations for EU OSS Translation module. + */ + +declare(strict_types=1); + +use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; +use Drupal\eu_oss_translation\JobBuilder; + +/** + * Implements hook_tmgmt_translatable_fields_alter(). + */ +function eu_oss_translation_tmgmt_translatable_fields_alter(ContentEntityInterface $entity, array &$translatableFields): void { + if (!$entity instanceof OssSolutionInterface || !$entity->hasTranslation(JobBuilder::TARGET_LANGUAGE)) { + return; + } + + $translated = $entity->getTranslation(JobBuilder::TARGET_LANGUAGE); + + // Skip already translated data. + foreach ($translatableFields as $translatableKey => $translatableField) { + if (!$translated->hasField($translatableKey)) { + continue; + } + + if (!$translated->get($translatableKey)->isEmpty()) { + unset($translatableFields[$translatableKey]); + } + } +} diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php index 134d05f3e1..b81df05136 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php @@ -19,7 +19,7 @@ class JobBuilder implements JobBuilderInterface { /** * Target language. */ - const string TARGET_LANGUAGE = 'en'; + public const string TARGET_LANGUAGE = 'en'; /** * Module config. @@ -102,6 +102,11 @@ protected function createJob(OssSolutionInterface $entity): void { $item = $job->addItem('content', $entity->getEntityTypeId(), $entity->id()); $item->save(); + $canRequest = $job->canRequestTranslation(); + if (!$canRequest->getSuccess()) { + throw new \Exception($canRequest->getReason()); + } + $job->requestTranslation(); } catch (\Exception $e) { -- GitLab From 054760b3519af84854605a0a322b719a200dd4f2 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 18 Sep 2024 14:08:15 +0200 Subject: [PATCH 109/149] ISAICP-9003: addItem automatic saves entities. --- .../modules/eu_oss_translation/src/JobBuilder.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php index b81df05136..4722432e81 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php @@ -97,10 +97,7 @@ protected function createJob(OssSolutionInterface $entity): void { 'translator' => $this->config->get('translator'), ] ); - $job->save(); - - $item = $job->addItem('content', $entity->getEntityTypeId(), $entity->id()); - $item->save(); + $job->addItem('content', $entity->getEntityTypeId(), $entity->id()); $canRequest = $job->canRequestTranslation(); if (!$canRequest->getSuccess()) { -- GitLab From 107615401bc57de5978dfefb9d2f09507cb8becf Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Wed, 18 Sep 2024 16:19:58 +0200 Subject: [PATCH 110/149] ISAICP-9003: Add dummy test. --- .../src/Functional/AutoTranslationTest.php | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php new file mode 100644 index 0000000000..477faecf6f --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php @@ -0,0 +1,53 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\eu_oss_translation\Functional; + +use Drupal\Tests\eu_oss_catalogue\Functional\FetchTestBase; + +/** + * Tests auto translation . + * + * @group eu_oss_catalogue + * @group eu_oss_translation + */ +class AutoTranslationTest extends FetchTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'tmgmt', + 'tmgmt_content', + 'tmgmt_ec_etranslation', + 'tmgmt_ec_etranslation_test', + 'http_request_mock', + 'editor', + 'eu_oss_catalogue_test', + 'language', + ]; + + /** + * {@inheritdoc} + */ + protected array $controlledVocabTerms = [ + 'oss_licence' => ['AGPL-3.0-or-later', 'BSD-3-Clause', 'EUPL-1.2', 'MIT'], + 'oss_category' => [ + 'data-analytics', + 'data-collection', + 'digital-citizenship', + 'nothing', + 'website-builder', + ], + ]; + + /** + * @covers + */ + public function testJobCreation(): void { + $this->fetchSolutions('developers_italia', 5); + $this->fail('fail message'); + } + +} -- GitLab From 06b7588080fce2bdd9d9deab315a66bbe3e644f9 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 08:51:25 +0200 Subject: [PATCH 111/149] ISAICP-9003: Perform tests inside submodules. --- phpunit.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpunit.xml b/phpunit.xml index f5b86614d9..23a353ae00 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -51,15 +51,19 @@ <testsuites> <testsuite name="unit"> <directory>web/modules/custom/**/tests/src/Unit</directory> + <directory>web/modules/custom/**/modules/**/tests/src/Unit</directory> <directory>web/profiles/joinup/tests/src/Unit</directory> </testsuite> <testsuite name="kernel"> <directory>web/modules/custom/**/tests/src/Kernel</directory> + <directory>web/modules/custom/**/modules/**/tests/src/Kernel</directory> <!-- WIP --> <exclude>web/modules/custom/joinup_stats/tests/src/Kernel/RefreshCountersTest.php</exclude> </testsuite> <testsuite name="functional"> <directory>web/modules/custom/**/tests/src/Functional</directory> + <directory>web/modules/custom/**/modules/**/tests/src/Functional + </directory> </testsuite> <testsuite name="existing-site"> <directory>web/modules/custom/**/tests/src/ExistingSite</directory> -- GitLab From b9f504f5f90d5416a27d35cbfd0772af08aa438c Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 11:32:16 +0200 Subject: [PATCH 112/149] ISAICP-9003: Fix type issue. --- .../modules/eu_oss_translation/src/JobBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php index 4722432e81..42099b61a8 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php @@ -101,7 +101,7 @@ protected function createJob(OssSolutionInterface $entity): void { $canRequest = $job->canRequestTranslation(); if (!$canRequest->getSuccess()) { - throw new \Exception($canRequest->getReason()); + throw new \Exception((string) $canRequest->getReason()); } $job->requestTranslation(); -- GitLab From e247cadc629e64b9da99266d613658fdc964b88d Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 13:06:17 +0200 Subject: [PATCH 113/149] ISAICP-9003: Allow translating from DE AND IT to EN. --- .../eu_oss_translation_test.info.yml | 9 ++++ .../ServiceMock/EuOssETranslationMock.php | 46 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/src/Plugin/ServiceMock/EuOssETranslationMock.php diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml new file mode 100644 index 0000000000..82236fa9a3 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml @@ -0,0 +1,9 @@ +name: 'EU OSS Translation Test' +type: module +description: 'Test module to mock eTranslation service.' +core_version_requirement: ^9 || ^10 +package: Testing +dependencies: + - drupal:tmgmt + - drupal:tmgmt_ec_etranslation + - http_request_mock:http_request_mock diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/src/Plugin/ServiceMock/EuOssETranslationMock.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/src/Plugin/ServiceMock/EuOssETranslationMock.php new file mode 100644 index 0000000000..eeb727486c --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/src/Plugin/ServiceMock/EuOssETranslationMock.php @@ -0,0 +1,46 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_translation_test\Plugin\ServiceMock; + +use Drupal\Component\Serialization\Json; +use Drupal\tmgmt_ec_etranslation_test\Plugin\ServiceMock\ETranslationMock; +use GuzzleHttp\Psr7\Response; +use Psr\Http\Message\ResponseInterface; + +/** + * Intercepts any HTTP requests made to eTranslation API. + * + * @ServiceMock( + * id = "eu_oss_etranslation", + * label = @Translation("EU OSS eTranslation API"), + * weight = -1, + * ) + */ +class EuOssETranslationMock extends ETranslationMock { + + /** + * Provides response for the get-domains endpoint. + * + * @return \Psr\Http\Message\ResponseInterface + * Response with domains. + */ + protected function getDomains(): ResponseInterface { + $data = Json::encode([ + 'SPD' => [ + 'name' => 'EU Formal Language', + 'languagePairs' => [ + 'DE-EN', + 'IT-EN', + ], + ], + ]); + + return new Response(200, [ + 'Content-Type' => 'application/json', + 'Content-Length' => strlen($data), + ], $data); + } + +} -- GitLab From 586991850efeeb3fbee22509291ff3d2cc223de2 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 13:10:54 +0200 Subject: [PATCH 114/149] ISAICP-9003: Add ec_etranslation provider. --- .../tmgmt.translator.ec_etranslation.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/install/tmgmt.translator.ec_etranslation.yml diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/install/tmgmt.translator.ec_etranslation.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/install/tmgmt.translator.ec_etranslation.yml new file mode 100644 index 0000000000..e28274ab45 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/install/tmgmt.translator.ec_etranslation.yml @@ -0,0 +1,17 @@ +langcode: en +status: true +dependencies: + module: + - tmgmt_ec_etranslation +name: ec_etranslation +label: 'European Commission eTranslation' +description: "Allows the European Commission's eTranslation service to process translation jobs." +auto_accept: true +weight: null +plugin: ec_etranslation +settings: + username: 'dummy-username' + password: 'dummy-password' + domain: SPD + email: '' +remote_languages_mappings: { } -- GitLab From ef41b8018baf41fc8e96c3bc83e3fbee6b8854e5 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 13:56:09 +0200 Subject: [PATCH 115/149] ISAICP-9003: Use variable as a queue id. --- .../src/EventSubscriber/SolutionPostSaveSubscriber.php | 3 ++- .../src/Plugin/QueueWorker/TranslationRequester.php | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php index c9de3d7ad3..4f420f6bca 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/EventSubscriber/SolutionPostSaveSubscriber.php @@ -6,6 +6,7 @@ use Drupal\Core\Queue\QueueFactory; use Drupal\eu_oss_catalogue\Event\EuOssSolutionPostSaveEvent; +use Drupal\eu_oss_translation\Plugin\QueueWorker\TranslationRequester; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -32,7 +33,7 @@ public static function getSubscribedEvents(): array { public function postSave(EuOssSolutionPostSaveEvent $event): void { $solution = $event->getSolution(); - $queue = $this->queue->get('eu_oss_translation_requester'); + $queue = $this->queue->get(TranslationRequester::ID); $queue->createQueue(); $queue->createItem(['nid' => $solution->id()]); } diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php index 07a6d6d7fa..901b17d984 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php @@ -15,13 +15,18 @@ * Defines 'eu_oss_translation_requester' queue worker. * * @QueueWorker( - * id = "eu_oss_translation_requester", + * id = \Drupal\eu_oss_translation\Plugin\QueueWorker\TranslationRequester::ID, * title = @Translation("Translation requester"), * cron = {"time" = 60}, * ) */ class TranslationRequester extends QueueWorkerBase implements ContainerFactoryPluginInterface { + /** + * Queue id. + */ + public const string ID = 'eu_oss_translation_requester'; + public function __construct( array $configuration, string $plugin_id, -- GitLab From b9c2616ef7987dc36a7b729f92ea2bab8b9884af Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 15:26:03 +0200 Subject: [PATCH 116/149] ISAICP-9003: Allow to overwrite dir. --- .../tests/src/Functional/FetchTestBase.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/tests/src/Functional/FetchTestBase.php b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/FetchTestBase.php index fa62de6827..df2ade2985 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/src/Functional/FetchTestBase.php +++ b/web/modules/custom/eu_oss_catalogue/tests/src/Functional/FetchTestBase.php @@ -49,6 +49,11 @@ abstract class FetchTestBase extends BrowserTestBase { */ protected array $controlledVocabTerms = []; + /** + * Module dir. + */ + public ?string $dir = NULL; + /** * {@inheritdoc} */ @@ -71,6 +76,8 @@ protected function setUp(): void { // Add Italian and German languages. ConfigurableLanguage::createFromLangcode('it')->save(); ConfigurableLanguage::createFromLangcode('de')->save(); + + $this->dir = __DIR__; } /** @@ -121,7 +128,7 @@ protected function getNode(string $nodeTitle, string $interface): OssSolutionInt // The first trace entry (0) is this method, the second (1) is its caller, // which is an assertion. The third (2) is the test method. $parts = explode('\\', $trace[2]['class']); - $filePath = __DIR__ . '/../../fixtures/expectancy/' . array_pop($parts) . '.' . $trace[2]['function'] . '.yml'; + $filePath = $this->dir . '/../../fixtures/expectancy/' . array_pop($parts) . '.' . $trace[2]['function'] . '.yml'; $this->assertFileExists($filePath); $expected = Yaml::decode(file_get_contents($filePath))[$nodeTitle]; $this->assertIsArray($expected); -- GitLab From af75ad502b48e66b9e9c375be0cea9fbd3dbc903 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 15:31:45 +0200 Subject: [PATCH 117/149] ISAICP-9003: Copy of developers_italia. --- .../AutoTranslationTest.testTranslation.yml | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml new file mode 100644 index 0000000000..acd374e2cd --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml @@ -0,0 +1,283 @@ +GitHub solution 1: + en: + langcode: en + default_langcode: '1' + status: '1' + oss_available_languages: + - it + - en + - de + oss_categories: + - digital-citizenship + oss_development_status: stable + oss_git_url: https://github.com/dummy-namespace-1/dummy-name-1 + oss_license: AGPL-3.0-or-later + oss_logo: https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/images/logo-solution-1.png + oss_git_forks: 103 + oss_git_stars: 123 + oss_git_open_issues: 143 + oss_maintenance_contacts: + - Peter Gregory + oss_maintenance_contractors: + - ACME Ltd + - Das Auto GmbH + oss_maintenance_type: contract + oss_owner: Sin City + oss_platforms: + - web + oss_publiccode_yml_version: '0.2' + oss_release_date: '2017-05-01' + oss_software_type: standalone/web + oss_software_version: '1.4' + oss_source: + - developers_italia + oss_source_hash: _RnRGlJcP5QA_tiadP_JTMJyyOypigHzRYjIY-LlQMM + oss_long_description: | + [EN] Solution 1: Long description + **Some bold text** + * Some list item + * Another list item + + _Some italic text_ + oss_short_description: '[EN] Solution 1: **Short description**' + oss_features: + - '[EN] Solution 1: Feature 1' + - '[EN] Solution 1: Feature 2' + - '[EN] Solution 1: Feature 3' + oss_screenshots: + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_EN_Screenshot1.jpg + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_EN_Screenshot2.jpg + oss_git_open_pull_requests: 3 + de: + langcode: de + default_langcode: '0' + oss_features: + - '[DE] Solution 1: Feature 1' + oss_long_description: | + [DE] Solution 1: Long description + **Some bold text** + * Some list item + * Another list item + + _Some italic text_ + oss_short_description: '[DE] Solution 1: **Short description**' + oss_screenshots: + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_DE_Screenshot1.jpg + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_DE_Screenshot3.jpg + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_DE_Screenshot4.jpg + it: + langcode: it + default_langcode: '0' + oss_features: + - '[IT] Solution 1: Feature 1' + - '[IT] Solution 1: Feature 2' + oss_long_description: | + [IT] Solution 1: Long description + **Some bold text** + * Some list item + * Another list item + + _Some italic text_ + oss_short_description: '[IT] Solution 1: **Short description**' + oss_screenshots: + - https://raw.githubusercontent.com/dummy-namespace-1/dummy-name-1/HEAD/Solution_1_IT_Screenshot1.jpg + +Project 1.1: + it: + langcode: it + default_langcode: '0' + oss_categories: + - data-collection + oss_git_url: https://limited.self-hosted.gitlab.example.com/group1/project-1-1 + oss_git_description: 'Group 1: Project 1: description' + oss_default_branch: branch-project-1-1 + oss_software_version: '2.0.0-alpha12' + oss_release_date: '2010-07-08' + oss_platform_reference: gid://gitlab/Project/11 + oss_logo: https://limited.self-hosted.gitlab.example.com/group1/project-1-1/raw/HEAD/images/logo-of-project-1-1.svg + oss_git_forks: 206 + oss_git_stars: 226 + oss_git_open_issues: 246 + oss_publiccode_yml_version: '0.2' + oss_documentation: https://example.com/group1/project-1-1/it/docs.md + oss_features: + - '[IT] feat 1' + - '[IT] feat 2' + - '[IT] feat 3' + oss_long_description: '[IT] Group1: Project 1: Long description' + oss_short_description: '[IT] Group1: Project 1: Short description' + oss_screenshots: + - 'https://limited.self-hosted.gitlab.example.com/group1/project-1-1/raw/HEAD/Group_1_Project1_IT_Screenshot.jpg' + oss_git_open_pull_requests: 32 + de: + langcode: de + oss_documentation: https://example.com/group1/project-1-1/de/docs.md + oss_features: + - '[DE] feat 1' + - '[DE] feat 2' + oss_long_description: '[DE] Group1: Project 1: Long description' + oss_short_description: '[DE] Group1: Project 1: Short description' + +Project 1.2: + de: + langcode: de + default_langcode: '0' + oss_categories: + - data-collection + - data-analytics + oss_git_url: https://limited.self-hosted.gitlab.example.com/group1/project-1-2 + oss_git_description: 'Group 1: Project 2: description' + oss_default_branch: branch-project-1-2 + oss_software_version: '220.0.1' + oss_release_date: '2013-08-19' + oss_platform_reference: gid://gitlab/Project/12 + oss_logo: https://all.self-hosted.gitlab.example.com/uploads/-/system/project/avatar/12/logo.jpg + oss_git_forks: 207 + oss_git_stars: 227 + oss_git_open_issues: 247 + oss_publiccode_yml_version: '0.2' + oss_documentation: https://example.com/group1/project-1-2/de/docs.md + oss_features: + - '[DE] feat 1' + - '[DE] feat 2' + oss_long_description: '[DE] Group1: Project 2: Long description' + oss_short_description: '[DE] Group1: Project 2: Short description' + oss_git_open_pull_requests: 2 + it: + langcode: it + default_langcode: '0' + oss_documentation: https://example.com/group1/project-1-2/it/docs.md + oss_features: + - '[IT] feat 1' + - '[IT] feat 2' + oss_long_description: '[IT] Group1: Project 2: Long description' + oss_short_description: '[IT] Group1: Project 2: Short description' + en: + langcode: en + default_langcode: '1' + oss_documentation: https://example.com/group1/project-1-2/en/docs.md + oss_features: + - '[EN] feat 1' + oss_long_description: '[EN] Group1: Project 2: Long description' + oss_short_description: '[EN] Group1: Project 2: Short description' + oss_used_by: + - 'Abbanoa' + - 'abbanoa' + - 'abbanoa ' + - 'Comune Di Malè' + - 'Comune Di Male' + - 'comune di male' + +Project 1.4: + de: + langcode: de + default_langcode: '0' + oss_categories: + - data-collection + - data-analytics + oss_git_url: https://limited.self-hosted.gitlab.example.com/group1/project-1-4 + oss_git_description: 'Group 1: Project 4: description' + oss_default_branch: branch-project-1-4 + oss_software_version: '220.0.9' + oss_release_date: '2013-08-19' + oss_platform_reference: gid://gitlab/Project/4 + oss_git_forks: 209 + oss_git_stars: 229 + oss_git_open_issues: 249 + oss_publiccode_yml_version: '0.2' + oss_documentation: https://example.com/group1/project-1-4/de/docs.md + oss_features: + - '[DE] feat 4' + oss_long_description: '[DE] Group1: Project 4: Long description' + oss_short_description: '[DE] Group1: Project 4: Short description' + oss_git_open_pull_requests: 9 + +GitHub solution 2: + en: + langcode: en + status: '1' + oss_available_languages: + - it + oss_categories: + - website-builder + oss_development_status: development + oss_git_url: https://limited.self-hosted.gitlab.example.com/group1/project-1-1 + oss_landing_url: https://example.com/group1/project-1-1 + oss_license: BSD-3-Clause + oss_maintenance_contacts: + - FOSS Conference + - Pirate Initiative + oss_maintenance_type: community + oss_owner: Narnia + oss_platforms: + - web + oss_publiccode_yml_version: '0.2' + oss_release_date: '2023-02-09' + oss_scope: + - energy + - research + - science-and-technology + - security + oss_software_type: library + oss_software_version: 'v2.3.4' + oss_source: + - developers_italia + oss_source_hash: 'WWiM57kppAUvDQdo2IiW1C9qh_Jdfzm8daYXeeS9IzU' + oss_git_open_pull_requests: 0 + it: + langcode: it + default_langcode: '0' + oss_features: + - '[IT] Solution 2: Feature 1' + - '[IT] Solution 2: Feature 2' + - '[IT] Solution 2: Feature 3' + - '[IT] Solution 2: Feature 4' + oss_long_description: | + [IT] Solution 2: Long description Lorem ipsum dolor sit amet, consectetur + adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna + aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi + ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in + voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim + id est laborum. + oss_short_description: '[IT] Solution 2: **Short description Lorem ipsum**' + oss_documentation: http://it.docs.example.com/vendor/solution2 + status: '1' + oss_available_languages: + - it + oss_categories: + - website-builder + oss_development_status: development + oss_git_url: https://limited.self-hosted.gitlab.example.com/group1/project-1-1 + oss_landing_url: https://example.com/group1/project-1-1 + oss_license: BSD-3-Clause + oss_maintenance_contacts: + - FOSS Conference + - Pirate Initiative + oss_maintenance_type: community + oss_owner: Narnia + oss_platforms: + - web + oss_publiccode_yml_version: '0.2' + oss_release_date: '2023-02-09' + oss_scope: + - energy + - research + - science-and-technology + - security + oss_software_type: library + oss_software_version: 'v2.3.4' + oss_source: + - developers_italia + oss_source_hash: 'WWiM57kppAUvDQdo2IiW1C9qh_Jdfzm8daYXeeS9IzU' + +Project 1: + en: + oss_git_url: https://limited.self-hosted.gitlab.example.com/user1/project-1 + oss_git_description: 'User 1: Project 1: description' + oss_default_branch: branch-project-1 + oss_software_version: '1.0.x-dev' + oss_release_date: '2020-10-22' + oss_platform_reference: gid://gitlab/Project/1 + oss_publiccode_yml_version: '0.2' + oss_git_open_pull_requests: 1 -- GitLab From c1941d1b3dbe12261ffe6f4ea110266c3913461b Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 16:07:25 +0200 Subject: [PATCH 118/149] ISAICP-9003: Improve logic. --- .../eu_oss_translation/eu_oss_translation.module | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module index 865027e3be..06856ce610 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.module @@ -19,15 +19,22 @@ function eu_oss_translation_tmgmt_translatable_fields_alter(ContentEntityInterfa return; } - $translated = $entity->getTranslation(JobBuilder::TARGET_LANGUAGE); + $source = $entity->getTranslation($entity->getRelevantLangCode()); + $target = $entity->getTranslation(JobBuilder::TARGET_LANGUAGE); // Skip already translated data. foreach ($translatableFields as $translatableKey => $translatableField) { - if (!$translated->hasField($translatableKey)) { + if (!$target->hasField($translatableKey)) { continue; } - if (!$translated->get($translatableKey)->isEmpty()) { + // If the source language field is empty, there is nothing to translate. + if ($source->get($translatableKey)->isEmpty()) { + unset($translatableFields[$translatableKey]); + } + + // The field in the target language is already set. + if (!$target->get($translatableKey)->isEmpty()) { unset($translatableFields[$translatableKey]); } } -- GitLab From ef22e48317549af24137121ba0ca0c97f77fc080 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 16:09:22 +0200 Subject: [PATCH 119/149] ISAICP-9003: Compare translated languages. --- .../AutoTranslationTest.testTranslation.yml | 18 +++ .../src/Functional/AutoTranslationTest.php | 117 ++++++++++++++++-- 2 files changed, 128 insertions(+), 7 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml index acd374e2cd..a37b364171 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/fixtures/expectancy/AutoTranslationTest.testTranslation.yml @@ -117,6 +117,14 @@ Project 1.1: - '[DE] feat 2' oss_long_description: '[DE] Group1: Project 1: Long description' oss_short_description: '[DE] Group1: Project 1: Short description' + en: + langcode: en + oss_features: + - '[IT] feat 1 it en' + - '[IT] feat 2 it en' + - '[IT] feat 3 it en' + oss_long_description: '[IT] Group1: Project 1: Long description it en' + oss_short_description: '[IT] Group1: Project 1: Short description it en' Project 1.2: de: @@ -191,6 +199,12 @@ Project 1.4: oss_long_description: '[DE] Group1: Project 4: Long description' oss_short_description: '[DE] Group1: Project 4: Short description' oss_git_open_pull_requests: 9 + en: + langcode: en + oss_features: + - '[DE] feat 4 de en' + oss_long_description: '[DE] Group1: Project 4: Long description de en' + oss_short_description: '[DE] Group1: Project 4: Short description de en' GitHub solution 2: en: @@ -281,3 +295,7 @@ Project 1: oss_platform_reference: gid://gitlab/Project/1 oss_publiccode_yml_version: '0.2' oss_git_open_pull_requests: 1 + oss_features: + - 'nada de en' + oss_long_description: '[DE] User 1: Project 1: Long description de en' + oss_short_description: '[DE] User 1: Project 1: Short description de en' diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php index 477faecf6f..e499fb8fe5 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php @@ -4,28 +4,68 @@ namespace Drupal\Tests\eu_oss_translation\Functional; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Queue\QueueFactory; +use Drupal\Core\Queue\QueueInterface; +use Drupal\Core\Queue\QueueWorkerInterface; +use Drupal\Core\Queue\QueueWorkerManagerInterface; +use Drupal\eu_oss_translation\Plugin\QueueWorker\TranslationRequester; use Drupal\Tests\eu_oss_catalogue\Functional\FetchTestBase; +use Drupal\tmgmt\TranslatorInterface; +use Drupal\tmgmt_ec_etranslation\Plugin\QueueWorker\TranslationQueueWorker; /** - * Tests auto translation . + * Tests auto translation. * * @group eu_oss_catalogue * @group eu_oss_translation */ class AutoTranslationTest extends FetchTestBase { + /** + * The translator plugin. + * + * @var \Drupal\tmgmt\TranslatorInterface + */ + protected TranslatorInterface $translator; + + /** + * The queue factory. + * + * @var \Drupal\Core\Queue\QueueFactory + */ + protected QueueFactory $queueFactory; + + /** + * Queue worker. + * + * @var \Drupal\Core\Queue\QueueWorkerManagerInterface + */ + protected QueueWorkerManagerInterface $queueWorkerManager; + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected EntityTypeManagerInterface $entityTypeManager; + /** * {@inheritdoc} */ protected static $modules = [ + 'dblog', + 'editor', + 'eu_oss_catalogue_test', + 'language', + 'markdown_easy', 'tmgmt', 'tmgmt_content', 'tmgmt_ec_etranslation', 'tmgmt_ec_etranslation_test', 'http_request_mock', - 'editor', - 'eu_oss_catalogue_test', - 'language', + 'eu_oss_translation', + 'eu_oss_translation_test', ]; /** @@ -40,14 +80,77 @@ class AutoTranslationTest extends FetchTestBase { 'nothing', 'website-builder', ], + 'oss_software_type' => [ + 'standalone/other', + ], ]; /** - * @covers + * {@inheritdoc} */ - public function testJobCreation(): void { + protected function setUp(): void { + parent::setUp(); + $this->queueFactory = $this->container->get('queue'); + $this->queueWorkerManager = $this->container->get('plugin.manager.queue_worker'); + $this->entityTypeManager = $this->container->get('entity_type.manager'); + + // Overwrite directory. + $this->dir = __DIR__; + } + + /** + * Tests translation. + */ + public function testTranslation(): void { + $jobBuilderWorker = $this->queueWorkerManager->createInstance(TranslationRequester::ID); + $jobBuilderQueue = $this->queueFactory->get(TranslationRequester::ID); + + $tmgProviderWorker = $this->queueWorkerManager->createInstance(TranslationQueueWorker::ID); + $tmgProviderQueue = $this->queueFactory->get(TranslationQueueWorker::ID); + $this->fetchSolutions('developers_italia', 5); - $this->fail('fail message'); + + $this->assertEquals(5, $jobBuilderQueue->numberOfItems()); + $this->processQueue($jobBuilderWorker, $jobBuilderQueue, 5); + $this->assertEquals(0, $jobBuilderQueue->numberOfItems()); + + $this->assertEquals(11, $tmgProviderQueue->numberOfItems()); + $this->processQueue($tmgProviderWorker, $tmgProviderQueue, 11); + $this->assertEquals(0, $tmgProviderQueue->numberOfItems()); + + $this->entityTypeManager->getStorage('node')->resetCache(); + + $this->assertOssSolution('GitHub solution 1', 'en'); + $this->assertOssSolution('Project 1.1', 'it'); + $this->assertOssSolution('Project 1.2', 'de'); + $this->assertOssSolution('Project 1.4', 'de'); + $this->assertOssSolution('Project 1', 'de'); + } + + /** + * Processes queue. + * + * @param \Drupal\Core\Queue\QueueWorkerInterface $queueWorker + * Queue worker. + * @param \Drupal\Core\Queue\QueueInterface $queue + * Queue. + * @param int $limit + * Limit of queue elements. + */ + protected function processQueue(QueueWorkerInterface $queueWorker, QueueInterface $queue, int $limit = 100): void { + $processed = 0; + while (($item = $queue->claimItem()) && $limit > $processed) { + try { + $queueWorker->processItem($item->data); + $queue->deleteItem($item); + } + catch (\Exception $e) { + $queue->releaseItem($item); + throw $e; + } + + $processed++; + } } } -- GitLab From bdfdb70b79ba164260e5e95d23258e56410e1c86 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 16:10:09 +0200 Subject: [PATCH 120/149] ISAICP-9003: Improve code standards. --- .../tests/src/Functional/AutoTranslationTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php index e499fb8fe5..ab8fc8e007 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php @@ -9,8 +9,8 @@ use Drupal\Core\Queue\QueueInterface; use Drupal\Core\Queue\QueueWorkerInterface; use Drupal\Core\Queue\QueueWorkerManagerInterface; -use Drupal\eu_oss_translation\Plugin\QueueWorker\TranslationRequester; use Drupal\Tests\eu_oss_catalogue\Functional\FetchTestBase; +use Drupal\eu_oss_translation\Plugin\QueueWorker\TranslationRequester; use Drupal\tmgmt\TranslatorInterface; use Drupal\tmgmt_ec_etranslation\Plugin\QueueWorker\TranslationQueueWorker; @@ -133,7 +133,7 @@ public function testTranslation(): void { * @param \Drupal\Core\Queue\QueueWorkerInterface $queueWorker * Queue worker. * @param \Drupal\Core\Queue\QueueInterface $queue - * Queue. + * Queue. * @param int $limit * Limit of queue elements. */ -- GitLab From edc1c3f648f588bed6045120ca1a1f2f898736e5 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 19 Sep 2024 16:38:59 +0200 Subject: [PATCH 121/149] ISAICP-9003: Limit the number of modules. --- .../tests/src/Functional/AutoTranslationTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php index ab8fc8e007..ec5d6354f7 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/src/Functional/AutoTranslationTest.php @@ -54,11 +54,8 @@ class AutoTranslationTest extends FetchTestBase { * {@inheritdoc} */ protected static $modules = [ - 'dblog', - 'editor', 'eu_oss_catalogue_test', 'language', - 'markdown_easy', 'tmgmt', 'tmgmt_content', 'tmgmt_ec_etranslation', -- GitLab From 6665e50a42c88b3e325f37072698c7f0bd8f614c Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 08:22:34 +0200 Subject: [PATCH 122/149] ISAICP-9003: Declare as optional. --- .../{install => optional}/tmgmt.translator.ec_etranslation.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/{install => optional}/tmgmt.translator.ec_etranslation.yml (100%) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/install/tmgmt.translator.ec_etranslation.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/optional/tmgmt.translator.ec_etranslation.yml similarity index 100% rename from web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/install/tmgmt.translator.ec_etranslation.yml rename to web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/config/optional/tmgmt.translator.ec_etranslation.yml -- GitLab From d8b76f994f9b209a7a4d5be13aeb55b5d6c7b821 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 08:33:05 +0200 Subject: [PATCH 123/149] ISAICP-9003: Make sure that contrib test module is enabled too. --- .../eu_oss_translation_test/eu_oss_translation_test.info.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml index 82236fa9a3..02d5402f86 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/tests/modules/eu_oss_translation_test/eu_oss_translation_test.info.yml @@ -7,3 +7,4 @@ dependencies: - drupal:tmgmt - drupal:tmgmt_ec_etranslation - http_request_mock:http_request_mock + - tmgmt_ec_etranslation:tmgmt_ec_etranslation_test -- GitLab From a1b971ff0c9d8fd7291bd723d270fe1401c108fa Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 09:15:44 +0200 Subject: [PATCH 124/149] ISAICP-9003: Limit creation of job which does not require any translations. --- .../eu_oss_translation.services.yml | 1 + .../eu_oss_translation/src/JobBuilder.php | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml index 4ccf184a01..b15b562b76 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/eu_oss_translation.services.yml @@ -5,6 +5,7 @@ services: - '@current_user' - '@entity_type.manager' - '@logger.channel.eu_oss_catalogue' + - '@plugin.manager.tmgmt.source' - '@config.factory' eu_oss_translation.solution_post_save_subscriber: diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php index 42099b61a8..f39d54524c 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/JobBuilder.php @@ -10,6 +10,8 @@ use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Session\AccountInterface; use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface; +use Drupal\tmgmt\SourceManager; +use Drupal\tmgmt_content\Plugin\tmgmt\Source\ContentEntitySource; /** * Job builder service. @@ -28,13 +30,22 @@ class JobBuilder implements JobBuilderInterface { */ protected ImmutableConfig $config; + /** + * Content source. + * + * @var \Drupal\tmgmt_content\Plugin\tmgmt\Source\ContentEntitySource + */ + protected ContentEntitySource $contentSource; + public function __construct( protected AccountInterface $currentUser, protected EntityTypeManagerInterface $entityTypeManager, protected LoggerChannelInterface $logger, + protected SourceManager $sourcePluginManager, ConfigFactoryInterface $configFactory, ) { $this->config = $configFactory->get('eu_oss_translation.settings'); + $this->contentSource = $this->sourcePluginManager->createInstance('content'); } /** @@ -75,7 +86,12 @@ protected function isBeingProcessed(OssSolutionInterface $entity): bool { * True if a node needs translation. */ protected function needsTranslation(OssSolutionInterface $entity): bool { - return $entity->getRelevantLangCode() !== self::TARGET_LANGUAGE; + if ($entity->getRelevantLangCode() === self::TARGET_LANGUAGE) { + return FALSE; + } + + $fields = $this->contentSource->extractTranslatableData($entity); + return !empty($fields); } /** -- GitLab From 79d4933586508f73ab2e78fd1f1b12c9a9faaca6 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 11:45:28 +0200 Subject: [PATCH 125/149] ISAICP-9063: WIP. --- .../QueueWorker/EuOssCatalogueFetcher.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php diff --git a/web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php b/web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php new file mode 100644 index 0000000000..cbf6bd8b32 --- /dev/null +++ b/web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php @@ -0,0 +1,50 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\eu_oss_catalogue\Plugin\QueueWorker; + +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Queue\QueueWorkerBase; +use Drupal\eu_oss_catalogue\EuOssCatalogueInterface; +use Drupal\eu_oss_catalogue\EuOssCataloguePluginManagerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Consumes the 'eu_oss_catalogue' queue. + * + * @QueueWorker( + * id = "eu_oss_catalogue_fetcher", + * title = @Translation("EU OSS Catalogue fetcher"), + * cron = {"time" = 10}, + * ) + */ +class EuOssCatalogueFetcher extends QueueWorkerBase implements ContainerFactoryPluginInterface { + + public function __construct( + array $configuration, + $pluginId, + $pluginDefinition, + protected EuOssCataloguePluginManagerInterface $providerPluginManager, + ) { + parent::__construct($configuration, $pluginId, $pluginDefinition); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('plugin.manager.eu_oss_catalogue.provider'), + ); + } + + /** + * {@inheritdoc} + */ + public function processItem($data): void {} + +} -- GitLab From e9db271f79cb1f3939814d003cfa53a437d4e7aa Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 12:13:14 +0200 Subject: [PATCH 126/149] ISAICP-9002: Reexport configuration. --- .../sync/tmgmt.translator.ec_etranslation.yml | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/config/sync/tmgmt.translator.ec_etranslation.yml b/config/sync/tmgmt.translator.ec_etranslation.yml index d2f4b9b731..e00f77b9e7 100644 --- a/config/sync/tmgmt.translator.ec_etranslation.yml +++ b/config/sync/tmgmt.translator.ec_etranslation.yml @@ -11,8 +11,20 @@ auto_accept: null weight: null plugin: ec_etranslation settings: - username: null - password: null + username: '' + password: '' domain: SPD - email: null -remote_languages_mappings: { } + email: '' + callback_hostname: '' +remote_languages_mappings: + cs: cs + da: da + nl: nl + en: en + et: et + fr: fr + de: de + el: el + it: it + sl: sl + es: es -- GitLab From 7390ee92de1c2e32dc80d993ea2aab9edd3e3255 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 12:22:15 +0200 Subject: [PATCH 127/149] ISAICP-9002: Hide information about missing variables, don't fail in this case. --- resources/runner/drupal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml index 40b912c9b8..2b0fc17ae3 100644 --- a/resources/runner/drupal.yml +++ b/resources/runner/drupal.yml @@ -325,8 +325,8 @@ drupal: $config['search_api.server.joinup']['backend_config']['connector_config']['path'] = '/'; $config['search_api.server.joinup']['backend_config']['connector_config']['core'] = getenv('SEARCH_API_SERVER_SS_SOLR_CORE'); European Commission eTranslation: | - $config['tmgmt.translator.ec_etranslation']['settings']['username'] = getenv('TMGMT_ETRANSLATION_USERNAME'); - $config['tmgmt.translator.ec_etranslation']['settings']['password'] = getenv('TMGMT_ETRANSLATION_PASSWORD'); + $config['tmgmt.translator.ec_etranslation']['settings']['username'] = getenv('TMGMT_ETRANSLATION_USERNAME') ?: ''; + $config['tmgmt.translator.ec_etranslation']['settings']['password'] = getenv('TMGMT_ETRANSLATION_PASSWORD') ?: ''; OpenEuropa Webtools Analytics: | $config['oe_webtools_analytics.settings']['siteID'] = getenv('OE_WEBTOOLS_ANALYTICS_SITE_ID'); $config['oe_webtools_analytics.settings']['sitePath'] = getenv('OE_WEBTOOLS_ANALYTICS_SITE_PATH'); -- GitLab From 08febf1fd64e4383c4dfe47d1e763bfa34955ac5 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 14:19:35 +0200 Subject: [PATCH 128/149] ISAICP-9063: Use eu_oss_catalogue_fetcher. --- .../eu_oss_catalogue/eu_oss_catalogue.module | 10 +++----- .../QueueWorker/EuOssCatalogueFetcher.php | 24 ++++++++++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index cf81480be1..0b8609d98b 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -159,17 +159,13 @@ function eu_oss_catalogue_cron(): void { if (($request_time - $last_check) < $interval) { return; } + $queue_fetcher = \Drupal::queue('eu_oss_catalogue_fetcher'); /** @var \Drupal\eu_oss_catalogue\EuOssCataloguePluginManagerInterface $providerPluginManager */ $providerPluginManager = \Drupal::service('plugin.manager.eu_oss_catalogue.provider'); foreach ($providerPluginManager->getDefinitionsAsOptions('label') as $provider => $label) { - try { - \Drupal::service('eu_oss_catalogue')->fetch($provider); - \Drupal::logger('eu_oss_catalogue')->info('OSS fetch data ' . $provider . ' completed successfully.'); - } - catch (\Exception $e) { - \Drupal::logger('eu_oss_catalogue')->error('An error occurred while processing the data retrieval of ' . $provider . ': @error', ['@error' => $e->getMessage()]); - } + $queue_fetcher->createQueue(); + $queue_fetcher->createItem(['provider' => $provider]); } // Establish the timestamp as 2 AM of the current day. $state->set('eu_oss_catalogue.last_check', strtotime(date('Y-m-d', $request_time) . ' 2:00:00')); diff --git a/web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php b/web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php index cbf6bd8b32..08012a37af 100644 --- a/web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php +++ b/web/modules/custom/eu_oss_catalogue/src/Plugin/QueueWorker/EuOssCatalogueFetcher.php @@ -4,19 +4,19 @@ namespace Drupal\eu_oss_catalogue\Plugin\QueueWorker; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Queue\QueueWorkerBase; use Drupal\eu_oss_catalogue\EuOssCatalogueInterface; -use Drupal\eu_oss_catalogue\EuOssCataloguePluginManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Consumes the 'eu_oss_catalogue' queue. + * Consumes the 'eu_oss_catalogue_fetcher' queue. * * @QueueWorker( * id = "eu_oss_catalogue_fetcher", * title = @Translation("EU OSS Catalogue fetcher"), - * cron = {"time" = 10}, + * cron = {"time" = 60} * ) */ class EuOssCatalogueFetcher extends QueueWorkerBase implements ContainerFactoryPluginInterface { @@ -25,7 +25,8 @@ public function __construct( array $configuration, $pluginId, $pluginDefinition, - protected EuOssCataloguePluginManagerInterface $providerPluginManager, + protected EuOssCatalogueInterface $euOssCatalogue, + protected LoggerChannelInterface $logger, ) { parent::__construct($configuration, $pluginId, $pluginDefinition); } @@ -38,13 +39,24 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('plugin.manager.eu_oss_catalogue.provider'), + $container->get('eu_oss_catalogue'), + $container->get('logger.channel.eu_oss_catalogue') ); } /** * {@inheritdoc} */ - public function processItem($data): void {} + public function processItem($data): void { + try { + $provider = $data['provider']; + + $this->euOssCatalogue->fetch($provider); + $this->logger->info('OSS fetch data ' . $provider . ' completed successfully.'); + } + catch (\Exception $e) { + $this->logger->error('An error occurred while processing the data retrieval of ' . $provider . ': @error', ['@error' => $e->getMessage()]); + } + } } -- GitLab From 72bce96466b216e488ffffa829487e8be3da0938 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 20 Sep 2024 15:14:17 +0200 Subject: [PATCH 129/149] ISAICP-9003: Fix typo --- .../src/Plugin/QueueWorker/TranslationRequester.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php index 901b17d984..06efc76198 100644 --- a/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php +++ b/web/modules/custom/eu_oss_catalogue/modules/eu_oss_translation/src/Plugin/QueueWorker/TranslationRequester.php @@ -23,7 +23,7 @@ class TranslationRequester extends QueueWorkerBase implements ContainerFactoryPluginInterface { /** - * Queue id. + * Queue ID. */ public const string ID = 'eu_oss_translation_requester'; -- GitLab From c0a783aed0270acef696ea9ab4b2332a0a7158e0 Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Mon, 23 Sep 2024 12:29:13 +0200 Subject: [PATCH 130/149] ISAICP-9056: Unpin drupal/imagecache_external. - Reroll #3390948 - Reroll #3398665 + prevent conflict in imagecache_external.module by using FQCN instead of use stmt - Remove #3424594 (included since 3.0.2) --- composer.json | 7 +- composer.lock | 18 +- .../drupal/imagecache_external/3390948.diff | 42 +-- .../drupal/imagecache_external/3398665.diff | 52 +-- ...rong_setting_key-3424594-5--complete.patch | 314 ------------------ 5 files changed, 52 insertions(+), 381 deletions(-) delete mode 100644 resources/patch/php/drupal/imagecache_external/imagecache_external-wrong_setting_key-3424594-5--complete.patch diff --git a/composer.json b/composer.json index 75174e765a..6f9ae10a59 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "drupal/honeypot": "~2", "drupal/iframe": "^2", "drupal/image_library_widget": "^2.0", - "drupal/imagecache_external": "3.0.1", + "drupal/imagecache_external": "^3.0.4", "drupal/inline_entity_form": "^3.0", "drupal/jquery_ui_accordion": "^2.1", "drupal/json_field": "^1.0", @@ -121,8 +121,8 @@ "drupal/views_multiple_permissions": "^2.0", "drupal/webform": "^6.2", "drush/drush": "^12.1", - "jakeasmith/http_build_url": "^1.0", "gitonomy/gitlib": "^1.4", + "jakeasmith/http_build_url": "^1.0", "knplabs/github-api": "^3.13", "m4tthumphrey/php-gitlab-api": "^11.12", "openeuropa/composer-artifacts": "^1.0", @@ -386,8 +386,7 @@ "drupal/imagecache_external": { "Support SVG @see https://www.drupal.org/i/3390948": "resources/patch/php/drupal/imagecache_external/3390948.diff", "Add option to override the inherited HTTP client configuration @see https://drupal.org/i/3396502": "resources/patch/php/drupal/imagecache_external/3396502-7.diff", - "Do not try to download failed URLs repeatedly: attempt next time only after the local cache is rebuilt @see https://drupal.org/i/3398665": "resources/patch/php/drupal/imagecache_external/3398665.diff", - "Imagecache External Responsive Image formatter uses wrong key to read link setting @see https://drupal.org/i/3424594": "resources/patch/php/drupal/imagecache_external/imagecache_external-wrong_setting_key-3424594-5--complete.patch" + "Do not try to download failed URLs repeatedly: attempt next time only after the local cache is rebuilt @see https://drupal.org/i/3398665": "resources/patch/php/drupal/imagecache_external/3398665.diff" }, "drupal/inline_entity_form": { "Autocomplete field doesn't allow to reference entities with long titles @see https://www.drupal.org/node/2895663": "resources/patch/php/drupal/inline_entity_form/2895663.patch", diff --git a/composer.lock b/composer.lock index f3a4eb8a08..7f496140ad 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e23b99a6d995e2fb5a630ccb6db433db", + "content-hash": "63b1220ccb3d35502d14fd6f1b4baf8b", "packages": [ { "name": "asm89/stack-cors", @@ -4705,26 +4705,26 @@ }, { "name": "drupal/imagecache_external", - "version": "3.0.1", + "version": "3.0.4", "source": { "type": "git", "url": "https://git.drupalcode.org/project/imagecache_external.git", - "reference": "3.0.1" + "reference": "3.0.4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/imagecache_external-3.0.1.zip", - "reference": "3.0.1", - "shasum": "f36e080a5059d760f4c47ad21ac9391f1b1ea6b3" + "url": "https://ftp.drupal.org/files/projects/imagecache_external-3.0.4.zip", + "reference": "3.0.4", + "shasum": "0a6fc7f66f6ab39beb787ae0a5923009911de55d" }, "require": { - "drupal/core": "^9.3 || ^10" + "drupal/core": "^10.1 || ^11" }, "type": "drupal-module", "extra": { "drupal": { - "version": "3.0.1", - "datestamp": "1665918248", + "version": "3.0.4", + "datestamp": "1722719303", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" diff --git a/resources/patch/php/drupal/imagecache_external/3390948.diff b/resources/patch/php/drupal/imagecache_external/3390948.diff index 28b5d9cf73..7f81882978 100644 --- a/resources/patch/php/drupal/imagecache_external/3390948.diff +++ b/resources/patch/php/drupal/imagecache_external/3390948.diff @@ -1,23 +1,3 @@ -diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml -new file mode 100644 -index 0000000000000000000000000000000000000000..71f942f0e424f0d260cdd56149ef4eeb7d6033f3 ---- /dev/null -+++ b/.gitlab-ci.yml -@@ -0,0 +1,14 @@ -+include: -+ - project: $_GITLAB_TEMPLATES_REPO -+ ref: $_GITLAB_TEMPLATES_REF -+ file: -+ - '/includes/include.drupalci.main.yml' -+ - '/includes/include.drupalci.variables.yml' -+ - '/includes/include.drupalci.workflows.yml' -+ -+variables: -+ _SHOW_ENVIRONMENT_VARIABLES: 1 -+ _TARGET_PHP: "$CORE_PHP_MAX" -+ _TARGET_DB_VERSION: "8" -+ # The whole module needs to adhere to coding standards. -+ SKIP_PHPCS: 1 diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..7f096249dab903c9b7c8d09020f1b0e8c720fc94 @@ -94,7 +74,7 @@ index 8f03bbb634d0dc65aad4be9bb0e869c033efc288..de0d854693bc9501f6b301a45fe73f61 + ->save(TRUE); +} diff --git a/imagecache_external.module b/imagecache_external.module -index 851681dc3efd08b1102862768d0f4e6d34f7acb8..fc346220baddecf0618a06c6334dbc6f26d88246 100644 +index df28db52df5b5f402c0ed7ddbaa04cc46b543ece..bfd9e00965c29d6f94d366e2139892ceb4c55a87 100644 --- a/imagecache_external.module +++ b/imagecache_external.module @@ -9,6 +9,9 @@ use Drupal\Component\Utility\UrlHelper; @@ -107,16 +87,16 @@ index 851681dc3efd08b1102862768d0f4e6d34f7acb8..fc346220baddecf0618a06c6334dbc6f const IMAGECACHE_EXTERNAL_FLUSH_DIRECTORIES = '_IMAGECACHE_FLUSH_DIRECTORIES_'; -@@ -139,7 +142,7 @@ function imagecache_external_generate_path($url) { +@@ -145,7 +148,7 @@ function imagecache_external_generate_path(?string $url) { // Add the extension for real images. - if ($extension = strtolower(pathinfo($url_parameters['path'], PATHINFO_EXTENSION))) { -- if (in_array($extension, ['jpg', 'png', 'gif', 'jpeg', 'webp'])) { -+ if (in_array($extension, ['jpg', 'png', 'gif', 'jpeg', 'webp', 'svg'])) { - $filename .= '.' . $extension; - } + $extension = strtolower(pathinfo($url_parameters['path'], PATHINFO_EXTENSION)); +- if (in_array($extension, ['jpg', 'png', 'gif', 'jpeg', 'webp'])) { ++ if (in_array($extension, ['jpg', 'png', 'gif', 'jpeg', 'webp', 'svg'])) { + $filename .= '.' . $extension; } -@@ -220,16 +223,20 @@ function imagecache_external_fetch(string $url, string $cachepath) { + else { +@@ -225,16 +228,20 @@ function imagecache_external_fetch(string $url, string $cachepath) { $content_type_array = explode(';', $response_mimetype); $content_type_allowed = FALSE; foreach ($content_type_array as $content_type) { @@ -141,7 +121,7 @@ index 851681dc3efd08b1102862768d0f4e6d34f7acb8..fc346220baddecf0618a06c6334dbc6f return $file->getFileUri(); } } -@@ -247,6 +254,36 @@ function imagecache_external_fetch(string $url, string $cachepath) { +@@ -252,6 +259,36 @@ function imagecache_external_fetch(string $url, string $cachepath) { } } @@ -340,10 +320,10 @@ index 0000000000000000000000000000000000000000..c5765c8791fb8248742d77b98dd66e93 + <rect height="50" width="50" fill="red"></rect> +</svg> diff --git a/tests/src/Functional/ImagecacheExternalTest.php b/tests/src/Functional/ImagecacheExternalTest.php -index 62498131ca16cc0065f176f7b7dd1fe1ec48a564..f737bb931b33e38ac8ecc1809c687ae5e5bb0bb7 100644 +index 239096248a0798b36a5cfffadc4d482f22edece2..e48440529e30c889387dff1cd5aa14eabbd2842d 100644 --- a/tests/src/Functional/ImagecacheExternalTest.php +++ b/tests/src/Functional/ImagecacheExternalTest.php -@@ -270,6 +270,67 @@ class ImagecacheExternalTest extends BrowserTestBase { +@@ -291,6 +291,67 @@ class ImagecacheExternalTest extends BrowserTestBase { $this->assertSession()->statusCodeEquals(200); } diff --git a/resources/patch/php/drupal/imagecache_external/3398665.diff b/resources/patch/php/drupal/imagecache_external/3398665.diff index 6681186ebe..d1996e2c53 100644 --- a/resources/patch/php/drupal/imagecache_external/3398665.diff +++ b/resources/patch/php/drupal/imagecache_external/3398665.diff @@ -1,47 +1,42 @@ diff --git a/imagecache_external.module b/imagecache_external.module -index 22d62dc..f05cccf 100644 +index df28db5..8320382 100644 --- a/imagecache_external.module +++ b/imagecache_external.module -@@ -9,6 +9,7 @@ use Drupal\Component\Utility\UrlHelper; - use Drupal\Core\StreamWrapper\StreamWrapperManager; - use Drupal\Core\File\FileSystemInterface; - use Drupal\file\Entity\File; -+use Drupal\imagecache_external\ImagecacheExternal; - use Drupal\imagecache_external\Svg\ImagecacheExternalAttributes; - use Drupal\imagecache_external\Svg\ImagecacheExternalTags; - use enshrined\svgSanitize\Sanitizer; -@@ -104,6 +105,9 @@ function template_preprocess_imagecache_external_responsive(&$variables) { - * The uri to the image. +@@ -102,11 +102,9 @@ function template_preprocess_imagecache_external_responsive(&$variables) { + * @throws \GuzzleHttp\Exception\GuzzleException */ - function imagecache_external_generate_path($url) { -+ if (ImagecacheExternal::isUnavailableUrl($url)) { -+ return FALSE; -+ } + function imagecache_external_generate_path(?string $url) { +- // If $url is null or empty, return FALSE +- if (empty($url)) { ++ if (empty($url) || \Drupal\imagecache_external\ImagecacheExternal::isUnavailableUrl($url)) { + return FALSE; + } +- // Get configuration. $config = imagecache_external_config(); -@@ -250,6 +254,7 @@ function imagecache_external_fetch(string $url, string $cachepath) { +@@ -247,6 +245,7 @@ function imagecache_external_fetch(string $url, string $cachepath) { if (!empty($fallback_image_fid) && $fallback_image = File::load($fallback_image_fid)) { return $fallback_image->getFileUri(); } -+ ImagecacheExternal::registerUnavailableUrl($url); ++ \Drupal\imagecache_external\ImagecacheExternal::registerUnavailableUrl($url); \Drupal::logger('imagecache_external')->notice(t('The image %url could not be retrieved', ['%url' => $url])); return FALSE; } -@@ -444,6 +449,7 @@ function imagecache_external_flush_create_queue($path) { +@@ -411,6 +410,7 @@ function imagecache_external_flush_create_queue($path) { \Drupal::service('file_system')->deleteRecursive($path); } -+ ImagecacheExternal::resetUnavailableUrls(); ++ \Drupal\imagecache_external\ImagecacheExternal::resetUnavailableUrls(); return TRUE; } diff --git a/src/ImagecacheExternal.php b/src/ImagecacheExternal.php new file mode 100644 -index 0000000..7e911e4 +index 0000000..49b6060 --- /dev/null +++ b/src/ImagecacheExternal.php -@@ -0,0 +1,86 @@ +@@ -0,0 +1,84 @@ +<?php + +declare(strict_types = 1); @@ -64,8 +59,6 @@ index 0000000..7e911e4 + + /** + * The state service. -+ * -+ * @var \Drupal\Core\State\StateInterface + */ + protected static StateInterface $state; + @@ -128,6 +121,19 @@ index 0000000..7e911e4 + } + +} +diff --git a/tests/src/Kernel/ImagecacheExternalResponsiveImageFormatterTest.php b/tests/src/Kernel/ImagecacheExternalResponsiveImageFormatterTest.php +index 92dbbec..4ab2c48 100644 +--- a/tests/src/Kernel/ImagecacheExternalResponsiveImageFormatterTest.php ++++ b/tests/src/Kernel/ImagecacheExternalResponsiveImageFormatterTest.php +@@ -208,7 +208,7 @@ class ImagecacheExternalResponsiveImageFormatterTest extends KernelTestBase { + * @return string[][] + * The test cases. + */ +- public static function providerLinkSetting(): array { ++ public function providerLinkSetting(): array { + return [ + 'Field not using link' => [ + 'link setting' => '', diff --git a/tests/src/Kernel/TrackNonDownloadableUrlsTest.php b/tests/src/Kernel/TrackNonDownloadableUrlsTest.php new file mode 100644 index 0000000..397b74c diff --git a/resources/patch/php/drupal/imagecache_external/imagecache_external-wrong_setting_key-3424594-5--complete.patch b/resources/patch/php/drupal/imagecache_external/imagecache_external-wrong_setting_key-3424594-5--complete.patch deleted file mode 100644 index 98a0e26740..0000000000 --- a/resources/patch/php/drupal/imagecache_external/imagecache_external-wrong_setting_key-3424594-5--complete.patch +++ /dev/null @@ -1,314 +0,0 @@ -diff --git a/src/Plugin/Field/FieldFormatter/ImagecacheExternalResponsiveImage.php b/src/Plugin/Field/FieldFormatter/ImagecacheExternalResponsiveImage.php -index a82e7a1..6f2e733 100644 ---- a/src/Plugin/Field/FieldFormatter/ImagecacheExternalResponsiveImage.php -+++ b/src/Plugin/Field/FieldFormatter/ImagecacheExternalResponsiveImage.php -@@ -231,7 +231,7 @@ class ImagecacheExternalResponsiveImage extends FormatterBase implements Contain - $field_settings = $this->getFieldSettings(); - - $url = NULL; -- $image_link_setting = $this->getSetting('imagecache_external_responsive_style'); -+ $image_link_setting = $this->getSetting('imagecache_external_link'); - // Check if the formatter involves a link. - if ($image_link_setting == 'content') { - $entity = $items->getEntity(); -diff --git a/tests/src/Kernel/ImagecacheExternalResponsiveImageFormatterTest.php b/tests/src/Kernel/ImagecacheExternalResponsiveImageFormatterTest.php -new file mode 100644 -index 0000000..69d152a ---- /dev/null -+++ b/tests/src/Kernel/ImagecacheExternalResponsiveImageFormatterTest.php -@@ -0,0 +1,295 @@ -+<?php -+ -+declare(strict_types=1); -+ -+namespace Drupal\Tests\imagecache_external\Kernel; -+ -+use Drupal\Component\Utility\Html; -+use Drupal\Core\Entity\Entity\EntityViewDisplay; -+use Drupal\Core\Render\RenderContext; -+use Drupal\entity_test\Entity\EntityTest; -+use Drupal\field\Entity\FieldConfig; -+use Drupal\field\Entity\FieldStorageConfig; -+use Drupal\image\Entity\ImageStyle; -+use Drupal\KernelTests\KernelTestBase; -+use Drupal\responsive_image\Entity\ResponsiveImageStyle; -+use GuzzleHttp\Client; -+use GuzzleHttp\Handler\MockHandler; -+use GuzzleHttp\HandlerStack; -+use GuzzleHttp\Psr7\Response; -+ -+/** -+ * Tests for Imagecache External. -+ * -+ * @coversDefaultClass \Drupal\imagecache_external\Plugin\Field\FieldFormatter\ImagecacheExternalResponsiveImage -+ * -+ * @group imagecache_external -+ */ -+class ImagecacheExternalResponsiveImageFormatterTest extends KernelTestBase { -+ -+ /** -+ * The test entity. -+ * -+ * @var \Drupal\entity_test\Entity\EntityTest -+ */ -+ protected $entity; -+ -+ /** -+ * Mock client. -+ * -+ * @var \GuzzleHttp\ClientInterface -+ */ -+ protected $mockClient; -+ -+ /** -+ * The field name of the test field. -+ * -+ * @var string -+ */ -+ protected $fieldName; -+ -+ /** -+ * A view display of the test entity. -+ * -+ * @var \Drupal\Core\Entity\Entity\EntityViewDisplay -+ */ -+ protected $display; -+ -+ /** -+ * {@inheritdoc} -+ */ -+ protected static $modules = [ -+ 'breakpoint', -+ 'entity_test', -+ 'field', -+ 'file', -+ 'image', -+ 'imagecache_external', -+ 'responsive_image', -+ 'system', -+ 'user', -+ ]; -+ -+ /** -+ * {@inheritdoc} -+ */ -+ protected function setUp(): void { -+ parent::setUp(); -+ $entity_type = 'entity_test'; -+ $this->installConfig([ -+ 'system', -+ 'field', -+ 'image', -+ 'responsive_image', -+ 'imagecache_external', -+ ]); -+ $this->installEntitySchema($entity_type); -+ $this->fieldName = $this->randomMachineName(); -+ -+ $field_storage = FieldStorageConfig::create([ -+ 'field_name' => $this->fieldName, -+ 'entity_type' => $entity_type, -+ 'type' => 'string', -+ ]); -+ $field_storage->save(); -+ -+ $instance = FieldConfig::create([ -+ 'field_storage' => $field_storage, -+ 'bundle' => $entity_type, -+ 'label' => $this->randomMachineName(), -+ ]); -+ $instance->save(); -+ -+ $this->display = EntityViewDisplay::create([ -+ 'targetEntityType' => $entity_type, -+ 'bundle' => $entity_type, -+ 'mode' => 'default', -+ 'status' => TRUE, -+ ]); -+ $this->display->save(); -+ -+ $this->entity = EntityTest::create([ -+ 'type' => 'entity_test', -+ 'name' => $this->randomMachineName(), -+ $this->fieldName => 'https://imagecache-external.example.com/image/drupal.png', -+ ]); -+ $this->entity->save(); -+ -+ $this->createImageStyle('foo'); -+ $this->createImageStyle('bar', 600, 600); -+ -+ // Add a responsive image style. -+ $responsive_image_styep = ResponsiveImageStyle::create([ -+ 'id' => 'responsive_image', -+ 'label' => 'Responsive image', -+ 'breakpoint_group' => 'responsive_image.viewport_sizing', -+ 'fallback_image_style' => 'foo', -+ ])->addImageStyleMapping( -+ 'test_breakpoint', -+ '1x', -+ [ -+ 'image_mapping_type' => 'sizes', -+ 'image_mapping' => [ -+ 'sizes' => '(min-width:700px) 700px, 100vw', -+ 'sizes_image_styles' => [ -+ 'foo' => 'foo', -+ 'bar' => 'bar', -+ ], -+ ], -+ ] -+ ); -+ $responsive_image_styep->save(); -+ } -+ -+ /** -+ * @covers ::viewElements -+ * @dataProvider providerLinkSetting -+ */ -+ public function testFormatter(string $link, string $expected_uri): void { -+ $this->display -+ ->setComponent( -+ $this->fieldName, -+ [ -+ 'type' => 'imagecache_external_responsive_image', -+ 'label' => 'hidden', -+ 'settings' => [ -+ 'imagecache_external_responsive_style' => 'responsive_image', -+ 'imagecache_external_link' => $link, -+ ], -+ ] -+ ) -+ ->save(); -+ -+ $this->normalizeTestUrl($expected_uri); -+ -+ $renderer = $this->container->get('renderer'); -+ $this->mockClient( -+ new Response( -+ 200, -+ [], -+ file_get_contents(dirname(__DIR__, 2) . '/assets/el-blue.png') -+ ), -+ ); -+ $rendered_output = $renderer->executeInRenderContext( -+ new RenderContext(), -+ function () use ($renderer) { -+ $build = $this->entity -+ ->get($this->fieldName) -+ ->view($this->display->getMode()); -+ return $renderer->render($build); -+ } -+ ); -+ $dom = Html::load($rendered_output); -+ // We should have an <img> and a <picture> element, and if the field is -+ // configured to link the items, then a link also should appear. -+ $this->assertCount(1, $dom->getElementsByTagName('img')); -+ $this->assertCount(1, $dom->getElementsByTagName('picture')); -+ $this->assertCount( -+ $expected_uri ? 1 : 0, -+ $links = $dom->getElementsByTagName('a'), -+ 'Responsive image is not wrapped into a link' -+ ); -+ if ($expected_uri) { -+ $this->assertEquals( -+ $expected_uri, -+ urldecode( -+ $links->item(0) -+ ->attributes -+ ->getNamedItem('href') -+ ->nodeValue -+ ) -+ ); -+ } -+ } -+ -+ /** -+ * Data provider for ::testFormatter. -+ * -+ * @return string[][] -+ * The test cases. -+ */ -+ public function providerLinkSetting(): array { -+ return [ -+ 'Field not using link' => [ -+ 'link setting' => '', -+ 'expected URL' => '', -+ ], -+ 'Linked to file' => [ -+ 'link setting' => 'file', -+ 'expected URL' => 'public://externals/0957f4609929b129757304fd836683f4.png', -+ ], -+ 'Linked to content' => [ -+ 'link setting' => 'content', -+ 'expected URL' => '/entity_test/1', -+ ], -+ ]; -+ } -+ -+ /** -+ * Normalizes test URLs. -+ * -+ * Replaces the scheme in URLs with the scheme's relative path if the scheme -+ * has its own stream wrapper in Drupal. -+ * -+ * @param string $url -+ * The URL to normalize. -+ */ -+ protected function normalizeTestUrl(string &$url): void { -+ $scheme = parse_url($url)['scheme'] ?? NULL; -+ if ( -+ $scheme && -+ $wrapper = $this->container->get('stream_wrapper_manager')->getViaScheme($scheme) -+ ) { -+ $wrapper_uri = $wrapper->getUri(); -+ $url = '/' . ltrim( -+ preg_replace( -+ "#^$wrapper_uri#", -+ $wrapper->realpath(), -+ $url -+ ), -+ '/' -+ ); -+ } -+ } -+ -+ /** -+ * Creates an image style with a single crop effect. -+ * -+ * @param string $id -+ * The ID of the image style. Also used as label. -+ * @param int $width -+ * The crop width. Optional, defaults to 400. -+ * @param int $height -+ * The crop height. Optional, defaults to 400. -+ */ -+ protected function createImageStyle(string $id, int $width = 400, int $height = 400): void { -+ $image_stype = ImageStyle::create(['name' => $id, 'label' => $id]); -+ $image_stype->addImageEffect([ -+ 'id' => 'image_scale', -+ 'data' => [ -+ 'upscale' => TRUE, -+ 'width' => $width, -+ 'height' => $height, -+ ], -+ 'weight' => 0, -+ ]); -+ $image_stype->save(); -+ } -+ -+ /** -+ * Replaces the HTTP client service with a mock returning the given responses. -+ * -+ * @param \GuzzleHttp\Psr7\Response ...$responses -+ * List of responses to return. -+ */ -+ protected function mockClient(Response ...$responses): void { -+ if (!isset($this->mockClient)) { -+ // Create a mock and queue responses. -+ $mock = new MockHandler($responses); -+ $handler_stack = HandlerStack::create($mock); -+ $this->mockClient = new Client(['handler' => $handler_stack]); -+ } -+ $this->container->set('http_client', $this->mockClient); -+ } -+ -+} -- GitLab From 079b27c8b0320dfd2390375d4ad82f3c9f060cce Mon Sep 17 00:00:00 2001 From: Herve Donner <hervedonner@gmail.com> Date: Mon, 23 Sep 2024 14:32:41 +0200 Subject: [PATCH 131/149] ISAICP-5244: Fixup 376f4f08. --- web/modules/custom/joinup_group/src/Entity/GroupTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php index 6038011cdd..603c5b3651 100644 --- a/web/modules/custom/joinup_group/src/Entity/GroupTrait.php +++ b/web/modules/custom/joinup_group/src/Entity/GroupTrait.php @@ -337,7 +337,7 @@ public function getActiveMemberCount(): int { ->condition('entity_type', 'rdf_entity') ->condition('entity_id', $this->id()) ->condition('state', OgMembershipInterface::STATE_ACTIVE); - return $this->activeMemberCount = (int) $query->countQuery()->execute()->fetchField(); + return (int) $query->countQuery()->execute()->fetchField(); } } -- GitLab From 54328060801e3c1053a33a307ce1b26e9166e503 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Mon, 23 Sep 2024 22:24:31 +0200 Subject: [PATCH 132/149] ISAICP-9099: Set minimum log level notice for default and php channels. --- .../joinup_core/joinup_core.monolog.services.yml | 4 ++-- .../joinup_core/src/JoinupCoreServiceProvider.php | 12 +++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/web/modules/custom/joinup_core/joinup_core.monolog.services.yml b/web/modules/custom/joinup_core/joinup_core.monolog.services.yml index 23738dbf3c..e56f8fa978 100644 --- a/web/modules/custom/joinup_core/joinup_core.monolog.services.yml +++ b/web/modules/custom/joinup_core/joinup_core.monolog.services.yml @@ -24,12 +24,12 @@ services: monolog.handler.default_handler: class: Monolog\Handler\RotatingFileHandler # The parameter is set in \Drupal\joinup_core\JoinupCoreServiceProvider - arguments: ['%joinup_core.monolog.paths.default_handler%', 10, '100'] + arguments: ['%joinup_core.monolog.paths.default_handler%', 10, 250] monolog.handler.php_handler: class: Monolog\Handler\RotatingFileHandler # The parameter is set in \Drupal\joinup_core\JoinupCoreServiceProvider - arguments: ['%joinup_core.monolog.paths.php_handler%', 10, '400'] + arguments: ['%joinup_core.monolog.paths.php_handler%', 10, 250] monolog.handler.mail: class: Drupal\joinup_core\Logger\Handler\MailHandler diff --git a/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php b/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php index b1890a4a55..cd5ac3eef3 100644 --- a/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php +++ b/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php @@ -6,32 +6,26 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceModifierInterface; -use Joinup\Traits\DigitQaPipelineAwareTrait; /** * Sets Monolog handler paths from DRUPAL_MONOLOG_PATHS and adds dblog logging. */ class JoinupCoreServiceProvider implements ServiceModifierInterface { - use DigitQaPipelineAwareTrait; - /** * {@inheritdoc} */ public function alter(ContainerBuilder $container): void { - // Workaround FPFISSUPP-15044. - // @see https://citnet.tech.ec.europa.eu/CITnet/jira/browse/FPFISSUPP-15044 - // @todo Remove once FPFISSUPP-15044 is fixed. - $paths = !static::isDigitQaPipeline() ? getenv('DRUPAL_MONOLOG_PATHS') : 'default_handler:/tmp/drupal/default.log;php_handler:/tmp/drupal/php.log'; + $paths = getenv('DRUPAL_MONOLOG_PATHS') ?: 'default_handler:/tmp/drupal/log/default.log;php_handler:/tmp/drupal/log/php.log'; // Sets the Monolog handler paths from DRUPAL_MONOLOG_PATHS env var. if ($paths) { foreach (explode(';', $paths) as $item) { $item = str_replace(' ', '', $item); - if (strpos($item, ':') !== FALSE) { + if (str_contains($item, ':')) { [$handler, $path] = explode(':', $item); if ($handler && $path) { - $container->setParameter("joinup_core.monolog.paths.{$handler}", $path); + $container->setParameter("joinup_core.monolog.paths.$handler", $path); } } } -- GitLab From 8cc3e4d7651f20f5b8037c1ea9e9b90f639ecfa1 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Wed, 25 Sep 2024 14:51:04 +0200 Subject: [PATCH 133/149] ISAICP-9099: Revert a change that prevents logs to be written by webserver. --- .../custom/joinup_core/src/JoinupCoreServiceProvider.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php b/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php index cd5ac3eef3..6ce4b43af3 100644 --- a/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php +++ b/web/modules/custom/joinup_core/src/JoinupCoreServiceProvider.php @@ -6,17 +6,23 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceModifierInterface; +use Joinup\Traits\DigitQaPipelineAwareTrait; /** * Sets Monolog handler paths from DRUPAL_MONOLOG_PATHS and adds dblog logging. */ class JoinupCoreServiceProvider implements ServiceModifierInterface { + use DigitQaPipelineAwareTrait; + /** * {@inheritdoc} */ public function alter(ContainerBuilder $container): void { - $paths = getenv('DRUPAL_MONOLOG_PATHS') ?: 'default_handler:/tmp/drupal/log/default.log;php_handler:/tmp/drupal/log/php.log'; + // Workaround FPFISSUPP-15044. + // @see https://citnet.tech.ec.europa.eu/CITnet/jira/browse/FPFISSUPP-15044 + // @todo Remove once FPFISSUPP-15044 is fixed. + $paths = !static::isDigitQaPipeline() ? getenv('DRUPAL_MONOLOG_PATHS') : 'default_handler:/tmp/drupal/default.log;php_handler:/tmp/drupal/php.log'; // Sets the Monolog handler paths from DRUPAL_MONOLOG_PATHS env var. if ($paths) { -- GitLab From ec5a524e7f8ce6087bfb9f6dc2441ea03bd44d6f Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 26 Sep 2024 08:56:58 +0200 Subject: [PATCH 134/149] ISAICP-9063: WIP --- web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module | 4 +++- .../eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index 0b8609d98b..cf5fa888d7 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -51,6 +51,7 @@ function eu_oss_catalogue_form_views_exposed_form_alter(array &$form, FormStateI '#default_value' => $form['oss_source']['#default_value'], ]; + dpm($providerPluginManager->getDefinitionsAsOptions('label')); // Use yes-no instead of true-false. $form['oss_archived']['#options'][1] = t('Yes'); $form['oss_archived']['#options'][0] = t('No'); @@ -160,13 +161,14 @@ function eu_oss_catalogue_cron(): void { return; } $queue_fetcher = \Drupal::queue('eu_oss_catalogue_fetcher'); + $queue_fetcher->createQueue(); /** @var \Drupal\eu_oss_catalogue\EuOssCataloguePluginManagerInterface $providerPluginManager */ $providerPluginManager = \Drupal::service('plugin.manager.eu_oss_catalogue.provider'); foreach ($providerPluginManager->getDefinitionsAsOptions('label') as $provider => $label) { - $queue_fetcher->createQueue(); $queue_fetcher->createItem(['provider' => $provider]); } + // Establish the timestamp as 2 AM of the current day. $state->set('eu_oss_catalogue.last_check', strtotime(date('Y-m-d', $request_time) . ' 2:00:00')); \Drupal::logger('eu_oss_catalogue')->info('Cron eu_oss_catalogue_cron ran successfully.'); diff --git a/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php b/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php index 0167385a26..ab9999d829 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php +++ b/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php @@ -69,6 +69,7 @@ public function testCronPeriodicalTask(): void { // And I run cron. $cron->run(); + // Failed. $this->assertEquals( strtotime(date('Y-m-d', $future_timestamp) . ' 2:00:00'), $state->get('eu_oss_catalogue.last_check') -- GitLab From 100108b0333e715596c1f90c38d9e6e830a3835e Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 26 Sep 2024 10:11:19 +0200 Subject: [PATCH 135/149] ISAICP-9063: Mock queue. --- .../tests/src/Kernel/CronTimingTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php b/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php index ab9999d829..5b54bf9f6f 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php +++ b/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php @@ -5,6 +5,8 @@ namespace Drupal\Tests\eu_oss_catalogue\Kernel; use Drupal\Component\Datetime\TimeInterface; +use Drupal\Core\Queue\QueueFactory; +use Drupal\Core\Queue\QueueInterface; use Drupal\KernelTests\KernelTestBase; /** @@ -66,6 +68,21 @@ public function testCronPeriodicalTask(): void { // Replace the real DrupalDateTime class with the mocked one. $this->container->set('datetime.time', $mocked_time); + // Mock queue to check if correct arguments were provided. + $mock_queue = $this->createMock(QueueInterface::class); + $mock_queue->expects($this->once()) + ->method('createQueue'); + $mock_queue->expects($this->once()) + ->method('createItem') + ->with(['provider' => 'developers_italia']); + $this->container->set('queue', $mock_queue); + $queue_factory = $this->createMock(QueueFactory::class); + $queue_factory->expects($this->any()) + ->method('get') + ->with('eu_oss_catalogue_fetcher') + ->willReturn($mock_queue); + $this->container->set('queue', $queue_factory); + // And I run cron. $cron->run(); -- GitLab From 43475611347aa182a92baf1ac16a5b9bfbf69378 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 26 Sep 2024 10:12:46 +0200 Subject: [PATCH 136/149] ISAICP-9063: Remove debug code. --- web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index cf5fa888d7..07975d3f8a 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -50,8 +50,7 @@ function eu_oss_catalogue_form_views_exposed_form_alter(array &$form, FormStateI '#options' => ['' => t('- Any -')] + $providerPluginManager->getDefinitionsAsOptions('label'), '#default_value' => $form['oss_source']['#default_value'], ]; - - dpm($providerPluginManager->getDefinitionsAsOptions('label')); + // Use yes-no instead of true-false. $form['oss_archived']['#options'][1] = t('Yes'); $form['oss_archived']['#options'][0] = t('No'); -- GitLab From 60b88428b93aa406fc1eea5b268a7695dbfad2b6 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 26 Sep 2024 10:13:20 +0200 Subject: [PATCH 137/149] ISAICP-9063: Fix padding. --- web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module index 07975d3f8a..2999a7976a 100644 --- a/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module +++ b/web/modules/custom/eu_oss_catalogue/eu_oss_catalogue.module @@ -50,7 +50,7 @@ function eu_oss_catalogue_form_views_exposed_form_alter(array &$form, FormStateI '#options' => ['' => t('- Any -')] + $providerPluginManager->getDefinitionsAsOptions('label'), '#default_value' => $form['oss_source']['#default_value'], ]; - + // Use yes-no instead of true-false. $form['oss_archived']['#options'][1] = t('Yes'); $form['oss_archived']['#options'][0] = t('No'); -- GitLab From 2a8453cd7eee9322267c40d1d67b391fd9f44e9a Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Thu, 26 Sep 2024 11:52:03 +0200 Subject: [PATCH 138/149] ISAICP-9063: Remove not needed comment. --- .../custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php b/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php index 5b54bf9f6f..2abf9e36b6 100644 --- a/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php +++ b/web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php @@ -86,7 +86,6 @@ public function testCronPeriodicalTask(): void { // And I run cron. $cron->run(); - // Failed. $this->assertEquals( strtotime(date('Y-m-d', $future_timestamp) . ' 2:00:00'), $state->get('eu_oss_catalogue.last_check') -- GitLab From 1d95935426019fee72358aaafa083c7dd9d20a5c Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 27 Sep 2024 08:50:42 +0200 Subject: [PATCH 139/149] ISAICP-9104: Update patch. --- composer.json | 2 +- composer.lock | 2 +- .../og_menu/{3392055.patch => 3392055.diff} | 31 +++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) rename resources/patch/php/drupal/og_menu/{3392055.patch => 3392055.diff} (72%) diff --git a/composer.json b/composer.json index 6f9ae10a59..0a6bfa5218 100644 --- a/composer.json +++ b/composer.json @@ -414,7 +414,7 @@ }, "drupal/og_menu": { "D10 deprecations @see https://www.drupal.org/project/og_menu/issues/3391985": "resources/patch/php/drupal/og_menu/3391985.patch", - "menu_name accessed before initialized @see https://www.drupal.org/project/og_menu/issues/3392055": "resources/patch/php/drupal/og_menu/3392055.patch" + "menu_name accessed before initialized @see https://www.drupal.org/project/og_menu/issues/3392055": "resources/patch/php/drupal/og_menu/3392055.diff" }, "drupal/poll": { "Add permissions to edit all polls @see https://www.drupal.org/project/poll/issues/3274724": "resources/patch/php/drupal/poll/3274724-4.patch", diff --git a/composer.lock b/composer.lock index 7f496140ad..a9c1f40fc6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "63b1220ccb3d35502d14fd6f1b4baf8b", + "content-hash": "d04ef4d4d908f71ba165051c7870fbce", "packages": [ { "name": "asm89/stack-cors", diff --git a/resources/patch/php/drupal/og_menu/3392055.patch b/resources/patch/php/drupal/og_menu/3392055.diff similarity index 72% rename from resources/patch/php/drupal/og_menu/3392055.patch rename to resources/patch/php/drupal/og_menu/3392055.diff index 994ff77999..e48c959a8e 100644 --- a/resources/patch/php/drupal/og_menu/3392055.patch +++ b/resources/patch/php/drupal/og_menu/3392055.diff @@ -1,5 +1,5 @@ diff --git a/src/Plugin/Block/OgMenuBlock.php b/src/Plugin/Block/OgMenuBlock.php -index 297960c..87cee17 100644 +index 297960c7643c717e46bc8b900d52bc195eac4eee..4a147d22d2e3d3263d0fcd01f400fb617a165e1b 100644 --- a/src/Plugin/Block/OgMenuBlock.php +++ b/src/Plugin/Block/OgMenuBlock.php @@ -99,6 +99,7 @@ class OgMenuBlock extends BlockBase implements ContainerFactoryPluginInterface, @@ -8,9 +8,9 @@ index 297960c..87cee17 100644 $this->entityTypeManager = $entity_type_manager; + $this->menuName = ''; } - + /** -@@ -284,13 +285,15 @@ class OgMenuBlock extends BlockBase implements ContainerFactoryPluginInterface, +@@ -284,15 +285,19 @@ class OgMenuBlock extends BlockBase implements ContainerFactoryPluginInterface, */ public function getOgMenuInstance() { $entity = $this->getContext('og')->getContextData()->getValue(); @@ -21,19 +21,24 @@ index 297960c..87cee17 100644 - ]); - if ($instances) { - return array_pop($instances); -+ $entity_id = $entity->id(); -+ if ($entity_id) { -+ $instances = $this->entityTypeManager->getStorage('ogmenu_instance')->loadByProperties([ ++ if (!$entity || !$entity->id()) { ++ return NULL; + } +- return NULL; ++ $instances = $this->entityTypeManager->getStorage('ogmenu_instance') ++ ->loadByProperties([ + 'type' => $this->getDerivativeId(), -+ OgGroupAudienceHelperInterface::DEFAULT_FIELD => $entity_id, ++ OgGroupAudienceHelperInterface::DEFAULT_FIELD => $entity->id(), + ]); -+ if ($instances) { -+ return array_pop($instances); -+ } - } - return NULL; ++ if (!$instances) { ++ return NULL; ++ } ++ ++ return array_pop($instances); } -@@ -302,7 +305,7 @@ class OgMenuBlock extends BlockBase implements ContainerFactoryPluginInterface, + + /** +@@ -302,7 +307,7 @@ class OgMenuBlock extends BlockBase implements ContainerFactoryPluginInterface, * The name of the menu, or null if no menu instance is found. */ public function getMenuName() { -- GitLab From 9113caecef72522e49cacef2352d24169743f3c5 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Fri, 27 Sep 2024 11:41:04 +0200 Subject: [PATCH 140/149] ISAICP-9104: Make sure that entity is an object. --- .../custom/joinup_group/src/Plugin/Block/GroupMenuBlock.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/modules/custom/joinup_group/src/Plugin/Block/GroupMenuBlock.php b/web/modules/custom/joinup_group/src/Plugin/Block/GroupMenuBlock.php index 08a572ef74..2d07b84043 100644 --- a/web/modules/custom/joinup_group/src/Plugin/Block/GroupMenuBlock.php +++ b/web/modules/custom/joinup_group/src/Plugin/Block/GroupMenuBlock.php @@ -172,14 +172,14 @@ protected function getEmptyResultsBuild(): array { } $disabled_message = ''; - if ($menu_instance->bundle() === 'navigation') { + if ($menu_instance instanceof OgMenuInstanceInterface && $menu_instance->bundle() === 'navigation') { $disabled_message = $this->t('All the pages have been disabled for this :type. You can <a href=":edit_menu_url">edit the menu configuration</a> or <a href=":add_page_url">add a new page</a>.', [ ':type' => $group->get('rid')->entity->getSingularLabel(), ':edit_menu_url' => $edit_navigation_menu_url, ':add_page_url' => $create_custom_page_url->toString(), ]); } - elseif ($menu_instance->bundle() === 'quick_links') { + elseif ($menu_instance instanceof OgMenuInstanceInterface && $menu_instance->bundle() === 'quick_links') { $disabled_message = $this->t('There are not any links to show. You can manage the quick links items through the <a href=":edit_menu_url">Edit menu</a> or you can add your links through the <a href=":group_edit">Edit page</a>.', [ -- GitLab From 13e0b92a3770436a2da7563a86034cf24f2016a2 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 30 Sep 2024 11:54:22 +0200 Subject: [PATCH 141/149] ISAICP-8999: Update composer.lock. --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index f51e7f2820..0b9308e5ca 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ad7a14f341be9f05de92f5b324b99667", + "content-hash": "141c36a2fdf20a315ac3d38d1295440c", "packages": [ { "name": "asm89/stack-cors", -- GitLab From a36673a07dff90badd7516346b4cf5719474f224 Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Mon, 30 Sep 2024 13:36:41 +0200 Subject: [PATCH 142/149] ISAICP-8592: Delete workflow_state_permission. --- .../workflow_state_permission.install | 48 ------------------- 1 file changed, 48 deletions(-) delete mode 100644 web/modules/custom/workflow_state_permission/workflow_state_permission.install diff --git a/web/modules/custom/workflow_state_permission/workflow_state_permission.install b/web/modules/custom/workflow_state_permission/workflow_state_permission.install deleted file mode 100644 index badb9082db..0000000000 --- a/web/modules/custom/workflow_state_permission/workflow_state_permission.install +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -/** - * @file - * Install, update, uninstall tasks for workflow_state_permission module. - */ - -declare(strict_types=1); - -use Drupal\Component\Render\MarkupInterface; -use Drupal\Core\StringTranslation\PluralTranslatableMarkup; - -/** - * Cleanup role permissions (prevents issues on config import). - */ -function workflow_state_permission_update_91001(): ?MarkupInterface { - // Verbatim copy from user module. - /* @see user_update_10000 */ - $cleaned_roles = []; - $existing_permissions = array_keys(\Drupal::service('user.permissions')->getPermissions()); - $config_factory = \Drupal::configFactory(); - $role_ids = $config_factory->listAll('user.role.'); - foreach ($role_ids as $role_id) { - $role_config = $config_factory->getEditable($role_id); - $removed_permissions = array_diff($role_config->get('permissions'), $existing_permissions); - if (!empty($removed_permissions)) { - $cleaned_roles[] = $role_config->get('label'); - \Drupal::logger('update')->notice('The role %role has had the following non-existent permission(s) removed: %permissions.', [ - '%role' => $role_config->get('label'), - '%permissions' => implode(', ', $removed_permissions), - ]); - $permissions = array_intersect($role_config->get('permissions'), $existing_permissions); - $role_config->set('permissions', $permissions); - $role_config->save(); - } - } - - if (!empty($cleaned_roles)) { - return new PluralTranslatableMarkup( - count($cleaned_roles), - 'The role %role_list has had non-existent permissions removed. Check the logs for details.', - 'The roles %role_list have had non-existent permissions removed. Check the logs for details.', - ['%role_list' => implode(', ', $cleaned_roles)] - ); - } - - return NULL; -} -- GitLab From 2dc10e62df8febce67c9021c34674c2b3a15e59b Mon Sep 17 00:00:00 2001 From: Adrian Lorenc <adrian.lorenc@gmail.com> Date: Tue, 1 Oct 2024 13:28:17 +0200 Subject: [PATCH 143/149] ISAICP-9121: Logo can be null. --- web/modules/custom/joinup_group/src/Form/AnnouncementForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php index 230e22049e..5eae7d5f36 100644 --- a/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php +++ b/web/modules/custom/joinup_group/src/Form/AnnouncementForm.php @@ -319,7 +319,7 @@ protected function getArguments(): array { 'value' => $group->toUrl('member-overview')->setAbsolute()->toString(), ], '@group_logo' => [ - 'value' => $group->getLogoAsUrl()->setAbsolute()->toString(), + 'value' => $group->getLogoAsUrl()?->setAbsolute()->toString(), ], '@author_name' => [ 'value' => $sender->getDisplayName(), -- GitLab From 666256e0b6a74a318d74bab01988da4a4013a530 Mon Sep 17 00:00:00 2001 From: zolhorvath <zolhorvath@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:09:16 +0200 Subject: [PATCH 144/149] ISAICP-9125: Ugrade diff to 1.8, also modifying the constraint in composer.json --- composer.json | 2 +- composer.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 49f2d25334..81f39651fa 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "drupal/core-composer-scaffold": "~10.3.0", "drupal/custom_markup_block": "^1.2", "drupal/default_content": "^2.0", - "drupal/diff": "~1.0", + "drupal/diff": "^1.8", "drupal/digital_size_formatter": "~2.0", "drupal/dropsolid_purge": "^1.0@beta", "drupal/dynamic_entity_reference": "^4.0", diff --git a/composer.lock b/composer.lock index 0b9308e5ca..54080b0d17 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "141c36a2fdf20a315ac3d38d1295440c", + "content-hash": "0ad7f865b6bfc92d03ae784fa8e78517", "packages": [ { "name": "asm89/stack-cors", @@ -2939,17 +2939,17 @@ }, { "name": "drupal/diff", - "version": "1.7.0", + "version": "1.8.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/diff.git", - "reference": "8.x-1.7" + "reference": "8.x-1.8" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/diff-8.x-1.7.zip", - "reference": "8.x-1.7", - "shasum": "d282bdf3350ac71f95b38576a9f397bdbab8d249" + "url": "https://ftp.drupal.org/files/projects/diff-8.x-1.8.zip", + "reference": "8.x-1.8", + "shasum": "a104bf731a282f06ff0d5a7fb861c01b5b933765" }, "require": { "drupal/core": "^10 || ^11", @@ -2964,13 +2964,13 @@ "phpstan/phpstan-deprecation-rules": "*", "phpstan/phpstan-phpunit": "1.4.x-dev", "phpstan/phpstan-strict-rules": "^1@stable", - "previousnext/coding-standard": "^1" + "previousnext/coding-standard": "1.0.1" }, "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.7", - "datestamp": "1718073570", + "version": "8.x-1.8", + "datestamp": "1727892285", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" -- GitLab From 41661a0afb0ecbfb98b088fbc21c4c3bd35c4a3f Mon Sep 17 00:00:00 2001 From: zolhorvath <zolhorvath@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:09:52 +0200 Subject: [PATCH 145/149] ISAICP-9125: Also add changes happened to web/autoload.php --- web/autoload.php | 1 - 1 file changed, 1 deletion(-) diff --git a/web/autoload.php b/web/autoload.php index 2c470f3395..7379151d9f 100644 --- a/web/autoload.php +++ b/web/autoload.php @@ -10,7 +10,6 @@ * @see index.php * @see core/install.php * @see core/rebuild.php - * @see core/modules/statistics/statistics.php */ return require __DIR__ . '/../vendor/autoload.php'; -- GitLab From cf160e89cc2243f546c5d6c87d76c1ffc87a11e3 Mon Sep 17 00:00:00 2001 From: zolhorvath <zolhorvath@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:13:18 +0200 Subject: [PATCH 146/149] ISAICP-9125: Ugrade twig/twig to 3.14.0 --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 54080b0d17..caa612ca9e 100644 --- a/composer.lock +++ b/composer.lock @@ -17386,16 +17386,16 @@ }, { "name": "twig/twig", - "version": "v3.12.0", + "version": "v3.14.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea" + "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea", - "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", + "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", "shasum": "" }, "require": { @@ -17449,7 +17449,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.12.0" + "source": "https://github.com/twigphp/Twig/tree/v3.14.0" }, "funding": [ { @@ -17461,7 +17461,7 @@ "type": "tidelift" } ], - "time": "2024-08-29T09:51:12+00:00" + "time": "2024-09-09T17:55:12+00:00" }, { "name": "webflo/drupal-finder", -- GitLab From fb8b535743888ee506bce1318087174cd5373726 Mon Sep 17 00:00:00 2001 From: zolhorvath <zolhorvath@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:43:56 +0200 Subject: [PATCH 147/149] ISAICP-9125: Suppress CVE-2024-45440 --- composer.json | 6 ++++ composer.lock | 76 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index 81f39651fa..085dc58fdb 100644 --- a/composer.json +++ b/composer.json @@ -197,6 +197,12 @@ "php-http/discovery": true, "ec-europa/toolkit-composer-plugin": true, "phpro/grumphp-shim": true + }, + "audit": { + "abandoned": "report", + "ignore": { + "CVE-2024-45440": "Seems to be a disputed report @see https://www.drupal.org/i/3471501#comment-15756190" + } } }, "autoload": { diff --git a/composer.lock b/composer.lock index caa612ca9e..85fff84aa5 100644 --- a/composer.lock +++ b/composer.lock @@ -1808,7 +1808,7 @@ ], "authors": [ { - "name": "AjitS", + "name": "ajits", "homepage": "https://www.drupal.org/user/981944" }, { @@ -1851,6 +1851,10 @@ "name": "prabeen.giri", "homepage": "https://www.drupal.org/user/913078" }, + { + "name": "scott_earnest", + "homepage": "https://www.drupal.org/user/416158" + }, { "name": "str8", "homepage": "https://www.drupal.org/user/2865063" @@ -3814,11 +3818,11 @@ "homepage": "https://www.drupal.org/user/124705" }, { - "name": "Nick_vh", + "name": "nick_vh", "homepage": "https://www.drupal.org/user/122682" }, { - "name": "StryKaizer", + "name": "strykaizer", "homepage": "https://www.drupal.org/user/462700" } ], @@ -4127,13 +4131,21 @@ ], "authors": [ { - "name": "Anybody", + "name": "anybody", "homepage": "https://www.drupal.org/user/291091" }, { - "name": "Hydra", + "name": "grevil", + "homepage": "https://www.drupal.org/user/3668491" + }, + { + "name": "hydra", "homepage": "https://www.drupal.org/user/647364" }, + { + "name": "joevagyok", + "homepage": "https://www.drupal.org/user/2876343" + }, { "name": "jyve", "homepage": "https://www.drupal.org/user/591438" @@ -4566,11 +4578,11 @@ "email": "geerlingguy@mac.com" }, { - "name": "Manuel Garcia", + "name": "manuel garcia", "homepage": "https://www.drupal.org/user/213194" }, { - "name": "TR", + "name": "tr", "homepage": "https://www.drupal.org/user/202830" }, { @@ -5559,7 +5571,7 @@ "homepage": "https://www.drupal.org/user/410199" }, { - "name": "JeroenT", + "name": "jeroent", "homepage": "https://www.drupal.org/user/2228934" }, { @@ -5730,6 +5742,10 @@ "GPL-2.0+" ], "authors": [ + { + "name": "bluegeek9", + "homepage": "https://www.drupal.org/user/1286304" + }, { "name": "febbraro", "homepage": "https://www.drupal.org/user/43670" @@ -6003,7 +6019,7 @@ "role": "Developer" }, { - "name": "Dave Reid", + "name": "dave reid", "homepage": "https://www.drupal.org/user/53892" } ], @@ -6747,11 +6763,11 @@ "homepage": "https://www.drupal.org/user/1295980" }, { - "name": "Berdir", + "name": "berdir", "homepage": "https://www.drupal.org/user/214652" }, { - "name": "BramDriesen", + "name": "bramdriesen", "homepage": "https://www.drupal.org/user/3383264" }, { @@ -7587,7 +7603,11 @@ "role": "Maintainer" }, { - "name": "JeroenT", + "name": "benjy", + "homepage": "https://www.drupal.org/user/1852732" + }, + { + "name": "jeroent", "homepage": "https://www.drupal.org/user/2228934" } ], @@ -8046,7 +8066,7 @@ "homepage": "https://www.drupal.org/user/124705" }, { - "name": "Nick_vh", + "name": "nick_vh", "homepage": "https://www.drupal.org/user/122682" } ], @@ -8154,7 +8174,7 @@ "homepage": "https://www.drupal.org/user/56348" }, { - "name": "Neslee Canil Pinto", + "name": "neslee canil pinto", "homepage": "https://www.drupal.org/user/3580850" } ], @@ -8712,6 +8732,18 @@ { "name": "See contributors", "homepage": "https://www.drupal.org/node/2887125/committers" + }, + { + "name": "imyaro", + "homepage": "https://www.drupal.org/user/2870933" + }, + { + "name": "mably", + "homepage": "https://www.drupal.org/user/3375160" + }, + { + "name": "thomas.frobieter", + "homepage": "https://www.drupal.org/user/409335" } ], "description": "Overrides the standard image formatter and widget to support SVG files.", @@ -9144,7 +9176,7 @@ ], "authors": [ { - "name": "Christian.wiedemann", + "name": "christian.wiedemann", "homepage": "https://www.drupal.org/user/861002" } ], @@ -9440,7 +9472,7 @@ "homepage": "https://www.drupal.org/u/graber" }, { - "name": "Graber", + "name": "graber", "homepage": "https://www.drupal.org/user/1599440" }, { @@ -9667,7 +9699,7 @@ "role": "Contributor" }, { - "name": "Liam Morland", + "name": "liam morland", "homepage": "https://www.drupal.org/user/493050" }, { @@ -25036,7 +25068,7 @@ }, "dist": { "type": "zip", - "url": "https://git.drupalcode.org/api/v4/projects/project%2Fdtt/repository/archive.zip?sha=eff79539951416dd3ef49cc355804a37aa70c280", + "url": "https://git.drupalcode.org/api/v4/projects/project%2Fdtt/repository/archive.zip?sha=d985fae238c6e3f6efa3f4142be6a4380b2a7a9e", "reference": "eff79539951416dd3ef49cc355804a37aa70c280", "shasum": "" }, @@ -25044,8 +25076,10 @@ "php": ">=8.1" }, "require-dev": { - "drush/drush": "^12.5", - "phpspec/prophecy-phpunit": "^2" + "drupal/mailsystem": "^4", + "drush/drush": "^12.5 || ^13", + "phpspec/prophecy-phpunit": "^2", + "webflo/drupal-finder": "^1.3.1" }, "default-branch": true, "type": "library", @@ -25083,7 +25117,7 @@ ], "description": "Traits for testing Drupal sites that have user content (versus unpopulated sites).", "support": { - "source": "https://git.drupalcode.org/project/dtt/-/tree/2.x" + "source": "https://git.drupalcode.org/project/dtt/-/tree/2.4.0" }, "time": "2024-08-24T15:19:02+00:00" }, -- GitLab From ed5b4eed1a7e318626ca1ac998335614d816738f Mon Sep 17 00:00:00 2001 From: zolhorvath <zolhorvath@users.noreply.github.com> Date: Thu, 3 Oct 2024 12:23:26 +0200 Subject: [PATCH 148/149] ISAICP-9126: Update subscription form lead text of closed collections with CoC --- .../collection/collection.membership_signup_leave.feature | 2 +- .../custom/collection/src/Form/SubscribeToCollectionForm.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/features/collection/collection.membership_signup_leave.feature b/tests/features/collection/collection.membership_signup_leave.feature index 69c3b726e6..90c95b7236 100644 --- a/tests/features/collection/collection.membership_signup_leave.feature +++ b/tests/features/collection/collection.membership_signup_leave.feature @@ -84,7 +84,7 @@ Feature: Joining and leaving collections through the web interface # There is a Code of Conduct document, what the user must accept before # requesting for membership, so the button text must not change. Then I should see the button "Join this collection" in the Header region - And I should see the text "To complete your membership, we need to make sure you agree with our Code of conduct. This helps us maintain a safe and respectful environment for all members of Closed collection with public CoC" + And I should see the text "To validate your membership and send it for approval, please tick the box agreeing with the Code of conduct. This helps us maintain a safe and respectful environment for all members of Closed collection with public CoC" And I should not see the following lines of text: | You have joined the collection and you are now able to publish content in it. | | When your membership is approved you will be able to publish content in it. | diff --git a/web/modules/custom/collection/src/Form/SubscribeToCollectionForm.php b/web/modules/custom/collection/src/Form/SubscribeToCollectionForm.php index 6a467ba0e4..a1cbca70c6 100644 --- a/web/modules/custom/collection/src/Form/SubscribeToCollectionForm.php +++ b/web/modules/custom/collection/src/Form/SubscribeToCollectionForm.php @@ -247,7 +247,7 @@ protected function getCodeOfConductComponents(?RdfInterface $collection): ?array $codeOfConductComponents['code_of_conduct_lead'] = [ '#type' => 'item', '#markup' => $this->t( - 'To complete your membership, we need to make sure you agree with our <a href=":code-of-conduct-url" target="_blank">Code of conduct</a>. This helps us maintain a safe and respectful environment for all members of @group-label', + 'To validate your membership and send it for approval, please tick the box agreeing with the <a href=":code-of-conduct-url" target="_blank">Code of conduct</a>. This helps us maintain a safe and respectful environment for all members of @group-label.', $codeOfConductArgs, ), '#weight' => -5, -- GitLab From d25a6b035653c2eb58d056cce6a85256f5430c4a Mon Sep 17 00:00:00 2001 From: Claudiu Cristea <clau.cristea@gmail.com> Date: Mon, 7 Oct 2024 12:15:56 +0200 Subject: [PATCH 149/149] ISAICP-9143: Temporarily, disable the OSS cron test. --- phpunit.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpunit.xml b/phpunit.xml index 23a353ae00..504193aa73 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -59,6 +59,8 @@ <directory>web/modules/custom/**/modules/**/tests/src/Kernel</directory> <!-- WIP --> <exclude>web/modules/custom/joinup_stats/tests/src/Kernel/RefreshCountersTest.php</exclude> + <!-- Remove in https://citnet.tech.ec.europa.eu/CITnet/jira/browse/ISAICP-9142 --> + <exclude>web/modules/custom/eu_oss_catalogue/tests/src/Kernel/CronTimingTest.php</exclude> </testsuite> <testsuite name="functional"> <directory>web/modules/custom/**/tests/src/Functional</directory> -- GitLab