Align product records with sitemap V2; product family model; CLI workbook import

- vitec:migrate-product-structure: exact V2 titles, Milestone typo fix (incl.
  slug), QTX100 stray VSN category removed, Aligo record moved to its own
  category with slug /product/aligo, new Aligo Workstation record takes over
  /product/aligo-workstation
- product families (sitemap column K) are ordinary content pages now:
  vitec:remove-family-records deletes the interim landing records again,
  reset_subproduct_flags.php clears the misused subproduct flag (the list
  renderer has always excluded subproduct=1)
- vitec:import-product-workbook: non-interactive counterpart of the module
  import (same reader, mapping and DataHandler path); Arqa imported, Aligo
  re-applied with the corrected capabilities markup
- ProductXlsxReader: new :copy cell selector (Body Copy with CTA fallback)
  absorbs the agency's column drift; default teaser mapping uses it
- ProductListJsonRenderer: selected categories now match their whole subtree,
  results ordered by category tree position, sheet order within a category
- read-only diagnostics: check_product_structure.php, check_productlist_ces.php
This commit is contained in:
2026-09-04 12:59:17 +02:00
parent 7833e1b668
commit 5499ca54af
12 changed files with 1186 additions and 121 deletions

194
composer.lock generated
View File

@@ -8,16 +8,16 @@
"packages": [
{
"name": "apache-solr-for-typo3/solr",
"version": "14.0.0-RC1",
"version": "14.0.1",
"source": {
"type": "git",
"url": "https://github.com/TYPO3-Solr/ext-solr.git",
"reference": "96834e83592d59c350005216821ee502cfee8ece"
"reference": "25fad97ffe192b1c4afc9400b98f4b4c4d3a6ea3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/TYPO3-Solr/ext-solr/zipball/96834e83592d59c350005216821ee502cfee8ece",
"reference": "96834e83592d59c350005216821ee502cfee8ece",
"url": "https://api.github.com/repos/TYPO3-Solr/ext-solr/zipball/25fad97ffe192b1c4afc9400b98f4b4c4d3a6ea3",
"reference": "25fad97ffe192b1c4afc9400b98f4b4c4d3a6ea3",
"shasum": ""
},
"require": {
@@ -33,7 +33,6 @@
"typo3/cms-extbase": "*",
"typo3/cms-fluid": "*",
"typo3/cms-frontend": "*",
"typo3/cms-install": "*",
"typo3/cms-reports": "*",
"typo3/cms-scheduler": "*",
"typo3/cms-tstemplate": "*"
@@ -52,12 +51,23 @@
"phpstan/phpstan-phpunit": "^2.0.18",
"phpunit/phpunit": "^11.5.55",
"typo3/cms-fluid-styled-content": "*",
"typo3/cms-install": "*",
"typo3/coding-standards": "v0.8.0",
"typo3/testing-framework": "^9.5.0"
},
"suggest": {
"typo3/cms-install": "Required only to run the \"Apache Solr Search\" plugin to content element upgrade wizard."
},
"type": "typo3-cms-extension",
"extra": {
"typo3/cms": {
"Package": {
"providesPackages": {
"solarium/solarium": "Resources/Private/Php/ComposerLibraries/vendor",
"halaxa/json-machine": "Resources/Private/Php/ComposerLibraries/vendor"
}
},
"version": "14.0.x-dev",
"web-dir": ".Build/Web",
"extension-key": "solr"
},
@@ -119,7 +129,7 @@
"type": "custom"
}
],
"time": "2026-07-17T15:16:50+00:00"
"time": "2026-09-03T14:19:19+00:00"
},
{
"name": "b13/container",
@@ -1610,16 +1620,16 @@
},
{
"name": "friendsoftypo3/headless",
"version": "v5.0.0-rc1",
"version": "v5.0.0-rc2",
"source": {
"type": "git",
"url": "https://github.com/TYPO3-Headless/headless.git",
"reference": "53eb4233a2b94fe47b88fa00a3f9859ba4eb1419"
"reference": "1eae1026caa455d05dea5e89c69b7c8474295b83"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/TYPO3-Headless/headless/zipball/53eb4233a2b94fe47b88fa00a3f9859ba4eb1419",
"reference": "53eb4233a2b94fe47b88fa00a3f9859ba4eb1419",
"url": "https://api.github.com/repos/TYPO3-Headless/headless/zipball/1eae1026caa455d05dea5e89c69b7c8474295b83",
"reference": "1eae1026caa455d05dea5e89c69b7c8474295b83",
"shasum": ""
},
"require": {
@@ -1637,18 +1647,26 @@
"helmich/typo3-typoscript-lint": "^v3",
"justinrainbow/json-schema": "^5",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.12",
"phpstan/phpstan": "^2",
"phpunit/phpcov": "^8 || ^9 || ^10",
"seld/jsonlint": "^1.11",
"symfony/yaml": "^6.1 || ^7.1",
"typo3/cms-felogin": "^14.3",
"typo3/cms-form": "^14.0",
"typo3/cms-redirects": "^14.3",
"typo3/cms-seo": "^14.3",
"typo3/cms-workspaces": "^14.3",
"typo3/coding-standards": "^0.8",
"typo3/testing-framework": "^9.0"
},
"type": "typo3-cms-extension",
"extra": {
"typo3/cms": {
"Package": {
"providesPackages": []
},
"app-dir": ".Build",
"version": "5.0.0-rc2",
"web-dir": ".Build/public",
"extension-key": "headless"
}
@@ -1686,7 +1704,7 @@
],
"support": {
"issues": "https://github.com/TYPO3-Headless/headless/issues",
"source": "https://github.com/TYPO3-Headless/headless/tree/v5.0.0-rc1"
"source": "https://github.com/TYPO3-Headless/headless/tree/v5.0.0-rc2"
},
"funding": [
{
@@ -1694,7 +1712,7 @@
"type": "custom"
}
],
"time": "2026-05-08T15:09:37+00:00"
"time": "2026-09-02T12:07:34+00:00"
},
{
"name": "georgringer/news",
@@ -3252,16 +3270,16 @@
},
{
"name": "phpstan/phpdoc-parser",
"version": "2.3.3",
"version": "2.3.5",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3"
"reference": "148cefffaf0233e4c08cc13db8a195a56dd6dfe9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fb19eedd2bb67ff8cf7a5502ad329e701d6398a3",
"reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/148cefffaf0233e4c08cc13db8a195a56dd6dfe9",
"reference": "148cefffaf0233e4c08cc13db8a195a56dd6dfe9",
"shasum": ""
},
"require": {
@@ -3293,9 +3311,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.3"
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.5"
},
"time": "2026-07-08T07:01:06+00:00"
"time": "2026-08-31T16:05:28+00:00"
},
{
"name": "plan2net/backend-category-hierarchy",
@@ -4634,16 +4652,16 @@
},
{
"name": "symfony/console",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "962e18f09ebe68a49039b4c82fc0ea4871824fca"
"reference": "23d6f88a29f6d0eac45bd77d70307adf83ba7ab0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/962e18f09ebe68a49039b4c82fc0ea4871824fca",
"reference": "962e18f09ebe68a49039b4c82fc0ea4871824fca",
"url": "https://api.github.com/repos/symfony/console/zipball/23d6f88a29f6d0eac45bd77d70307adf83ba7ab0",
"reference": "23d6f88a29f6d0eac45bd77d70307adf83ba7ab0",
"shasum": ""
},
"require": {
@@ -4708,7 +4726,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.4.17"
"source": "https://github.com/symfony/console/tree/v7.4.18"
},
"funding": [
{
@@ -4728,7 +4746,7 @@
"type": "tidelift"
}
],
"time": "2026-08-21T12:09:28+00:00"
"time": "2026-08-25T14:18:37+00:00"
},
{
"name": "symfony/dependency-injection",
@@ -4887,7 +4905,7 @@
},
{
"name": "symfony/doctrine-messenger",
"version": "v7.4.15",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/doctrine-messenger.git",
@@ -4939,7 +4957,7 @@
"description": "Symfony Doctrine Messenger Bridge",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/doctrine-messenger/tree/v7.4.15"
"source": "https://github.com/symfony/doctrine-messenger/tree/v7.4.18"
},
"funding": [
{
@@ -5128,16 +5146,16 @@
},
{
"name": "symfony/expression-language",
"version": "v7.4.14",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/expression-language.git",
"reference": "bd5763f92959201816ecc31defdf352d2ea473be"
"reference": "b73866506ff02800836a40fa1f95614a71064f35"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/expression-language/zipball/bd5763f92959201816ecc31defdf352d2ea473be",
"reference": "bd5763f92959201816ecc31defdf352d2ea473be",
"url": "https://api.github.com/repos/symfony/expression-language/zipball/b73866506ff02800836a40fa1f95614a71064f35",
"reference": "b73866506ff02800836a40fa1f95614a71064f35",
"shasum": ""
},
"require": {
@@ -5172,7 +5190,7 @@
"description": "Provides an engine that can compile and evaluate expressions",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/expression-language/tree/v7.4.14"
"source": "https://github.com/symfony/expression-language/tree/v7.4.18"
},
"funding": [
{
@@ -5192,20 +5210,20 @@
"type": "tidelift"
}
],
"time": "2026-06-08T20:24:16+00:00"
"time": "2026-08-30T00:47:26+00:00"
},
{
"name": "symfony/filesystem",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "ee7bc7bca4c7079b88e57d5000aeeb20df570c8d"
"reference": "90d412aa5277c6819db39e7605aa46b1019e3232"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/ee7bc7bca4c7079b88e57d5000aeeb20df570c8d",
"reference": "ee7bc7bca4c7079b88e57d5000aeeb20df570c8d",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/90d412aa5277c6819db39e7605aa46b1019e3232",
"reference": "90d412aa5277c6819db39e7605aa46b1019e3232",
"shasum": ""
},
"require": {
@@ -5242,7 +5260,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/filesystem/tree/v7.4.17"
"source": "https://github.com/symfony/filesystem/tree/v7.4.18"
},
"funding": [
{
@@ -5262,7 +5280,7 @@
"type": "tidelift"
}
],
"time": "2026-08-21T12:09:28+00:00"
"time": "2026-08-23T10:03:40+00:00"
},
{
"name": "symfony/finder",
@@ -5334,16 +5352,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "2ebe78c083501dfb9509b31a7aedcae4d60a391f"
"reference": "d070b716a32fbe3bf04204db0f58ace73b86d133"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/2ebe78c083501dfb9509b31a7aedcae4d60a391f",
"reference": "2ebe78c083501dfb9509b31a7aedcae4d60a391f",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/d070b716a32fbe3bf04204db0f58ace73b86d133",
"reference": "d070b716a32fbe3bf04204db0f58ace73b86d133",
"shasum": ""
},
"require": {
@@ -5392,7 +5410,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-foundation/tree/v7.4.17"
"source": "https://github.com/symfony/http-foundation/tree/v7.4.18"
},
"funding": [
{
@@ -5412,7 +5430,7 @@
"type": "tidelift"
}
],
"time": "2026-08-20T09:55:18+00:00"
"time": "2026-08-30T20:10:52+00:00"
},
{
"name": "symfony/mailer",
@@ -5500,16 +5518,16 @@
},
{
"name": "symfony/messenger",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/messenger.git",
"reference": "3976018381c403e369d3027592e911b979eaeed9"
"reference": "b109f9f4e54470ee6835751bc39318fe3d8275e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/messenger/zipball/3976018381c403e369d3027592e911b979eaeed9",
"reference": "3976018381c403e369d3027592e911b979eaeed9",
"url": "https://api.github.com/repos/symfony/messenger/zipball/b109f9f4e54470ee6835751bc39318fe3d8275e6",
"reference": "b109f9f4e54470ee6835751bc39318fe3d8275e6",
"shasum": ""
},
"require": {
@@ -5570,7 +5588,7 @@
"description": "Helps applications send and receive messages to/from other applications or via message queues",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/messenger/tree/v7.4.17"
"source": "https://github.com/symfony/messenger/tree/v7.4.18"
},
"funding": [
{
@@ -5590,11 +5608,11 @@
"type": "tidelift"
}
],
"time": "2026-08-21T17:40:08+00:00"
"time": "2026-08-30T00:47:26+00:00"
},
{
"name": "symfony/mime",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
@@ -5659,7 +5677,7 @@
"mime-type"
],
"support": {
"source": "https://github.com/symfony/mime/tree/v7.4.17"
"source": "https://github.com/symfony/mime/tree/v7.4.18"
},
"funding": [
{
@@ -6743,7 +6761,7 @@
},
{
"name": "symfony/process",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
@@ -6784,7 +6802,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v7.4.17"
"source": "https://github.com/symfony/process/tree/v7.4.18"
},
"funding": [
{
@@ -6889,16 +6907,16 @@
},
{
"name": "symfony/property-info",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/property-info.git",
"reference": "a37837b52ed5dd7474c251d15694007344c6462d"
"reference": "52420d499b03ec20c0d38f0dc2f940bc9c43dc8e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/property-info/zipball/a37837b52ed5dd7474c251d15694007344c6462d",
"reference": "a37837b52ed5dd7474c251d15694007344c6462d",
"url": "https://api.github.com/repos/symfony/property-info/zipball/52420d499b03ec20c0d38f0dc2f940bc9c43dc8e",
"reference": "52420d499b03ec20c0d38f0dc2f940bc9c43dc8e",
"shasum": ""
},
"require": {
@@ -6955,7 +6973,7 @@
"validator"
],
"support": {
"source": "https://github.com/symfony/property-info/tree/v7.4.17"
"source": "https://github.com/symfony/property-info/tree/v7.4.18"
},
"funding": [
{
@@ -6975,11 +6993,11 @@
"type": "tidelift"
}
],
"time": "2026-08-21T17:40:08+00:00"
"time": "2026-08-25T14:18:37+00:00"
},
{
"name": "symfony/rate-limiter",
"version": "v7.4.16",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/rate-limiter.git",
@@ -7029,7 +7047,7 @@
"rate-limiter"
],
"support": {
"source": "https://github.com/symfony/rate-limiter/tree/v7.4.16"
"source": "https://github.com/symfony/rate-limiter/tree/v7.4.18"
},
"funding": [
{
@@ -7053,7 +7071,7 @@
},
{
"name": "symfony/routing",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
@@ -7114,7 +7132,7 @@
"url"
],
"support": {
"source": "https://github.com/symfony/routing/tree/v7.4.17"
"source": "https://github.com/symfony/routing/tree/v7.4.18"
},
"funding": [
{
@@ -7138,16 +7156,16 @@
},
{
"name": "symfony/service-contracts",
"version": "v3.7.1",
"version": "v3.7.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0"
"reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0",
"reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/15e6a07ec2a2c75ceb1b21dd98105ee8456d2257",
"reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257",
"shasum": ""
},
"require": {
@@ -7201,7 +7219,7 @@
"standards"
],
"support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.7.1"
"source": "https://github.com/symfony/service-contracts/tree/v3.7.3"
},
"funding": [
{
@@ -7221,7 +7239,7 @@
"type": "tidelift"
}
],
"time": "2026-06-16T09:55:08+00:00"
"time": "2026-07-27T15:39:01+00:00"
},
{
"name": "symfony/string",
@@ -7657,16 +7675,16 @@
},
{
"name": "symfony/validator",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/validator.git",
"reference": "b1cbb758c005fbe0d7b2b8d1561869d318628a10"
"reference": "976bd879fda78de30ee4688fd38ae87bc4d2dc76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/validator/zipball/b1cbb758c005fbe0d7b2b8d1561869d318628a10",
"reference": "b1cbb758c005fbe0d7b2b8d1561869d318628a10",
"url": "https://api.github.com/repos/symfony/validator/zipball/976bd879fda78de30ee4688fd38ae87bc4d2dc76",
"reference": "976bd879fda78de30ee4688fd38ae87bc4d2dc76",
"shasum": ""
},
"require": {
@@ -7737,7 +7755,7 @@
"description": "Provides tools to validate values",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/validator/tree/v7.4.17"
"source": "https://github.com/symfony/validator/tree/v7.4.18"
},
"funding": [
{
@@ -7757,7 +7775,7 @@
"type": "tidelift"
}
],
"time": "2026-08-22T09:04:42+00:00"
"time": "2026-08-30T00:47:26+00:00"
},
{
"name": "symfony/var-exporter",
@@ -7841,16 +7859,16 @@
},
{
"name": "symfony/yaml",
"version": "v7.4.17",
"version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "0b040d7b66ceb10b7bb24c8e6656257932693a12"
"reference": "4cef939e55b8a21c5780418de0d98ab00d0736e1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/0b040d7b66ceb10b7bb24c8e6656257932693a12",
"reference": "0b040d7b66ceb10b7bb24c8e6656257932693a12",
"url": "https://api.github.com/repos/symfony/yaml/zipball/4cef939e55b8a21c5780418de0d98ab00d0736e1",
"reference": "4cef939e55b8a21c5780418de0d98ab00d0736e1",
"shasum": ""
},
"require": {
@@ -7893,7 +7911,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v7.4.17"
"source": "https://github.com/symfony/yaml/tree/v7.4.18"
},
"funding": [
{
@@ -7913,7 +7931,7 @@
"type": "tidelift"
}
],
"time": "2026-08-21T12:09:28+00:00"
"time": "2026-08-30T00:47:26+00:00"
},
{
"name": "typo3/class-alias-loader",
@@ -10081,16 +10099,16 @@
},
{
"name": "typo3fluid/fluid",
"version": "5.3.1",
"version": "5.3.2",
"source": {
"type": "git",
"url": "https://github.com/TYPO3/Fluid.git",
"reference": "28c42c75b171aef196ddbe151b0d1146c290249d"
"reference": "2f16b9e8d2509f7abb6a087ad781e361351f465d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/TYPO3/Fluid/zipball/28c42c75b171aef196ddbe151b0d1146c290249d",
"reference": "28c42c75b171aef196ddbe151b0d1146c290249d",
"url": "https://api.github.com/repos/TYPO3/Fluid/zipball/2f16b9e8d2509f7abb6a087ad781e361351f465d",
"reference": "2f16b9e8d2509f7abb6a087ad781e361351f465d",
"shasum": ""
},
"require": {
@@ -10137,7 +10155,7 @@
"issues": "https://github.com/TYPO3/Fluid/issues",
"source": "https://github.com/TYPO3/Fluid"
},
"time": "2026-04-16T17:09:54+00:00"
"time": "2026-08-12T19:45:55+00:00"
},
{
"name": "webmozart/assert",