diff --git a/composer.lock b/composer.lock index c479d6171..6778ccbcc 100644 --- a/composer.lock +++ b/composer.lock @@ -2535,16 +2535,16 @@ }, { "name": "drupal/core", - "version": "11.3.5", + "version": "11.3.8", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "6de8a6ff360ad1c2719af077259c3ef77ba3d23f" + "reference": "d40f45fa436fb089cd54029d2dab387c3040fc2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/6de8a6ff360ad1c2719af077259c3ef77ba3d23f", - "reference": "6de8a6ff360ad1c2719af077259c3ef77ba3d23f", + "url": "https://api.github.com/repos/drupal/core/zipball/d40f45fa436fb089cd54029d2dab387c3040fc2c", + "reference": "d40f45fa436fb089cd54029d2dab387c3040fc2c", "shasum": "" }, "require": { @@ -2702,13 +2702,13 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/11.3.5" + "source": "https://github.com/drupal/core/tree/11.3.8" }, - "time": "2026-03-06T09:54:42+00:00" + "time": "2026-04-20T07:33:20+00:00" }, { "name": "drupal/core-composer-scaffold", - "version": "11.3.5", + "version": "11.3.8", "source": { "type": "git", "url": "https://github.com/drupal/core-composer-scaffold.git", @@ -2752,7 +2752,7 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-composer-scaffold/tree/11.3.5" + "source": "https://github.com/drupal/core-composer-scaffold/tree/11.3.8" }, "time": "2026-02-10T11:39:53+00:00" }, @@ -2815,26 +2815,26 @@ }, { "name": "drupal/csp", - "version": "2.2.2", + "version": "2.2.3", "source": { "type": "git", "url": "https://git.drupalcode.org/project/csp.git", - "reference": "2.2.2" + "reference": "2.2.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/csp-2.2.2.zip", - "reference": "2.2.2", - "shasum": "4ae305859e6997c62296ddbeee480ba619557fe8" + "url": "https://ftp.drupal.org/files/projects/csp-2.2.3.zip", + "reference": "2.2.3", + "shasum": "a02939b221ecb66273530d7be3b2a287f897fa3c" }, "require": { - "drupal/core": "^10.2 || ^11" + "drupal/core": "^11.2 || ^12" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.2.2", - "datestamp": "1741822236", + "version": "2.2.3", + "datestamp": "1776729271", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3815,17 +3815,17 @@ }, { "name": "drupal/external_entities", - "version": "3.0.0-rc1", + "version": "3.0.0-rc2", "source": { "type": "git", "url": "https://git.drupalcode.org/project/external_entities.git", - "reference": "3.0.0-rc1" + "reference": "3.0.0-rc2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/external_entities-3.0.0-rc1.zip", - "reference": "3.0.0-rc1", - "shasum": "7319be341c37a0763a32815edba1a98081efc11e" + "url": "https://ftp.drupal.org/files/projects/external_entities-3.0.0-rc2.zip", + "reference": "3.0.0-rc2", + "shasum": "a6e1f6e0194bdad17b41f258772e829edeb3e220" }, "require": { "drupal/core": "^10 || ^11", @@ -3838,8 +3838,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "3.0.0-rc1", - "datestamp": "1769878913", + "version": "3.0.0-rc2", + "datestamp": "1776284356", "security-coverage": { "status": "not-covered", "message": "RC releases are not covered by Drupal security advisories." @@ -4357,16 +4357,16 @@ }, { "name": "drupal/hdbt", - "version": "6.16.60", + "version": "6.16.70", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-hdbt.git", - "reference": "65ed94c157f3e1c02a77a35aeed75110142008ac" + "reference": "b30aa236a9a992b9f53adfb0bd72e25fcb0c7d94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt/zipball/65ed94c157f3e1c02a77a35aeed75110142008ac", - "reference": "65ed94c157f3e1c02a77a35aeed75110142008ac", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt/zipball/b30aa236a9a992b9f53adfb0bd72e25fcb0c7d94", + "reference": "b30aa236a9a992b9f53adfb0bd72e25fcb0c7d94", "shasum": "" }, "require": { @@ -4385,10 +4385,10 @@ "Drupal" ], "support": { - "source": "https://github.com/City-of-Helsinki/drupal-hdbt/tree/6.16.60", + "source": "https://github.com/City-of-Helsinki/drupal-hdbt/tree/6.16.70", "issues": "https://github.com/City-of-Helsinki/drupal-hdbt/issues" }, - "time": "2026-04-02T13:27:44+00:00" + "time": "2026-04-21T07:27:59+00:00" }, { "name": "drupal/hdbt_admin", @@ -4479,16 +4479,16 @@ }, { "name": "drupal/helfi_api_base", - "version": "2.8.15", + "version": "2.8.19", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base.git", - "reference": "1b0a72acbc78b4c95c0f760eb806ef2908156d64" + "reference": "989784a16b9f4336a67e8d2c33e71f44813bd45d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-api-base/zipball/1b0a72acbc78b4c95c0f760eb806ef2908156d64", - "reference": "1b0a72acbc78b4c95c0f760eb806ef2908156d64", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-api-base/zipball/989784a16b9f4336a67e8d2c33e71f44813bd45d", + "reference": "989784a16b9f4336a67e8d2c33e71f44813bd45d", "shasum": "" }, "require": { @@ -4497,7 +4497,8 @@ "drupal/entity": "^1.0", "drupal/health_check": "^3.0", "drupal/monolog": "^3.0", - "drupal/raven": "^5.0 || ^6.0", + "drupal/raven": "^6.0 || ^7.0", + "drupal/redis": "^1.0", "ext-curl": "*", "firebase/php-jwt": "^7.0", "php": "^8.1", @@ -4530,10 +4531,10 @@ ], "description": "Helfi - API Base", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/tree/2.8.15", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/tree/2.8.19", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/issues" }, - "time": "2026-04-07T06:25:24+00:00" + "time": "2026-04-21T08:39:47+00:00" }, { "name": "drupal/helfi_azure_fs", @@ -4661,16 +4662,16 @@ }, { "name": "drupal/helfi_hakuvahti", - "version": "1.2.3", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti.git", - "reference": "fc44c07faf61c24f8f6238fa2a9d7380e90f80b4" + "reference": "f6e86aa805455f2a736a9f9bb7bb23f0647bda1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-hakuvahti/zipball/fc44c07faf61c24f8f6238fa2a9d7380e90f80b4", - "reference": "fc44c07faf61c24f8f6238fa2a9d7380e90f80b4", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-hakuvahti/zipball/f6e86aa805455f2a736a9f9bb7bb23f0647bda1b", + "reference": "f6e86aa805455f2a736a9f9bb7bb23f0647bda1b", "shasum": "" }, "require": { @@ -4686,10 +4687,10 @@ ], "description": "Helfi - Hakuvahti", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti/tree/1.2.3", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti/tree/1.2.4", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti/issues" }, - "time": "2026-03-23T09:43:42+00:00" + "time": "2026-04-13T12:35:08+00:00" }, { "name": "drupal/helfi_navigation", @@ -4727,16 +4728,16 @@ }, { "name": "drupal/helfi_platform_config", - "version": "5.1.35", + "version": "5.1.42", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config.git", - "reference": "ce367bb2c3fd801c0ffa421e6f17328932bda0b1" + "reference": "90ea1221ee2bb76d7bf4966d0888ed876809cce4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/ce367bb2c3fd801c0ffa421e6f17328932bda0b1", - "reference": "ce367bb2c3fd801c0ffa421e6f17328932bda0b1", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/90ea1221ee2bb76d7bf4966d0888ed876809cce4", + "reference": "90ea1221ee2bb76d7bf4966d0888ed876809cce4", "shasum": "" }, "require": { @@ -4806,6 +4807,7 @@ "symfony/property-access": "^7.3" }, "conflict": { + "drupal/core": "<11.3.8", "drupal/external_entities": "<3.0.0-beta7", "drush/drush": "<12" }, @@ -4815,11 +4817,11 @@ "drupal/core": { "[#UHF-12709] Patch 'Deleted and replaced ...' error messages": "./public/modules/contrib/helfi_platform_config/patches/UHF-12709-skip_deleted_and_replaced_log.patch", "[#UHF-181] Hide untranslated menu links (https://www.drupal.org/project/drupal/issues/3091246)": "./public/modules/contrib/helfi_platform_config/patches/3091246.patch", - "[#UHF-3812] Ajax exposed filters not working for multiple instances of the same Views block placed on one page (https://www.drupal.org/project/drupal/issues/3163299)": "https://www.drupal.org/files/issues/2023-05-07/3163299-104-D10.patch", + "[#UHF-3812] Ajax exposed filters not working for multiple instances of the same Views block placed on one page (https://www.drupal.org/project/drupal/issues/3163299)": "./public/modules/contrib/helfi_platform_config/patches/3163299-104-D10.patch", "[#UHF-4325] Strip whitespaces from twig debug comments": "./public/modules/contrib/helfi_platform_config/patches/drupal_core_strip_debug_mode_whitespaces_11.3.x.patch", "[#UHF-7008] Add multilingual support for caching basefield definitions (https://www.drupal.org/project/drupal/issues/3114824)": "./public/modules/contrib/helfi_platform_config/patches/3114824.patch", "[#UHF-7008] Admin toolbar and contextual links should always be rendered in the admin language (https://www.drupal.org/project/drupal/issues/2313309)": "./public/modules/contrib/helfi_platform_config/patches/2313309.patch", - "[#UHF-9690] Allow updating lists when switching from allowed values to allowed values function (https://www.drupal.org/i/2873353)": "https://www.drupal.org/files/issues/2025-06-27/allow-allowed-values-function-update-2873353-20.patch", + "[#UHF-9690] Allow updating lists when switching from allowed values to allowed values function (https://www.drupal.org/i/2873353)": "./public/modules/contrib/helfi_platform_config/patches/2873353-20.patch", "[#UHF-9952, #UHF-9980] Duplicate
tags (https://www.drupal.org/i/3083786)": "./public/modules/contrib/helfi_platform_config/patches/3083786.patch", "[#UHF-11025] Status message templates missing theme when bigpipe is enabled (https://www.drupal.org/i/3396318)": "./public/modules/contrib/helfi_platform_config/patches/3396318.patch", "[#UHF-11784] Sort the source and target arrays in the configuration storage comparer to avoid false positives": "./public/modules/contrib/helfi_platform_config/patches/drupal-core-sort-storage-comparer-source-and-target-arrays.patch" @@ -4837,7 +4839,7 @@ "https://www.drupal.org/project/default_content/issues/2640734#comment-14638943": "./public/modules/contrib/helfi_platform_config/patches/default_content_2.0.0-alpha3-2640734_manual_imports.patch" }, "drupal/paragraphs": { - "https://www.drupal.org/project/paragraphs/issues/2904705#comment-13836790": "https://www.drupal.org/files/issues/2020-09-25/2904705-115.patch", + "https://www.drupal.org/project/paragraphs/issues/2904705#comment-13836790": "./public/modules/contrib/helfi_platform_config/patches/2904705-115.patch", "[#UHF-2059] Enhancements for the Admin UI": "./public/modules/contrib/helfi_platform_config/patches/helfi_customizations_for_paragraphs_widget_8.x-1.12.patch", "[#UHF-10840] https://www.drupal.org/i/3510842: Duplicating nested paragraph overwriting paragraph references": "./public/modules/contrib/helfi_platform_config/patches/paragraphs-3510842-duplicate_paragraph_overwrite.patch" }, @@ -4851,23 +4853,23 @@ ], "description": "HELfi platform config", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/5.1.35", + "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/5.1.42", "issues": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/issues" }, - "time": "2026-04-08T06:21:41+00:00" + "time": "2026-04-21T10:23:14+00:00" }, { "name": "drupal/helfi_proxy", - "version": "3.4.0", + "version": "3.4.1", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-proxy.git", - "reference": "f3f460548b0848d22bd889f4826b825e4aa103f6" + "reference": "7cfd008ab8668254f2522ee9bef8e9008c90425a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-proxy/zipball/f3f460548b0848d22bd889f4826b825e4aa103f6", - "reference": "f3f460548b0848d22bd889f4826b825e4aa103f6", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-proxy/zipball/7cfd008ab8668254f2522ee9bef8e9008c90425a", + "reference": "7cfd008ab8668254f2522ee9bef8e9008c90425a", "shasum": "" }, "require": { @@ -4897,10 +4899,10 @@ ], "description": "Provides various fixes so we can serve multiple Drupal instances in one domain.", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-proxy/tree/3.4.0", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-proxy/tree/3.4.1", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-proxy/issues" }, - "time": "2025-11-21T14:03:03+00:00" + "time": "2026-04-21T07:08:58+00:00" }, { "name": "drupal/helfi_tpr", @@ -6317,33 +6319,33 @@ }, { "name": "drupal/raven", - "version": "6.0.16", + "version": "7.3.8", "source": { "type": "git", "url": "https://git.drupalcode.org/project/raven.git", - "reference": "6.0.16" + "reference": "7.3.8" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/raven-6.0.16.zip", - "reference": "6.0.16", - "shasum": "7859678b6c935afbdacf72f5ca3508784d9b0948" + "url": "https://ftp.drupal.org/files/projects/raven-7.3.8.zip", + "reference": "7.3.8", + "shasum": "78e4219650a9b49a7f35ae165cb8d6077ceb46bc" }, "require": { - "drupal/core": "^10.2 || ^11", - "sentry/sentry": "^4.9" + "drupal/core": "^11.1", + "sentry/sentry": "^4.20" }, "require-dev": { "drupal/csp": "^1.17 || ^2.0", "drupal/monitoring": "^1.13", "drupal/seckit": "^2.0", - "drush/drush": "^11.0 || ^12.0 || ^13.0" + "drush/drush": "^13.0" }, "type": "drupal-module", "extra": { "drupal": { - "version": "6.0.16", - "datestamp": "1755300523", + "version": "7.3.8", + "datestamp": "1775584686", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -6372,6 +6374,10 @@ "type": "github", "url": "https://github.com/sponsors/mfb" }, + { + "type": "ko-fi", + "url": "https://ko-fi.com/mfb" + }, { "type": "patreon", "url": "https://www.patreon.com/mfb" @@ -8373,12 +8379,12 @@ "version": "v7.0.5", "source": { "type": "git", - "url": "https://github.com/firebase/php-jwt.git", + "url": "https://github.com/googleapis/php-jwt.git", "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/47ad26bab5e7c70ae8a6f08ed25ff83631121380", + "url": "https://api.github.com/repos/googleapis/php-jwt/zipball/47ad26bab5e7c70ae8a6f08ed25ff83631121380", "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380", "shasum": "" }, @@ -8427,8 +8433,8 @@ "php" ], "support": { - "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v7.0.5" + "issues": "https://github.com/googleapis/php-jwt/issues", + "source": "https://github.com/googleapis/php-jwt/tree/v7.0.5" }, "time": "2026-04-01T20:38:03+00:00" }, @@ -8979,16 +8985,16 @@ }, { "name": "laravel/prompts", - "version": "v0.3.16", + "version": "v0.3.17", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2" + "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/11e7d5f93803a2190b00e145142cb00a33d17ad2", - "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2", + "url": "https://api.github.com/repos/laravel/prompts/zipball/6a82ac19a28b916ae0885828795dbd4c59d9a818", + "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818", "shasum": "" }, "require": { @@ -9032,9 +9038,9 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.16" + "source": "https://github.com/laravel/prompts/tree/v0.3.17" }, - "time": "2026-03-23T14:35:33+00:00" + "time": "2026-04-20T16:07:33+00:00" }, { "name": "league/container", @@ -10011,6 +10017,84 @@ }, "time": "2025-12-06T11:56:16+00:00" }, + { + "name": "nyholm/psr7", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2024-09-09T07:06:30+00:00" + }, { "name": "open-telemetry/api", "version": "1.9.0", @@ -11359,35 +11443,36 @@ }, { "name": "phrity/websocket", - "version": "3.6.2", + "version": "3.7.0", "source": { "type": "git", "url": "https://github.com/sirn-se/websocket-php.git", - "reference": "b9816ed2b4a10c8c42bd0b6398044ab506869756" + "reference": "01f15374987d8281dba0ca511f322a0e18229330" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sirn-se/websocket-php/zipball/b9816ed2b4a10c8c42bd0b6398044ab506869756", - "reference": "b9816ed2b4a10c8c42bd0b6398044ab506869756", + "url": "https://api.github.com/repos/sirn-se/websocket-php/zipball/01f15374987d8281dba0ca511f322a0e18229330", + "reference": "01f15374987d8281dba0ca511f322a0e18229330", "shasum": "" }, "require": { + "nyholm/psr7": "^1.4", "php": "^8.1", - "phrity/http": "^1.0", - "phrity/net-stream": "^2.3", + "phrity/http": "^1.1", + "phrity/net-stream": "^2.4", "phrity/net-uri": "^2.1", - "psr/http-message": "^1.1 | ^2.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "psr/log": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { - "guzzlehttp/psr7": "^2.0", "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0 || ^13.0", "phrity/logger-console": "^1.0", - "phrity/net-mock": "^2.3", + "phrity/net-mock": "^2.4", "phrity/util-errorhandler": "^1.1", "robiningelbrecht/phpunit-coverage-tools": "^1.9", - "squizlabs/php_codesniffer": "^3.5 || ^4.0" + "squizlabs/php_codesniffer": "^4.0" }, "type": "library", "autoload": { @@ -11418,9 +11503,9 @@ ], "support": { "issues": "https://github.com/sirn-se/websocket-php/issues", - "source": "https://github.com/sirn-se/websocket-php/tree/3.6.2" + "source": "https://github.com/sirn-se/websocket-php/tree/3.7.0" }, - "time": "2025-12-21T09:58:16+00:00" + "time": "2026-04-06T18:18:14+00:00" }, { "name": "proj4php/proj4php", @@ -13367,16 +13452,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -13426,7 +13511,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.36.0" }, "funding": [ { @@ -13446,20 +13531,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "5f3b930437ae03ae5dff61269024d8ea1b3774aa" + "reference": "2c5729fd241b4b22f6e4b436bc3354a4f262df57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/5f3b930437ae03ae5dff61269024d8ea1b3774aa", - "reference": "5f3b930437ae03ae5dff61269024d8ea1b3774aa", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/2c5729fd241b4b22f6e4b436bc3354a4f262df57", + "reference": "2c5729fd241b4b22f6e4b436bc3354a4f262df57", "shasum": "" }, "require": { @@ -13510,7 +13595,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.36.0" }, "funding": [ { @@ -13530,20 +13615,20 @@ "type": "tidelift" } ], - "time": "2024-09-17T14:58:18+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/ad1b7b9092976d6c948b8a187cec9faaea9ec1df", + "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df", "shasum": "" }, "require": { @@ -13592,7 +13677,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.36.0" }, "funding": [ { @@ -13612,11 +13697,11 @@ "type": "tidelift" } ], - "time": "2025-06-27T09:58:17+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -13679,7 +13764,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.36.0" }, "funding": [ { @@ -13703,7 +13788,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -13764,7 +13849,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.36.0" }, "funding": [ { @@ -13788,16 +13873,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { @@ -13849,7 +13934,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.36.0" }, "funding": [ { @@ -13869,7 +13954,7 @@ "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/polyfill-php56", @@ -13941,7 +14026,7 @@ }, { "name": "symfony/polyfill-php81", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", @@ -13997,7 +14082,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.36.0" }, "funding": [ { @@ -14021,16 +14106,16 @@ }, { "name": "symfony/polyfill-php82", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php82.git", - "reference": "5d2ed36f7734637dacc025f179698031951b1692" + "reference": "34808efe3e68f69685796f7c253a2f1d8ea9df59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/5d2ed36f7734637dacc025f179698031951b1692", - "reference": "5d2ed36f7734637dacc025f179698031951b1692", + "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/34808efe3e68f69685796f7c253a2f1d8ea9df59", + "reference": "34808efe3e68f69685796f7c253a2f1d8ea9df59", "shasum": "" }, "require": { @@ -14077,7 +14162,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php82/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php82/tree/v1.36.0" }, "funding": [ { @@ -14097,20 +14182,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", "shasum": "" }, "require": { @@ -14157,7 +14242,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.36.0" }, "funding": [ { @@ -14177,20 +14262,20 @@ "type": "tidelift" } ], - "time": "2025-07-08T02:45:35+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", "shasum": "" }, "require": { @@ -14237,7 +14322,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.36.0" }, "funding": [ { @@ -14257,20 +14342,20 @@ "type": "tidelift" } ], - "time": "2025-06-24T13:30:11+00:00" + "time": "2026-04-10T18:47:49+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" + "reference": "2c408a6bb0313e6001a83628dc5506100474254e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/2c408a6bb0313e6001a83628dc5506100474254e", + "reference": "2c408a6bb0313e6001a83628dc5506100474254e", "shasum": "" }, "require": { @@ -14317,7 +14402,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.36.0" }, "funding": [ { @@ -14337,7 +14422,7 @@ "type": "tidelift" } ], - "time": "2025-06-23T16:12:55+00:00" + "time": "2026-04-10T16:50:15+00:00" }, { "name": "symfony/process", @@ -16141,16 +16226,16 @@ }, { "name": "composer/composer", - "version": "2.9.5", + "version": "2.9.7", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "72a8f8e653710e18d83e5dd531eb5a71fc3223e6" + "reference": "82a2fbd1372a98d7915cfb092acf05207d9b4113" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/72a8f8e653710e18d83e5dd531eb5a71fc3223e6", - "reference": "72a8f8e653710e18d83e5dd531eb5a71fc3223e6", + "url": "https://api.github.com/repos/composer/composer/zipball/82a2fbd1372a98d7915cfb092acf05207d9b4113", + "reference": "82a2fbd1372a98d7915cfb092acf05207d9b4113", "shasum": "" }, "require": { @@ -16238,7 +16323,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.9.5" + "source": "https://github.com/composer/composer/tree/2.9.7" }, "funding": [ { @@ -16250,7 +16335,7 @@ "type": "github" } ], - "time": "2026-01-29T10:40:53+00:00" + "time": "2026-04-14T11:31:52+00:00" }, { "name": "composer/metadata-minifier", @@ -16402,24 +16487,24 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.9", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "edf364cefe8c43501e21e88110aac10b284c3c9f" + "reference": "5ecd0cb4177696f9fd48f1605dda81db3dee7889" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/edf364cefe8c43501e21e88110aac10b284c3c9f", - "reference": "edf364cefe8c43501e21e88110aac10b284c3c9f", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/5ecd0cb4177696f9fd48f1605dda81db3dee7889", + "reference": "5ecd0cb4177696f9fd48f1605dda81db3dee7889", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^1.11", - "symfony/phpunit-bridge": "^3 || ^7" + "symfony/phpunit-bridge": "^6.4.25 || ^7.3.3 || ^8.0" }, "type": "library", "extra": { @@ -16462,7 +16547,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/spdx-licenses/issues", - "source": "https://github.com/composer/spdx-licenses/tree/1.5.9" + "source": "https://github.com/composer/spdx-licenses/tree/1.6.0" }, "funding": [ { @@ -16472,13 +16557,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2025-05-12T21:07:07+00:00" + "time": "2026-04-08T20:18:39+00:00" }, { "name": "composer/xdebug-handler", @@ -16796,7 +16877,7 @@ }, { "name": "drupal/core-dev", - "version": "11.3.5", + "version": "11.3.8", "source": { "type": "git", "url": "https://github.com/drupal/core-dev.git", @@ -16846,7 +16927,7 @@ ], "description": "require-dev dependencies from drupal/drupal; use in addition to drupal/core-recommended to run tests from drupal/core.", "support": { - "source": "https://github.com/drupal/core-dev/tree/11.3.5" + "source": "https://github.com/drupal/core-dev/tree/11.3.8" }, "time": "2026-02-04T09:01:40+00:00" }, @@ -18192,16 +18273,16 @@ }, { "name": "phpspec/prophecy", - "version": "v1.26.0", + "version": "v1.26.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "0da07c10d5fe64cd0c748f0523b47599400f2ed1" + "reference": "09c2e5949d676286358a62af818f8407167a9dd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/0da07c10d5fe64cd0c748f0523b47599400f2ed1", - "reference": "0da07c10d5fe64cd0c748f0523b47599400f2ed1", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/09c2e5949d676286358a62af818f8407167a9dd6", + "reference": "09c2e5949d676286358a62af818f8407167a9dd6", "shasum": "" }, "require": { @@ -18257,9 +18338,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.26.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.26.1" }, - "time": "2026-02-24T15:40:48+00:00" + "time": "2026-04-13T14:35:16+00:00" }, { "name": "phpspec/prophecy-phpunit", @@ -20890,7 +20971,7 @@ }, { "name": "symfony/polyfill-php73", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", @@ -20946,7 +21027,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.36.0" }, "funding": [ { @@ -20970,16 +21051,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.33.0", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { @@ -21030,7 +21111,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.36.0" }, "funding": [ { @@ -21050,7 +21131,7 @@ "type": "tidelift" } ], - "time": "2025-01-02T08:10:11+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "tbachert/spi", diff --git a/conf/cmi/core.entity_form_display.media.file.media_library.yml b/conf/cmi/core.entity_form_display.media.file.media_library.yml index 6d659d4e5..9fc58014b 100644 --- a/conf/cmi/core.entity_form_display.media.file.media_library.yml +++ b/conf/cmi/core.entity_form_display.media.file.media_library.yml @@ -7,7 +7,7 @@ dependencies: - field.field.media.file.field_media_file - media.type.file _core: - default_config_hash: PnLUWOfSDV2wuJomGo-wDi3ndC1-Rp_qhZ6roAFuz0M + default_config_hash: 1DAJx9kbI8ZYNr04x4oOKphGJpxCk-VvNy15kZ5-I6w id: media.file.media_library targetEntityType: media bundle: file diff --git a/conf/cmi/core.entity_form_display.media.hel_map.media_library.yml b/conf/cmi/core.entity_form_display.media.hel_map.media_library.yml index 89787e1ee..8a55f9deb 100644 --- a/conf/cmi/core.entity_form_display.media.hel_map.media_library.yml +++ b/conf/cmi/core.entity_form_display.media.hel_map.media_library.yml @@ -9,7 +9,7 @@ dependencies: module: - link _core: - default_config_hash: mB1qn09Anlv4NN5drGy-3Yp6eCU79CFve-VfKP_f7ag + default_config_hash: aRir_YGDHSxIqElevsVN6oe9_5_PkrcyWlJV5OoKKXQ id: media.hel_map.media_library targetEntityType: media bundle: hel_map diff --git a/conf/cmi/core.entity_form_display.media.helfi_chart.media_library.yml b/conf/cmi/core.entity_form_display.media.helfi_chart.media_library.yml index 33b0e5d50..0232c7521 100644 --- a/conf/cmi/core.entity_form_display.media.helfi_chart.media_library.yml +++ b/conf/cmi/core.entity_form_display.media.helfi_chart.media_library.yml @@ -11,7 +11,7 @@ dependencies: module: - text _core: - default_config_hash: 7I7JgqwSLHKPVnnYpmVSQ0-RS8tUb0ayNGVynJiS_Jg + default_config_hash: aW9n1OCAr-p3GfXOj_Hv9qDgEvMKCb1FUzLVQY4-xSc id: media.helfi_chart.media_library targetEntityType: media bundle: helfi_chart diff --git a/conf/cmi/core.entity_form_display.media.image.media_library.yml b/conf/cmi/core.entity_form_display.media.image.media_library.yml index 89b27e309..5590281cf 100644 --- a/conf/cmi/core.entity_form_display.media.image.media_library.yml +++ b/conf/cmi/core.entity_form_display.media.image.media_library.yml @@ -11,7 +11,7 @@ dependencies: module: - focal_point _core: - default_config_hash: sBZSklr6VL62q9muMdA81sfI53ReprPQkcd9IGCGEtI + default_config_hash: TJWhq-XZhpnNdLiW6qa38fYy05myTPDoAgni2M5RItg id: media.image.media_library targetEntityType: media bundle: image diff --git a/conf/cmi/core.entity_form_display.media.remote_video.media_library.yml b/conf/cmi/core.entity_form_display.media.remote_video.media_library.yml index d9379d3ae..9bdfc2093 100644 --- a/conf/cmi/core.entity_form_display.media.remote_video.media_library.yml +++ b/conf/cmi/core.entity_form_display.media.remote_video.media_library.yml @@ -8,7 +8,7 @@ dependencies: - field.field.media.remote_video.field_remote_video_videographer - media.type.remote_video _core: - default_config_hash: ICmLjt5WIfXzvtJX_YkRGdyKasNtsRCLGIjhuqkbCvw + default_config_hash: 07Od0-Y4xT12ZoyAWxsTuJ0u32DaNqma-0sjemx9Olo id: media.remote_video.media_library targetEntityType: media bundle: remote_video diff --git a/conf/cmi/core.entity_form_display.paragraph.from_library.default.yml b/conf/cmi/core.entity_form_display.paragraph.from_library.default.yml index e0f5996e3..2a6554609 100644 --- a/conf/cmi/core.entity_form_display.paragraph.from_library.default.yml +++ b/conf/cmi/core.entity_form_display.paragraph.from_library.default.yml @@ -7,6 +7,7 @@ dependencies: - paragraphs.paragraphs_type.from_library module: - select2 + - paragraphs_library _core: default_config_hash: RBhuX9npNnq2pmFG3bnj9977tRJQYZ1VTb45-BHjmqE id: paragraph.from_library.default diff --git a/conf/cmi/core.entity_form_display.paragraph.news_list.default.yml b/conf/cmi/core.entity_form_display.paragraph.news_list.default.yml index d630adeca..ffaff7056 100644 --- a/conf/cmi/core.entity_form_display.paragraph.news_list.default.yml +++ b/conf/cmi/core.entity_form_display.paragraph.news_list.default.yml @@ -15,7 +15,7 @@ dependencies: - select2 - text _core: - default_config_hash: qWEWZZ5y2CFa0KrsVWs0SgVKuOKv3M-yRvPSLqNqiE4 + default_config_hash: o9SMPuB22qt8yDE6vhZ1eXIIcS2ztzFjZiidMrswmCU id: paragraph.news_list.default targetEntityType: paragraph bundle: news_list diff --git a/conf/cmi/core.entity_view_display.media.file.media_library.yml b/conf/cmi/core.entity_view_display.media.file.media_library.yml index 0b118bb3d..ed6d8deb4 100644 --- a/conf/cmi/core.entity_view_display.media.file.media_library.yml +++ b/conf/cmi/core.entity_view_display.media.file.media_library.yml @@ -10,7 +10,7 @@ dependencies: module: - image _core: - default_config_hash: E6bdvTtEOpUnVMOmE-Zrnsb91guXE-JLQrL-Vx1q954 + default_config_hash: PGilb0gSRJYPI4L3JcMoiR-sZ4GnWGA594CtYJXWzFk id: media.file.media_library targetEntityType: media bundle: file diff --git a/conf/cmi/core.entity_view_display.media.hel_map.media_library.yml b/conf/cmi/core.entity_view_display.media.hel_map.media_library.yml index ee5c9a660..e1f554d60 100644 --- a/conf/cmi/core.entity_view_display.media.hel_map.media_library.yml +++ b/conf/cmi/core.entity_view_display.media.hel_map.media_library.yml @@ -9,7 +9,7 @@ dependencies: module: - helfi_media_map _core: - default_config_hash: xrAnYtkc8F-kZb6szt7sZHZ01BM1RnD-NfJ0bOtBTDs + default_config_hash: Z8YHS_atwbA0gO2P3uNNSbok6LicCJGZ5PNIM86COi0 id: media.hel_map.media_library targetEntityType: media bundle: hel_map diff --git a/conf/cmi/core.entity_view_display.media.helfi_chart.media_library.yml b/conf/cmi/core.entity_view_display.media.helfi_chart.media_library.yml index 02d79dfde..6dc1d41a8 100644 --- a/conf/cmi/core.entity_view_display.media.helfi_chart.media_library.yml +++ b/conf/cmi/core.entity_view_display.media.helfi_chart.media_library.yml @@ -11,7 +11,7 @@ dependencies: module: - helfi_media_chart _core: - default_config_hash: 28nwEZaRGXg0zD-nmyYusiqAx3gMir52iQG7f5pcyJM + default_config_hash: hR8QQbn1tM3s7PON49lzBRowMWmFCL-7gk8kpjXECQ0 id: media.helfi_chart.media_library targetEntityType: media bundle: helfi_chart diff --git a/conf/cmi/core.entity_view_display.media.image.media_library.yml b/conf/cmi/core.entity_view_display.media.image.media_library.yml index 224ec4770..636408173 100644 --- a/conf/cmi/core.entity_view_display.media.image.media_library.yml +++ b/conf/cmi/core.entity_view_display.media.image.media_library.yml @@ -11,7 +11,7 @@ dependencies: module: - image _core: - default_config_hash: yp1TP84E6TnK3NSxSikmnzowUx7XVkTQFxtOTe0KPfE + default_config_hash: v-wwjZUvAoDslCgLA5KMkZBkPglteYcy97uSy5Fl-io id: media.image.media_library targetEntityType: media bundle: image diff --git a/conf/cmi/core.entity_view_display.media.remote_video.media_library.yml b/conf/cmi/core.entity_view_display.media.remote_video.media_library.yml index 93a466f20..5b950d581 100644 --- a/conf/cmi/core.entity_view_display.media.remote_video.media_library.yml +++ b/conf/cmi/core.entity_view_display.media.remote_video.media_library.yml @@ -11,7 +11,7 @@ dependencies: module: - image _core: - default_config_hash: '-OYhRJ3MUtZvvq8kso4SneprcI1fHAFW9QVpdL4L2hk' + default_config_hash: AodaWuCtx8vTnZ5Jtrp_8F-tNBrzZwlav62GAQhaMZs id: media.remote_video.media_library targetEntityType: media bundle: remote_video diff --git a/conf/cmi/core.entity_view_display.paragraph.news_list.default.yml b/conf/cmi/core.entity_view_display.paragraph.news_list.default.yml index d2233696d..37d8b0f72 100644 --- a/conf/cmi/core.entity_view_display.paragraph.news_list.default.yml +++ b/conf/cmi/core.entity_view_display.paragraph.news_list.default.yml @@ -14,7 +14,7 @@ dependencies: module: - text _core: - default_config_hash: 8ae_31-J5VbYHZDB3yqQ03vR72k0To1dELDZEdOVYOQ + default_config_hash: gy6jtJHNETBeYxflDkbuoQDbkEZUTBdFlmmY5oRYfig id: paragraph.news_list.default targetEntityType: paragraph bundle: news_list diff --git a/conf/cmi/external_entities.external_entity_type.helfi_announcements.yml b/conf/cmi/external_entities.external_entity_type.helfi_announcements.yml index f52cf89d9..4880ee6e2 100644 --- a/conf/cmi/external_entities.external_entity_type.helfi_announcements.yml +++ b/conf/cmi/external_entities.external_entity_type.helfi_announcements.yml @@ -5,7 +5,7 @@ dependencies: module: - helfi_etusivu_entities _core: - default_config_hash: 3JhNUZYN5TzmQVXkHRPLUGfc2s8hncoJD2wGyWgRzVM + default_config_hash: 2imB2uro181l7DLzY82D8LvGvDI5HFD3oKrB-9kgt94 id: helfi_announcements label: 'Helfi: Announcements' label_plural: 'Helfi: Announcements' diff --git a/conf/cmi/external_entities.external_entity_type.helfi_news.yml b/conf/cmi/external_entities.external_entity_type.helfi_news.yml index fdede9964..311270c3a 100644 --- a/conf/cmi/external_entities.external_entity_type.helfi_news.yml +++ b/conf/cmi/external_entities.external_entity_type.helfi_news.yml @@ -5,7 +5,7 @@ dependencies: module: - helfi_paragraphs_news_list _core: - default_config_hash: flMUKt27dw4Qq_U-20V4tWVrgpm-AcVby8KmaCBoXf8 + default_config_hash: qHAP3KifdQVTgoHmLjzavIIuA0KK-jbKmmayodzLSaE id: helfi_news label: 'Helfi: News' label_plural: 'Helfi: News' diff --git a/conf/cmi/external_entities.external_entity_type.helfi_news_groups.yml b/conf/cmi/external_entities.external_entity_type.helfi_news_groups.yml index b1366effe..3b8292e6c 100644 --- a/conf/cmi/external_entities.external_entity_type.helfi_news_groups.yml +++ b/conf/cmi/external_entities.external_entity_type.helfi_news_groups.yml @@ -5,7 +5,7 @@ dependencies: module: - helfi_paragraphs_news_list _core: - default_config_hash: qlDAzZQ8PSytgUjdqAXk-2_qmN_uLshxfOFF2ocfclI + default_config_hash: ktoTBmwQz_GKPFMjRFtQD3I2YnJDMy6kJgj4lLHZP5M id: helfi_news_groups label: 'Helfi: News groups' label_plural: 'Helfi: News groups' diff --git a/conf/cmi/external_entities.external_entity_type.helfi_news_neighbourhoods.yml b/conf/cmi/external_entities.external_entity_type.helfi_news_neighbourhoods.yml index 54f636715..c7ce539fb 100644 --- a/conf/cmi/external_entities.external_entity_type.helfi_news_neighbourhoods.yml +++ b/conf/cmi/external_entities.external_entity_type.helfi_news_neighbourhoods.yml @@ -5,7 +5,7 @@ dependencies: module: - helfi_paragraphs_news_list _core: - default_config_hash: 9j2pKAqUWIeKOX6X5QLpOwFSDsezXFGX4Gyte8PXekY + default_config_hash: aVspV_NJZq1ZVwc8Yc3EkiFq_49Zo6qGsUME8me2kcc id: helfi_news_neighbourhoods label: 'Helfi: News neighbourhoods' label_plural: 'Helfi: News neighbourhoods' diff --git a/conf/cmi/external_entities.external_entity_type.helfi_news_tags.yml b/conf/cmi/external_entities.external_entity_type.helfi_news_tags.yml index 8cc701b0a..158d9dfca 100644 --- a/conf/cmi/external_entities.external_entity_type.helfi_news_tags.yml +++ b/conf/cmi/external_entities.external_entity_type.helfi_news_tags.yml @@ -5,7 +5,7 @@ dependencies: module: - helfi_paragraphs_news_list _core: - default_config_hash: r7ZcjpivRV8Dr933oHre59xnKkzo7FA7BF85YoI0s24 + default_config_hash: tHod6ZIsyIeXPIUplT4OH1cpZkxtqc3UhsFpNV_H3bQ id: helfi_news_tags label: 'Helfi: News tags' label_plural: 'Helfi: News tags' diff --git a/conf/cmi/external_entities.external_entity_type.helfi_surveys.yml b/conf/cmi/external_entities.external_entity_type.helfi_surveys.yml index 2d280de89..5ab23035d 100644 --- a/conf/cmi/external_entities.external_entity_type.helfi_surveys.yml +++ b/conf/cmi/external_entities.external_entity_type.helfi_surveys.yml @@ -5,7 +5,7 @@ dependencies: module: - helfi_etusivu_entities _core: - default_config_hash: quOJapX57NowVd84rXbh7rHEJ-7csctd9FyWnQ7cIvk + default_config_hash: cOOBGsMZIwgp3zOCS0SsA3TwDpEJqmM6pVb0fTCC80o id: helfi_surveys label: 'Helfi: Survey' label_plural: 'Helfi: Surveys' diff --git a/conf/cmi/field.field.node.announcement.body.yml b/conf/cmi/field.field.node.announcement.body.yml index d89163725..fa0887bb8 100644 --- a/conf/cmi/field.field.node.announcement.body.yml +++ b/conf/cmi/field.field.node.announcement.body.yml @@ -9,7 +9,7 @@ dependencies: module: - text _core: - default_config_hash: WvleFfpLbnQtIUacO3xu0rwNYfRDfAY4CbvmwE1B9ag + default_config_hash: OijFS0n0SdsLLMnAS0Z4SUa_GBz5mgplPGglXf5Vd-s id: node.announcement.body field_name: body entity_type: node diff --git a/conf/cmi/field.field.node.survey.body.yml b/conf/cmi/field.field.node.survey.body.yml index e0cfdd809..cb77844d3 100644 --- a/conf/cmi/field.field.node.survey.body.yml +++ b/conf/cmi/field.field.node.survey.body.yml @@ -9,7 +9,7 @@ dependencies: module: - text _core: - default_config_hash: b0mXl8TINgWLn5XgnqShu90a4YKPYoiv8cKuu6ybhAU + default_config_hash: TMWUAj5DkOv1_BzrBAfbe9j2g4eOcRrINB4_F3pkpOo id: node.survey.body field_name: body entity_type: node diff --git a/conf/cmi/helfi_api_base.features.yml b/conf/cmi/helfi_api_base.features.yml index 8ae0455e9..708189cda 100644 --- a/conf/cmi/helfi_api_base.features.yml +++ b/conf/cmi/helfi_api_base.features.yml @@ -1,5 +1,6 @@ disable_email_sending: true disable_user_password: true user_expire: true +user_delete: true use_mock_responses: false logger: true diff --git a/conf/cmi/language/ru/views.view.content.yml b/conf/cmi/language/ru/views.view.content.yml index fb69671ec..85d9fcb4a 100644 --- a/conf/cmi/language/ru/views.view.content.yml +++ b/conf/cmi/language/ru/views.view.content.yml @@ -57,6 +57,8 @@ display: group_items: 1: title: Опубликовано + 2: + title: 'Снято с публикации' langcode: expose: label: Язык diff --git a/conf/cmi/media.type.image.yml b/conf/cmi/media.type.image.yml index b21822a31..b114fff20 100644 --- a/conf/cmi/media.type.image.yml +++ b/conf/cmi/media.type.image.yml @@ -8,7 +8,7 @@ third_party_settings: crop: image_field: _none _core: - default_config_hash: LX01N5rjJ7mTGbJeTSQJuX_ZvFCUl0sCBkxSR3a18Bg + default_config_hash: h9Q6cJbRkDQMf9GnvrXshX0KsKXwEz7BhMrgZpbFuzU id: image label: Image description: 'Use local image for reusable media.' diff --git a/conf/cmi/search_api.index.paikkatieto_street_names.yml b/conf/cmi/search_api.index.paikkatieto_street_names.yml new file mode 100644 index 000000000..5ff0415ef --- /dev/null +++ b/conf/cmi/search_api.index.paikkatieto_street_names.yml @@ -0,0 +1,37 @@ +uuid: 3809159c-46bf-43d9-8496-823ce93efac4 +langcode: en +status: true +dependencies: + config: + - search_api.server.default + module: + - helfi_kymp_content + - helfi_react_search + - helfi_recommendations +id: paikkatieto_street_names +name: 'Paikkatieto street names' +description: 'Street names from Paikkatieto API for vehicle removal search autocomplete.' +read_only: false +field_settings: + id: + label: ID + datasource_id: paikkatieto_street_name_source + property_path: id + type: string + street_name: + label: 'Street name' + datasource_id: paikkatieto_street_name_source + property_path: street_name + type: text +datasource_settings: + paikkatieto_street_name_source: { } +processor_settings: { } +tracker_settings: + default: + indexing_order: fifo +options: + cron_limit: 500 + delete_on_fail: true + index_directly: false + track_changes_in_references: true +server: default diff --git a/docker/openshift/crons/street-data.sh b/docker/openshift/crons/street-data.sh index 2973b3611..0d4647ed6 100644 --- a/docker/openshift/crons/street-data.sh +++ b/docker/openshift/crons/street-data.sh @@ -5,5 +5,6 @@ echo "Start indexing street data from external datasource: $(date)" while true do drush sapi-r street_data && drush sapi-i street_data --batch-size=500 + drush sapi-r paikkatieto_street_names sleep 86400 done diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 000000000..a20d7dafb --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,393 @@ +parameters: + ignoreErrors: + - + message: "#^Function _helfi_kymp_content_create_district_nodes_from_taxonomy_terms\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function _helfi_kymp_content_invalidate_subdistricts\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_first_paragraph_grey_alter\\(\\) has parameter \\$paragraphs with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_form_node_form_alter\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_form_node_form_alter\\(\\) has parameter \\$form with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_form_node_form_alter\\(\\) has parameter \\$form_id with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_helfi_paragraph_types\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_node_delete\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_node_form_validate\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_node_form_validate\\(\\) has parameter \\$form with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_node_insert\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_node_update\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_preprocess_page\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_preprocess_page\\(\\) has parameter \\$variables with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_sidebar_menu_visibility\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_sidebar_menu_visibility\\(\\) has parameter \\$variables with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_sidebar_visibility_allowed_entities_alter\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_sidebar_visibility_allowed_entities_alter\\(\\) has parameter \\$entities with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Function helfi_kymp_content_theme\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/helfi_kymp_content.module + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\DistrictUtility\\:\\:getSubdistrictParentIds\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/DistrictUtility.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Form\\\\SettingsForm\\:\\:buildForm\\(\\) has parameter \\$form with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Form/SettingsForm.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Form\\\\SettingsForm\\:\\:buildForm\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Form/SettingsForm.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Form\\\\SettingsForm\\:\\:getEditableConfigNames\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Form/SettingsForm.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Form\\\\SettingsForm\\:\\:submitForm\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Form/SettingsForm.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Form\\\\SettingsForm\\:\\:submitForm\\(\\) has parameter \\$form with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Form/SettingsForm.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Form\\\\SettingsForm\\:\\:validateForm\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Form/SettingsForm.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Form\\\\SettingsForm\\:\\:validateForm\\(\\) has parameter \\$form with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Form/SettingsForm.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Hook\\\\MobileNoteCronHooks\\:\\:syncIndex\\(\\) has parameter \\$activeIds with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Hook/MobileNoteCronHooks.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Hook\\\\MobileNoteCronHooks\\:\\:syncIndex\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Hook/MobileNoteCronHooks.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Hook\\\\MobileNoteCronHooks\\:\\:syncIndex\\(\\) has parameter \\$expiredIds with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Hook/MobileNoteCronHooks.php + + - + message: "#^Cannot access offset 'features' on array\\|bool\\|float\\|int\\|object\\|string\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/MobileNoteDataService.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\MobileNoteDataService\\:\\:buildMapUrl\\(\\) has parameter \\$coordinates with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/MobileNoteDataService.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\MobileNoteDataService\\:\\:convertGeometry\\(\\) has parameter \\$geometry with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/MobileNoteDataService.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\MobileNoteDataService\\:\\:transformFeature\\(\\) has parameter \\$feature with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/MobileNoteDataService.php + + + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\Block\\\\SubdistrictsNavigationBlock\\:\\:__construct\\(\\) has parameter \\$configuration with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/Block/SubdistrictsNavigationBlock.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\Block\\\\SubdistrictsNavigationBlock\\:\\:build\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/Block/SubdistrictsNavigationBlock.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\Block\\\\SubdistrictsNavigationBlock\\:\\:create\\(\\) has parameter \\$configuration with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/Block/SubdistrictsNavigationBlock.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\Block\\\\VehicleRemovalBlock\\:\\:__construct\\(\\) has parameter \\$configuration with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/Block/VehicleRemovalBlock.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\Block\\\\VehicleRemovalBlock\\:\\:build\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/Block/VehicleRemovalBlock.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\DataType\\\\MobileNoteData\\:\\:propertyDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/DataType/MobileNoteData.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\DataType\\\\StreetData\\:\\:propertyDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/DataType/StreetData.php + + - + message: "#^Cannot access offset 'id' on Drupal\\\\Core\\\\TypedData\\\\ComplexDataInterface\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/HelfiStreetDataSource.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\search_api\\\\datasource\\\\HelfiStreetDataSource\\:\\:create\\(\\) has parameter \\$configuration with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/HelfiStreetDataSource.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\search_api\\\\datasource\\\\HelfiStreetDataSource\\:\\:loadMultiple\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/HelfiStreetDataSource.php + + - + message: "#^Cannot access offset 'id' on Drupal\\\\Core\\\\TypedData\\\\ComplexDataInterface\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/MobileNoteDataSource.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\search_api\\\\datasource\\\\MobileNoteDataSource\\:\\:create\\(\\) has parameter \\$configuration with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/MobileNoteDataSource.php + + - + message: "#^Method Drupal\\\\helfi_kymp_content\\\\Plugin\\\\search_api\\\\datasource\\\\MobileNoteDataSource\\:\\:loadMultiple\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/MobileNoteDataSource.php + + - + message: "#^Property Drupal\\\\Core\\\\TypedData\\\\ComplexDataDefinitionBase\\:\\:\\$propertyDefinitions \\(array\\\\) in isset\\(\\) is not nullable\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/TypedData/MobileNoteDataDefinition.php + + - + message: "#^Property Drupal\\\\Core\\\\TypedData\\\\ComplexDataDefinitionBase\\:\\:\\$propertyDefinitions \\(array\\\\) in isset\\(\\) is not nullable\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/src/TypedData/StreetDataDefinition.php + + - + message: "#^Method Drupal\\\\Tests\\\\helfi_kymp_content\\\\Kernel\\\\MobileNoteCronHooksTest\\:\\:createMockIndex\\(\\) has parameter \\$staleItemIds with no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteCronHooksTest.php + + - + message: "#^Method Drupal\\\\Tests\\\\helfi_kymp_content\\\\Kernel\\\\MobileNoteCronHooksTest\\:\\:createMockIndex\\(\\) return type with generic class Prophecy\\\\Prophecy\\\\ObjectProphecy does not specify its types\\: T$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteCronHooksTest.php + + - + message: "#^Parameter \\$body of class GuzzleHttp\\\\Psr7\\\\Response constructor expects Psr\\\\Http\\\\Message\\\\StreamInterface\\|resource\\|string\\|null, string\\|false given\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteCronHooksTest.php + + - + message: "#^Parameter \\#3 \\$body of class GuzzleHttp\\\\Psr7\\\\Response constructor expects Psr\\\\Http\\\\Message\\\\StreamInterface\\|resource\\|string\\|null, string\\|false given\\.$#" + count: 3 + path: public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteDataServiceTest.php + + - + message: "#^Parameter \\$body of class GuzzleHttp\\\\Psr7\\\\Response constructor expects Psr\\\\Http\\\\Message\\\\StreamInterface\\|resource\\|string\\|null, string\\|false given\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteDataSourceTest.php + + - + message: "#^Parameter \\$body of class GuzzleHttp\\\\Psr7\\\\Response constructor expects Psr\\\\Http\\\\Message\\\\StreamInterface\\|resource\\|string\\|null, string\\|false given\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_content/tests/src/Kernel/StreetDataTest.php + + - + message: "#^Function helfi_kymp_plans_preprocess_paragraph__list_of_plans\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/helfi_kymp_plans.module + + - + message: "#^Function helfi_kymp_plans_preprocess_paragraph__list_of_plans\\(\\) has parameter \\$variables with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/helfi_kymp_plans.module + + - + message: "#^Function helfi_kymp_plans_theme\\(\\) has no return type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/helfi_kymp_plans.module + + - + message: "#^Function helfi_kymp_plans_theme\\(\\) has parameter \\$existing with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/helfi_kymp_plans.module + + - + message: "#^Function helfi_kymp_plans_theme\\(\\) has parameter \\$path with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/helfi_kymp_plans.module + + - + message: "#^Function helfi_kymp_plans_theme\\(\\) has parameter \\$theme with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/helfi_kymp_plans.module + + - + message: "#^Function helfi_kymp_plans_theme\\(\\) has parameter \\$type with no type specified\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/helfi_kymp_plans.module + + - + message: "#^Method Drupal\\\\helfi_kymp_plans\\\\ListOfPlans\\:\\:getPlans\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/src/ListOfPlans.php + + - + message: "#^Parameter \\#2 \\$timestamp of function date expects int\\|null, int\\|false given\\.$#" + count: 1 + path: public/modules/custom/helfi_kymp_plans/src/ListOfPlans.php + + - + message: "#^Function hdbt_subtheme_preprocess_block\\(\\) has no return type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_block\\(\\) has parameter \\$variables with no type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_node\\(\\) has no return type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_node\\(\\) has parameter \\$variables with no value type specified in iterable type array\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_paragraph__journey_planner\\(\\) has parameter \\$variables with no value type specified in iterable type array\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_paragraph__project_listing\\(\\) has no return type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_paragraph__project_listing\\(\\) has parameter \\$variables with no type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_views_view__project_list\\(\\) has no return type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_preprocess_views_view__project_list\\(\\) has parameter \\$variables with no type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_theme_suggestions_block_alter\\(\\) has no return type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_theme_suggestions_block_alter\\(\\) has parameter \\$suggestions with no type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_theme_suggestions_menu_alter\\(\\) has no return type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_theme_suggestions_menu_alter\\(\\) has parameter \\$suggestions with no type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme + + - + message: "#^Function hdbt_subtheme_theme_suggestions_menu_alter\\(\\) has parameter \\$variables with no type specified\\.$#" + count: 1 + path: public/themes/custom/hdbt_subtheme/hdbt_subtheme.theme diff --git a/phpstan.neon b/phpstan.neon index 5755a2aa6..8a0d88d82 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,5 @@ +includes: + - phpstan-baseline.neon parameters: fileExtensions: - php @@ -9,5 +11,5 @@ parameters: - ./public/themes/custom excludePaths: - vendor - level: 3 + level: 7 treatPhpDocTypesAsCertain: false diff --git a/public/modules/custom/helfi_kymp_content/config/schema/helfi_kymp_content.schema.yml b/public/modules/custom/helfi_kymp_content/config/schema/helfi_kymp_content.schema.yml index 1807bc127..7c74f8959 100644 --- a/public/modules/custom/helfi_kymp_content/config/schema/helfi_kymp_content.schema.yml +++ b/public/modules/custom/helfi_kymp_content/config/schema/helfi_kymp_content.schema.yml @@ -21,3 +21,9 @@ helfi_kymp_content.settings: type: string sync_lookback_offset: type: string + address_search_distance: + type: integer + label: 'Address search distance in meters' + address_search_limit: + type: integer + label: 'Address search result limit' diff --git a/public/modules/custom/helfi_kymp_content/helfi_kymp_content.services.yml b/public/modules/custom/helfi_kymp_content/helfi_kymp_content.services.yml index 990c84f0a..2f63e2ec4 100644 --- a/public/modules/custom/helfi_kymp_content/helfi_kymp_content.services.yml +++ b/public/modules/custom/helfi_kymp_content/helfi_kymp_content.services.yml @@ -8,12 +8,6 @@ services: arguments: - 'helfi_kymp_content' - helfi_kymp_content.search_api_subscriber: - class: Drupal\helfi_kymp_content\EventSubscriber\SearchApiSubscriber - arguments: ['@logger.channel.helfi_kymp_content'] - tags: - - { name: event_subscriber } - Drupal\helfi_kymp_content\StreetDataService: ~ Drupal\helfi_kymp_content\Paikkatieto\PaikkatietoClient: ~ diff --git a/public/modules/custom/helfi_kymp_content/src/EventSubscriber/SearchApiSubscriber.php b/public/modules/custom/helfi_kymp_content/src/EventSubscriber/SearchApiSubscriber.php deleted file mode 100644 index 08bdfbcac..000000000 --- a/public/modules/custom/helfi_kymp_content/src/EventSubscriber/SearchApiSubscriber.php +++ /dev/null @@ -1,77 +0,0 @@ - ['reindex'], - ]; - } - - /** - * Tell tracker which IDs to index on next indexing. - * - * @param \Drupal\search_api\Event\ReindexScheduledEvent $event - * The event. - * - * @throws \Drupal\search_api\SearchApiException - */ - public function reindex(ReindexScheduledEvent $event): void { - $index = $event->getIndex(); - - // Handle street_data index. - if ($index->id() == 'street_data') { - $this->trackDatasourceItems($index, 'helfi_street_data_source'); - } - } - - /** - * Track items for a datasource. - * - * @param \Drupal\search_api\IndexInterface $index - * The index. - * @param string $datasourceId - * The datasource ID. - */ - protected function trackDatasourceItems($index, string $datasourceId): void { - try { - $source = $index->getDatasource($datasourceId); - $ids = $source->getItemIds(); - if (!$ids) { - return; - } - $index->trackItemsInserted($source->getPluginId(), $ids); - } - catch (\Exception $e) { - $this->logger->error('Unable to fetch data while running reindex event for @datasource: @message', [ - '@datasource' => $datasourceId, - '@message' => $e->getMessage(), - ]); - } - } - -} diff --git a/public/modules/custom/helfi_kymp_content/src/Paikkatieto/PaikkatietoClient.php b/public/modules/custom/helfi_kymp_content/src/Paikkatieto/PaikkatietoClient.php index 70c694bda..fafa7e846 100644 --- a/public/modules/custom/helfi_kymp_content/src/Paikkatieto/PaikkatietoClient.php +++ b/public/modules/custom/helfi_kymp_content/src/Paikkatieto/PaikkatietoClient.php @@ -21,11 +21,6 @@ class PaikkatietoClient implements LoggerAwareInterface { use LoggerAwareTrait; - /** - * Earth radius in meters. - */ - private const float EARTH_RADIUS = 6371000; - public function __construct( private readonly ConfigFactoryInterface $configFactory, private readonly ClientInterface $httpClient, @@ -36,23 +31,19 @@ public function __construct( * Fetches unique street names along a linestring. * * Queries the API at the midpoint of each segment and returns - * the deduplicated set of closest street names. + * the deduplicated set of street names found within the configured + * search radius. * - * We attempt to avoid picking the wrong results at an intersection - * by choosing midpoints. - * - * @param array $coordinates + * @param array $coordinates * Array of [lon, lat] coordinate pairs (GeoJSON order). - * @param int $distance - * Search radius in meters for each segment midpoint. * - * @return array + * @return array * Unique street names (fi and sv) found along the linestring. * * @throws \Drupal\helfi_kymp_content\Paikkatieto\Exception * @throws \InvalidArgumentException */ - public function fetchStreetsForLineString(array $coordinates, int $distance = 75): array { + public function fetchStreetsForLineString(array $coordinates): array { $count = count($coordinates); $streets = []; @@ -60,7 +51,7 @@ public function fetchStreetsForLineString(array $coordinates, int $distance = 75 $midLat = ($coordinates[$i][1] + $coordinates[$i + 1][1]) / 2; $midLon = ($coordinates[$i][0] + $coordinates[$i + 1][0]) / 2; - $segmentStreets = $this->fetchStreetsByPoint($midLat, $midLon, $distance); + $segmentStreets = $this->fetchStreetsByPoint($midLat, $midLon); array_push($streets, ...$segmentStreets); } @@ -70,78 +61,119 @@ public function fetchStreetsForLineString(array $coordinates, int $distance = 75 /** * Fetches street names using the point-radius method. * + * Returns all unique street names found within the configured search + * radius, not just the closest. The search distance and result limit + * are read from 'helfi_kymp_content.settings' config + * (address_search_distance, address_search_limit) with defaults of + * 75 meters and 20 results. + * * @param float $lat * Latitude. * @param float $lon * Longitude. - * @param int $distance - * Distance. We look at street names within this - * distance and pick the closest result. * - * @return array + * @return array * A list of unique street names found within radius. * * @throws \Drupal\helfi_kymp_content\Paikkatieto\Exception * @throws \InvalidArgumentException */ - public function fetchStreetsByPoint(float $lat, float $lon, int $distance = 75): array { - $results = $this->makeRequest([ + public function fetchStreetsByPoint(float $lat, float $lon): array { + $config = $this->configFactory->get('helfi_kymp_content.settings'); + $distance = $config->get('address_search_distance') ?: 75; + $limit = $config->get('address_search_limit') ?: 20; + + $data = $this->makeRequest([ 'lat' => $lat, 'lon' => $lon, 'distance' => $distance, - 'limit' => 20, + 'limit' => $limit, ]); + $results = $data->results ?? []; if (empty($results)) { return []; } - // Find the closest result by haversine distance. - $closest = NULL; - $minDistance = PHP_FLOAT_MAX; - + $streets = []; foreach ($results as $result) { - $coords = $result->location->coordinates ?? NULL; - if (!$coords) { - continue; - } - // API returns [lon, lat] (GeoJSON order). - $d = self::haversineDistance($lat, $lon, $coords[1], $coords[0]); - if ($d < $minDistance) { - $minDistance = $d; - $closest = $result; + foreach (['fi', 'sv'] as $langcode) { + if (!empty($result->street->name->{$langcode})) { + $streets[] = $result->street->name->{$langcode}; + } } } - if (!$closest) { - return []; + return array_values(array_unique($streets)); + } + + /** + * Fetches unique street names from a single page of the API. + * + * @param int $page + * The 1-based page number. + * @param int $pageSize + * Results per page. + * + * @return array|null + * List of street names with their language, or NULL past the last page. + * + * @throws \Drupal\helfi_kymp_content\Paikkatieto\Exception + * @throws \InvalidArgumentException + */ + public function fetchStreetNamesByPage(int $page = 1, int $pageSize = 500): ?array { + try { + $data = $this->makeRequest([ + 'municipality' => 'Helsinki', + 'page_size' => $pageSize, + 'page' => $page, + ]); + } + catch (Exception $e) { + // API returns 404 {"detail":"Epäkelpo sivu."} past the last page. + $previous = $e->getPrevious(); + if ($previous instanceof RequestException && $previous->getResponse()?->getStatusCode() === 404) { + return NULL; + } + + throw $e; } + $results = $data->results ?? []; $streets = []; - foreach (['fi', 'sv'] as $langcode) { - if (!empty($closest->street->name->{$langcode})) { - $streets[] = $closest->street->name->{$langcode}; + + foreach ($results as $result) { + foreach (['fi', 'sv', 'en'] as $langcode) { + $name = $result->street->name->{$langcode} ?? NULL; + if (!empty($name)) { + $streets[] = ['name' => $name, 'language' => $langcode]; + } } } + $this->logger?->info('Paikkatieto street names: fetched page @page (@count results).', [ + '@page' => $page, + '@count' => count($results), + ]); + return $streets; } /** - * Fetches results from the Paikkatietohaku API. + * Fetches a response from the Paikkatietohaku API. * - * @param array $queryParams + * @param array $queryParams * Query parameters for the API request. * @param int $maxRetries * Maximum number of retries on 502 errors. * - * @return array - * The results array from the API response. + * @return object + * The full decoded JSON response. * * @throws \Drupal\helfi_kymp_content\Paikkatieto\Exception * @throws \InvalidArgumentException */ - private function makeRequest(array $queryParams, int $maxRetries = 3): array { + private function makeRequest(array $queryParams, int $maxRetries = 3): object { $config = $this->configFactory->get('helfi_kymp_content.settings'); $apiKey = $config->get('address_api_key'); @@ -164,9 +196,9 @@ private function makeRequest(array $queryParams, int $maxRetries = 3): array { 'timeout' => 60, ]); + /** @var object $data */ $data = Utils::jsonDecode($response->getBody()->getContents()); - - return $data->results ?? []; + return $data; } catch (GuzzleException $e) { $lastException = $e; @@ -187,24 +219,4 @@ private function makeRequest(array $queryParams, int $maxRetries = 3): array { throw new Exception($lastException->getMessage(), previous: $lastException); } - /** - * Calculate the distance between two coordinates using the Haversine formula. - */ - private static function haversineDistance(float $lat1, float $lon1, float $lat2, float $lon2): float { - $lat1 = deg2rad($lat1); - $lon1 = deg2rad($lon1); - $lat2 = deg2rad($lat2); - $lon2 = deg2rad($lon2); - - $deltaLat = $lat2 - $lat1; - $deltaLon = $lon2 - $lon1; - - $a = sin($deltaLat / 2) ** 2 - + cos($lat1) * cos($lat2) * sin($deltaLon / 2) ** 2; - - $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); - - return self::EARTH_RADIUS * $c; - } - } diff --git a/public/modules/custom/helfi_kymp_content/src/Plugin/DataType/PaikkatietoStreetName.php b/public/modules/custom/helfi_kymp_content/src/Plugin/DataType/PaikkatietoStreetName.php new file mode 100644 index 000000000..c2d67abfe --- /dev/null +++ b/public/modules/custom/helfi_kymp_content/src/Plugin/DataType/PaikkatietoStreetName.php @@ -0,0 +1,48 @@ + + * The property definitions. + */ + public static function propertyDefinitions(): array { + $properties = []; + + $properties['id'] = DataDefinition::create('string') + ->setLabel('ID') + ->setRequired(TRUE); + + $properties['street_name'] = DataDefinition::create('string') + ->setLabel('Street name') + ->setRequired(TRUE); + + $properties['language'] = DataDefinition::create('string') + ->setLabel('Language') + ->setRequired(TRUE); + + return $properties; + } + +} diff --git a/public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/PaikkatietoStreetNameDataSource.php b/public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/PaikkatietoStreetNameDataSource.php new file mode 100644 index 000000000..81223a46a --- /dev/null +++ b/public/modules/custom/helfi_kymp_content/src/Plugin/search_api/datasource/PaikkatietoStreetNameDataSource.php @@ -0,0 +1,142 @@ + $configuration + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); + $instance->client = $container->get(PaikkatietoClient::class); + $instance->typedDataManager = $container->get(TypedDataManagerInterface::class); + $instance->logger = $container->get('logger.channel.helfi_kymp_content'); + return $instance; + } + + /** + * {@inheritdoc} + */ + public function getItemIds($page = NULL) { + // API pages are 1-based, datasource pages are 0-based. + $apiPage = ($page ?? 0) + 1; + + try { + $results = $this->client->fetchStreetNamesByPage($apiPage); + } + catch (\InvalidArgumentException $e) { + Error::logException($this->logger, $e); + return NULL; + } + + if ($results === NULL) { + return NULL; + } + + $ids = []; + foreach ($results as $entry) { + $ids[] = "{$entry['language']}:{$entry['name']}"; + } + + // The API returns addresses, not unique street names, so the same + // street name appears multiple times per page. Duplicates within a + // single batch cause integrity constraint violations in the tracker. + return array_unique($ids); + } + + /** + * {@inheritdoc} + */ + public function getItemId(ComplexDataInterface $item): null|string { + return $item->get('id')->getString(); + } + + /** + * {@inheritDoc} + * + * Item content is encoded in the ID. No network requests needed. + */ + public function load($id): ?ComplexDataInterface { + [$language, $name] = explode(':', $id, 2); + $definition = $this->typedDataManager->createDataDefinition('paikkatieto_street_name'); + $typedData = $this->typedDataManager->create($definition); + assert($typedData instanceof ComplexDataInterface); + $typedData->setValue([ + 'id' => $id, + 'street_name' => $name, + 'language' => $language, + ]); + + return $typedData; + } + + /** + * {@inheritdoc} + * + * @phpstan-param array $ids + */ + public function loadMultiple(array $ids): array { + $items = []; + + foreach ($ids as $id) { + $items[$id] = $this->load($id); + } + + return $items; + } + + /** + * {@inheritdoc} + */ + public function getItemLanguage(ComplexDataInterface $item): string { + return $item->get('language')->getString(); + } + + /** + * {@inheritdoc} + */ + public function getPropertyDefinitions(): array { + return PaikkatietoStreetName::propertyDefinitions(); + } + +} diff --git a/public/modules/custom/helfi_kymp_content/src/TypedData/PaikkatietoStreetNameDefinition.php b/public/modules/custom/helfi_kymp_content/src/TypedData/PaikkatietoStreetNameDefinition.php new file mode 100644 index 000000000..a4abb5d24 --- /dev/null +++ b/public/modules/custom/helfi_kymp_content/src/TypedData/PaikkatietoStreetNameDefinition.php @@ -0,0 +1,25 @@ +propertyDefinitions)) { + $this->propertyDefinitions = PaikkatietoStreetName::propertyDefinitions(); + } + return $this->propertyDefinitions; + } + +} diff --git a/public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteDataServiceTest.php b/public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteDataServiceTest.php index 573b13bf6..7e1f80007 100644 --- a/public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteDataServiceTest.php +++ b/public/modules/custom/helfi_kymp_content/tests/src/Kernel/MobileNoteDataServiceTest.php @@ -128,11 +128,12 @@ public function testGetMobileNoteData(): void { $this->assertEquals('test.123', $item['id']); $this->assertEquals('Test Street 1', $item['address']); $this->assertEquals('Test Reason', $item['reason']); - // Street names should contain the closest result's fi and sv names. + // Street names should contain all results' fi and sv names. $this->assertNotEmpty($item['street_names']); $this->assertContains('Mannerheimintie', $item['street_names']); $this->assertContains('Mannerheimvägen', $item['street_names']); - $this->assertCount(2, $item['street_names']); + $this->assertContains('Kaivokatu', $item['street_names']); + $this->assertCount(3, $item['street_names']); // Verify date conversion (Europe/Helsinki timezone). $tz = new \DateTimeZone('Europe/Helsinki'); diff --git a/public/modules/custom/helfi_kymp_content/tests/src/Kernel/PaikkatietoClientTest.php b/public/modules/custom/helfi_kymp_content/tests/src/Kernel/PaikkatietoClientTest.php new file mode 100644 index 000000000..06b7313e0 --- /dev/null +++ b/public/modules/custom/helfi_kymp_content/tests/src/Kernel/PaikkatietoClientTest.php @@ -0,0 +1,226 @@ +config('helfi_kymp_content.settings') + ->set('address_api_key', 'TEST_KEY') + ->save(); + } + + /** + * Creates a PaikkatietoClient with mocked HTTP responses. + * + * @param array<\Psr\Http\Message\ResponseInterface|\GuzzleHttp\Exception\GuzzleException> $responses + * The queued HTTP responses. + * + * @return \Drupal\helfi_kymp_content\Paikkatieto\PaikkatietoClient + * The client. + */ + private function createClient(array $responses): PaikkatietoClient { + $httpClient = $this->createMockHttpClient($responses); + $this->container->set('http_client', $httpClient); + return $this->container->get(PaikkatietoClient::class); + } + + /** + * Creates an address API JSON response. + * + * @param array $streets + * Street names keyed by language. + * + * @return \GuzzleHttp\Psr7\Response + * A mock response. + */ + private function createAddressResponse(array $streets): Response { + $results = []; + foreach ($streets as $names) { + $nameObj = new \stdClass(); + foreach ($names as $lang => $name) { + $nameObj->{$lang} = $name; + } + $results[] = ['street' => ['name' => $nameObj]]; + } + return new Response(body: json_encode(['results' => $results], JSON_THROW_ON_ERROR)); + } + + /** + * Tests fetching street names by point. + */ + public function testFetchStreetsByPoint(): void { + $client = $this->createClient([ + $this->createAddressResponse([ + ['fi' => 'Mannerheimintie', 'sv' => 'Mannerheimvägen'], + ['fi' => 'Mannerheimintie', 'sv' => 'Mannerheimvägen'], + ['fi' => 'Kaivokatu', 'sv' => 'Brunnsgatan'], + ]), + new Response(body: json_encode(['results' => []], JSON_THROW_ON_ERROR)), + ]); + + // Tests fetching street names by point. + $streets = $client->fetchStreetsByPoint(60.171, 24.941); + + $this->assertCount(4, $streets); + $this->assertContains('Mannerheimintie', $streets); + $this->assertContains('Mannerheimvägen', $streets); + $this->assertContains('Kaivokatu', $streets); + $this->assertContains('Brunnsgatan', $streets); + + // Tests fetching street names by point with empty results. + $streets = $client->fetchStreetsByPoint(60.191, 24.931); + + $this->assertEmpty($streets); + } + + /** + * Tests fetching streets for a linestring. + */ + public function testFetchStreetsForLineString(): void { + $client = $this->createClient([ + // Segment 1 midpoint response. + $this->createAddressResponse([ + ['fi' => 'Mannerheimintie', 'sv' => 'Mannerheimvägen'], + ]), + // Segment 2 midpoint response. + $this->createAddressResponse([ + ['fi' => 'Mannerheimintie', 'sv' => 'Mannerheimvägen'], + ['fi' => 'Kaivokatu'], + ]), + ]); + + $coordinates = [ + [24.941, 60.171], + [24.945, 60.173], + [24.950, 60.175], + ]; + + $streets = $client->fetchStreetsForLineString($coordinates); + + // Deduplicated across segments. + $this->assertCount(3, $streets); + $this->assertContains('Mannerheimintie', $streets); + $this->assertContains('Mannerheimvägen', $streets); + $this->assertContains('Kaivokatu', $streets); + } + + /** + * Tests fetching street names by page. + */ + public function testFetchStreetNamesByPage(): void { + $client = $this->createClient([ + $this->createAddressResponse([ + ['fi' => 'Mannerheimintie', 'sv' => 'Mannerheimvägen'], + ['fi' => 'Kaivokatu'], + ]), + new RequestException( + 'Not Found', + new Request('GET', 'test'), + new Response(404, [], json_encode(['detail' => 'error'], JSON_THROW_ON_ERROR)), + ), + new RequestException( + 'Server Error', + new Request('GET', 'test'), + new Response(500), + ), + ]); + + $results = $client->fetchStreetNamesByPage(1); + + $this->assertNotNull($results); + $this->assertCount(3, $results); + + $this->assertEquals('Mannerheimintie', $results[0]['name']); + $this->assertEquals('fi', $results[0]['language']); + $this->assertEquals('Mannerheimvägen', $results[1]['name']); + $this->assertEquals('sv', $results[1]['language']); + $this->assertEquals('Kaivokatu', $results[2]['name']); + $this->assertEquals('fi', $results[2]['language']); + + // Tests that fetching past the last page returns NULL. + $result = $client->fetchStreetNamesByPage(999); + $this->assertNull($result); + + // Tests that non-404 errors are rethrown. + $this->expectException(Exception::class); + $client->fetchStreetNamesByPage(1); + } + + /** + * Tests that missing API key throws an exception. + */ + public function testMissingApiKeyThrows(): void { + $this->config('helfi_kymp_content.settings') + ->set('address_api_key', '') + ->save(); + + $client = $this->createClient([]); + + $this->expectException(\InvalidArgumentException::class); + $client->fetchStreetsByPoint(60.171, 24.941); + } + + /** + * Tests retry on 502 followed by success. + */ + public function testRetryOn502ThenSuccess(): void { + $client = $this->createClient([ + new RequestException( + 'Bad Gateway', + new Request('GET', 'test'), + new Response(502), + ), + $this->createAddressResponse([ + ['fi' => 'Kaivokatu'], + ]), + new RequestException( + 'Forbidden', + new Request('GET', 'test'), + new Response(403), + ), + ]); + + $streets = $client->fetchStreetsByPoint(60.171, 24.941); + + $this->assertCount(1, $streets); + $this->assertContains('Kaivokatu', $streets); + + // Tests that non-502 errors throw immediately without retrying. + $this->expectException(Exception::class); + $client->fetchStreetsByPoint(60.171, 24.941); + } + +} diff --git a/public/modules/custom/helfi_kymp_content/tests/src/Kernel/PaikkatietoStreetNameDataSourceTest.php b/public/modules/custom/helfi_kymp_content/tests/src/Kernel/PaikkatietoStreetNameDataSourceTest.php new file mode 100644 index 000000000..1132bb55e --- /dev/null +++ b/public/modules/custom/helfi_kymp_content/tests/src/Kernel/PaikkatietoStreetNameDataSourceTest.php @@ -0,0 +1,119 @@ + 'Test Index', + 'id' => 'test_paikkatieto_street_names', + 'status' => FALSE, + 'datasource_settings' => [ + 'paikkatieto_street_name_source' => [], + ], + 'tracker_settings' => [ + 'default' => [], + ], + ]); + return $index->getDatasource('paikkatieto_street_name_source'); + } + + /** + * Tests getItemIds returns deduplicated IDs. + */ + public function testGetItemIds(): void { + $client = $this->prophesize(PaikkatietoClient::class); + $client->fetchStreetNamesByPage(1) + ->shouldBeCalled() + ->willReturn([ + ['name' => 'Mannerheimintie', 'language' => 'fi'], + ['name' => 'Mannerheimintie', 'language' => 'fi'], + ['name' => 'Mannerheimvägen', 'language' => 'sv'], + ['name' => 'Kaivokatu', 'language' => 'fi'], + ]); + $this->container->set(PaikkatietoClient::class, $client->reveal()); + + $datasource = $this->getDatasource(); + $ids = $datasource->getItemIds(0); + + // Duplicates should be removed. + $this->assertCount(3, $ids); + $this->assertContains('fi:Mannerheimintie', $ids); + $this->assertContains('sv:Mannerheimvägen', $ids); + $this->assertContains('fi:Kaivokatu', $ids); + } + + /** + * Tests that getItemIds returns NULL on InvalidArgumentException. + */ + public function testGetItemIdsReturnsNullOnInvalidArgumentException(): void { + $client = $this->prophesize(PaikkatietoClient::class); + $client->fetchStreetNamesByPage(1) + ->shouldBeCalled() + ->willThrow(new \InvalidArgumentException('Missing API key')); + $this->container->set(PaikkatietoClient::class, $client->reveal()); + + $datasource = $this->getDatasource(); + $this->assertNull($datasource->getItemIds(0)); + } + + /** + * Tests loading a single item from its ID. + */ + public function testLoad(): void { + $datasource = $this->getDatasource(); + $item = $datasource->load('fi:Mannerheimintie'); + + $this->assertInstanceOf(ComplexDataInterface::class, $item); + $this->assertEquals('fi:Mannerheimintie', $item->get('id')->getString()); + $this->assertEquals('Mannerheimintie', $item->get('street_name')->getString()); + $this->assertEquals('fi', $item->get('language')->getString()); + } + + /** + * Tests loading multiple items. + */ + public function testLoadMultiple(): void { + $datasource = $this->getDatasource(); + $items = $datasource->loadMultiple(['fi:Mannerheimintie', 'sv:Mannerheimvägen']); + + $this->assertCount(2, $items); + $this->assertArrayHasKey('fi:Mannerheimintie', $items); + $this->assertArrayHasKey('sv:Mannerheimvägen', $items); + } + +} diff --git a/public/themes/custom/hdbt_subtheme/templates/views/views-view--district-and-project-search.html.twig b/public/themes/custom/hdbt_subtheme/templates/views/views-view--district-and-project-search.html.twig deleted file mode 100644 index 8d0e5c6f4..000000000 --- a/public/themes/custom/hdbt_subtheme/templates/views/views-view--district-and-project-search.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -{# -/** - * @file - * Theme override for main view template. - */ -#} - -{% embed '@hdbt/component/content-list-with-count.twig'%} - {% block count_container%} - {%- if total_rows -%} - {{ total_rows }} {% trans with {'context': 'District and project search fallback'}%}search result{% plural total_rows ?? 0 %}search results{% endtrans %} - {%- else -%} - {{ 'No results'|t({}, {'context' : 'Unit search no results title'}) }} - {%- endif -%} - {% endblock count_container %} -{% endembed %}