Skip to content

[XML2PHP] TaxonomyBundle#18775

Merged
TheMilek merged 1 commit intoSylius:2.3from
crydotsnake:xml2php/taxonomy
Feb 4, 2026
Merged

[XML2PHP] TaxonomyBundle#18775
TheMilek merged 1 commit intoSylius:2.3from
crydotsnake:xml2php/taxonomy

Conversation

@crydotsnake
Copy link
Copy Markdown
Member

@crydotsnake crydotsnake commented Jan 31, 2026

Q A
Branch? 2.3
Bug fix? no
New feature? no
BC breaks? no
Deprecations? no
Related tickets partially #18490
License MIT

Summary by CodeRabbit

  • Chores

    • Modernized internal service configuration format without changing user-facing behavior.
  • New Features

    • Added Taxon form types for editing and positioning.
    • Introduced a dedicated taxon slug generator and taxon tree provider.
    • Added a parent-relation validator for taxons.
  • Integrations

    • Registered repository wiring for Doctrine ORM and MongoDB ODM integrations.

@crydotsnake crydotsnake requested review from a team as code owners January 31, 2026 13:14
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 31, 2026

📝 Walkthrough

Walkthrough

Migrates TaxonomyBundle DependencyInjection from XML to PHP: replaces XmlFileLoader with PhpFileLoader and converts all service, form, repository, and Doctrine integration configs from .xml to .php while preserving existing DI wiring and registrations.

Changes

Cohort / File(s) Summary
Dependency Injection Extension
src/Sylius/Bundle/TaxonomyBundle/DependencyInjection/SyliusTaxonomyExtension.php
Switched loader from XmlFileLoader to PhpFileLoader; updated all resource paths to load .php files instead of .xml (services, form, tree_repository, integrations).
Core Services
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.php, src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.xml
Added services.php with service definitions (taxon factory decorator, slug generator, taxon tree provider, parent-relation validator) and removed the old services.xml.
Form Types
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/form.php, src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/form.xml
Converted form type parameter and service declarations to form.php (three form types + validation group params); removed form.xml.
Tree Repository
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/tree_repository.php, .../tree_repository.xml
Replaced XML with PHP wiring for nested tree repositories and a decorated custom tree repository; added tree_repository.php, removed XML counterpart.
Doctrine ORM integration
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/orm.php, .../orm.xml
Added orm.php to set sylius.repository.taxon.class to TaxonRepository::class; removed the XML parameter file.
Doctrine MongoDB ODM integration
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/mongodb-odm.php, .../mongodb-odm.xml
Added PHP-based services for ODM unit of work, manager alias, metadata and repository; removed the XML variant.
Composer require checker
composer-require-checker.json
Added "inline_service" and "service" to the symbol whitelist.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

Maintenance, DX

Suggested reviewers

  • TheMilek
  • mpysiak

Poem

🐰 I hopped from XML to PHP with cheer,
Services reborn, the code feels near,
Same logic, new dress, neat and spry,
Taxonomy hops—hello new sky! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[XML2PHP] TaxonomyBundle' directly and clearly describes the main change: migrating TaxonomyBundle configuration from XML to PHP format. This accurately summarizes the primary objective evident across all file changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 31, 2026

❌ Preview Environment deleted from Bunnyshell

Available commands:

  • 🚀 /bns:deploy to redeploy the environment

@TheMilek
Copy link
Copy Markdown
Member

TheMilek commented Feb 2, 2026

to make the build pass you can suppress this phpstan error in phpstan.neon.dist or I think using strings instead of ::class should do the trick also 🤔

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.php`:
- Around line 24-49: The closure passed to the ContainerConfigurator currently
lacks a return type; update the anonymous function signature that takes
ContainerConfigurator $container to declare a return type of void so it conforms
to the project's PHP typing guideline (look for the closure building services
and imports and add the ": void" return type to that function).

In
`@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/mongodb-odm.php`:
- Around line 18-36: The closure passed to configure services currently has no
return type; update the anonymous function declaration "static function
(ContainerConfigurator $container)" to include an explicit void return type
(i.e. "static function (ContainerConfigurator $container): void") so the
configurator closure matches Symfony's typing guideline and the project's
requirement for declared return types; modify the declaration where the
ContainerConfigurator closure is defined in this services configurator.

In
`@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/orm.php`:
- Around line 18-21: The configurator closure in this file lacks a return type;
update the anonymous function signature that takes ContainerConfigurator
$container (the closure returned by the file) to declare a void return type
(i.e., add ": void") so the function signature becomes a typed closure returning
nothing; ensure you modify the closure declaration where ContainerConfigurator
is used and leave the body (parameters->set('sylius.repository.taxon.class',
TaxonRepository::class)) unchanged.
🧹 Nitpick comments (2)
src/Sylius/Bundle/TaxonomyBundle/DependencyInjection/SyliusTaxonomyExtension.php (1)

16-19: Sort use imports alphabetically.
Keeps the imports aligned with the repo’s ordering rule.

♻️ Proposed fix
 use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension;
-use Symfony\Component\Config\FileLocator;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\Config\FileLocator;
 use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

As per coding guidelines, Sort PHP use imports alphabetically and group by type (classes, functions, constants).

src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.php (1)

16-23: Sort use imports alphabetically.
Keeps imports aligned with the repo’s ordering rule.

♻️ Proposed fix
-use Sylius\Bundle\TaxonomyBundle\Provider\TaxonTreeProvider;
-use Sylius\Bundle\TaxonomyBundle\Validator\Constraints\TaxonParentRelationValidator;
 use Sylius\Component\Taxonomy\Factory\TaxonFactory;
 use Sylius\Component\Taxonomy\Factory\TaxonFactoryInterface;
 use Sylius\Component\Taxonomy\Generator\TaxonSlugGenerator;
 use Sylius\Component\Taxonomy\Generator\TaxonSlugGeneratorInterface;
+use Sylius\Bundle\TaxonomyBundle\Provider\TaxonTreeProvider;
 use Sylius\Component\Taxonomy\Provider\TaxonTreeProviderInterface;
+use Sylius\Bundle\TaxonomyBundle\Validator\Constraints\TaxonParentRelationValidator;

As per coding guidelines, Sort PHP use imports alphabetically and group by type (classes, functions, constants).

Comment on lines +24 to +49
return static function (ContainerConfigurator $container) {
$services = $container->services();
$container->import('services/form.php');
$container->import('services/tree_repository.php');

$services->set('sylius.custom_factory.taxon', TaxonFactory::class)
->decorate('sylius.factory.taxon', null, 256)
->args([service('sylius.custom_factory.taxon.inner')]);

$services->alias(TaxonFactoryInterface::class, 'sylius.custom_factory.taxon');

$services->set('sylius.generator.taxon_slug', TaxonSlugGenerator::class);

$services->alias(TaxonSlugGeneratorInterface::class, 'sylius.generator.taxon_slug');

$services->set('sylius.provider.taxon_tree', TaxonTreeProvider::class)
->args([
service('sylius.repository.taxon'),
service('sylius.repository.nested_tree.taxon'),
]);

$services->alias(TaxonTreeProviderInterface::class, 'sylius.provider.taxon_tree');

$services->set('sylius.validator.taxon_parent_relation', TaxonParentRelationValidator::class)
->tag('validator.constraint_validator', ['alias' => 'sylius_taxon_parent_relation_validator']);
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.php

Repository: Sylius/Sylius

Length of output: 273


🌐 Web query:

Sylius service configuration closure return type PHP typing

💡 Result:

In Sylius (Symfony) PHP service configuration files (e.g. config/services.php), the closure you return is a configurator callback and should be typed as returning void:

<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $container): void {
    $services = $container->services();
    // ...
};

Symfony’s docs show this same pattern for PHP-based service configuration closures (the returned closure is not meant to “return” service definitions; it configures the container). [1]

If what you mean is closures used inside a service locator/subscriber map, then the closure’s return type matters for PHP typing/introspection: Symfony notes that getProvidedServices() uses the closures’ declared return types; without them, the provided type becomes ?. So you should explicitly type them, e.g.:

$locator = new class([
    'foo' => static fn (): Foo => new Foo(),
]) implements \Symfony\Contracts\Service\ServiceProviderInterface {
    use \Symfony\Contracts\Service\ServiceLocatorTrait;
};

[2]

Sources: Symfony service container / PHP configurator closures [1], Symfony service subscribers/locators note about closure return types [2].


Add a return type to the configurator closure.
Required by the repo's PHP typing guideline.

🛠️ Proposed fix
-return static function (ContainerConfigurator $container) {
+return static function (ContainerConfigurator $container): void {

Service configurator closures in Symfony/Sylius PHP configuration files must declare a return type of void.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return static function (ContainerConfigurator $container) {
$services = $container->services();
$container->import('services/form.php');
$container->import('services/tree_repository.php');
$services->set('sylius.custom_factory.taxon', TaxonFactory::class)
->decorate('sylius.factory.taxon', null, 256)
->args([service('sylius.custom_factory.taxon.inner')]);
$services->alias(TaxonFactoryInterface::class, 'sylius.custom_factory.taxon');
$services->set('sylius.generator.taxon_slug', TaxonSlugGenerator::class);
$services->alias(TaxonSlugGeneratorInterface::class, 'sylius.generator.taxon_slug');
$services->set('sylius.provider.taxon_tree', TaxonTreeProvider::class)
->args([
service('sylius.repository.taxon'),
service('sylius.repository.nested_tree.taxon'),
]);
$services->alias(TaxonTreeProviderInterface::class, 'sylius.provider.taxon_tree');
$services->set('sylius.validator.taxon_parent_relation', TaxonParentRelationValidator::class)
->tag('validator.constraint_validator', ['alias' => 'sylius_taxon_parent_relation_validator']);
};
return static function (ContainerConfigurator $container): void {
$services = $container->services();
$container->import('services/form.php');
$container->import('services/tree_repository.php');
$services->set('sylius.custom_factory.taxon', TaxonFactory::class)
->decorate('sylius.factory.taxon', null, 256)
->args([service('sylius.custom_factory.taxon.inner')]);
$services->alias(TaxonFactoryInterface::class, 'sylius.custom_factory.taxon');
$services->set('sylius.generator.taxon_slug', TaxonSlugGenerator::class);
$services->alias(TaxonSlugGeneratorInterface::class, 'sylius.generator.taxon_slug');
$services->set('sylius.provider.taxon_tree', TaxonTreeProvider::class)
->args([
service('sylius.repository.taxon'),
service('sylius.repository.nested_tree.taxon'),
]);
$services->alias(TaxonTreeProviderInterface::class, 'sylius.provider.taxon_tree');
$services->set('sylius.validator.taxon_parent_relation', TaxonParentRelationValidator::class)
->tag('validator.constraint_validator', ['alias' => 'sylius_taxon_parent_relation_validator']);
};
🤖 Prompt for AI Agents
In `@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.php` around lines
24 - 49, The closure passed to the ContainerConfigurator currently lacks a
return type; update the anonymous function signature that takes
ContainerConfigurator $container to declare a return type of void so it conforms
to the project's PHP typing guideline (look for the closure building services
and imports and add the ": void" return type to that function).

Comment on lines +18 to +36
return static function (ContainerConfigurator $container) {
$services = $container->services();

$services->set('sylius.doctrine.odm.mongodb.unit_of_work', 'Doctrine\ODM\MongoDB\UnitOfWork')
->factory([service('doctrine.odm.mongodb.document_manager'), 'getUnitOfWork']);

$services->alias('sylius.manager.taxon', 'doctrine.odm.mongodb.document_manager');

$services->set('sylius.doctrine.odm.mongodb.metadata.taxon', 'Doctrine\ODM\MongoDB\Mapping\ClassMetadata')
->args(['%sylius.model.taxon.class%'])
->factory([service('sylius.manager.taxon'), 'getClassMetadata']);

$services->set('sylius.repository.taxon', DocumentRepository::class)
->args([
service('sylius.manager.taxon'),
service('sylius.doctrine.odm.mongodb.unit_of_work'),
service('sylius.doctrine.odm.mongodb.metadata.taxon'),
]);
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/mongodb-odm.php

Repository: Sylius/Sylius

Length of output: 273


🌐 Web query:

Symfony ContainerConfigurator closure return type service configuration

💡 Result:

In a Symfony PHP service config file (e.g. config/services.php), the file returns a closure, and that closure should return void (you configure the container inside it; you don’t return definitions). Symfony’s docs show this signature:

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return function (ContainerConfigurator $containerConfigurator, string $env): void {
    // configure services here
};

[1]

The : void return type is recommended/commonly used, but Symfony examples also show it can be omitted (the closure still shouldn’t return anything meaningful). [2]

Sources: [1] Symfony “Service Container” docs (current) (symfony.com), [2] Symfony “Service Container” docs (v7.2) (symfony.com)

Citations:


Add a return type to the configurator closure.

Symfony service configurator closures should declare a : void return type per both Symfony documentation and the coding guideline requiring type declarations for all return values.

🛠️ Proposed fix
-return static function (ContainerConfigurator $container) {
+return static function (ContainerConfigurator $container): void {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return static function (ContainerConfigurator $container) {
$services = $container->services();
$services->set('sylius.doctrine.odm.mongodb.unit_of_work', 'Doctrine\ODM\MongoDB\UnitOfWork')
->factory([service('doctrine.odm.mongodb.document_manager'), 'getUnitOfWork']);
$services->alias('sylius.manager.taxon', 'doctrine.odm.mongodb.document_manager');
$services->set('sylius.doctrine.odm.mongodb.metadata.taxon', 'Doctrine\ODM\MongoDB\Mapping\ClassMetadata')
->args(['%sylius.model.taxon.class%'])
->factory([service('sylius.manager.taxon'), 'getClassMetadata']);
$services->set('sylius.repository.taxon', DocumentRepository::class)
->args([
service('sylius.manager.taxon'),
service('sylius.doctrine.odm.mongodb.unit_of_work'),
service('sylius.doctrine.odm.mongodb.metadata.taxon'),
]);
};
return static function (ContainerConfigurator $container): void {
$services = $container->services();
$services->set('sylius.doctrine.odm.mongodb.unit_of_work', 'Doctrine\ODM\MongoDB\UnitOfWork')
->factory([service('doctrine.odm.mongodb.document_manager'), 'getUnitOfWork']);
$services->alias('sylius.manager.taxon', 'doctrine.odm.mongodb.document_manager');
$services->set('sylius.doctrine.odm.mongodb.metadata.taxon', 'Doctrine\ODM\MongoDB\Mapping\ClassMetadata')
->args(['%sylius.model.taxon.class%'])
->factory([service('sylius.manager.taxon'), 'getClassMetadata']);
$services->set('sylius.repository.taxon', DocumentRepository::class)
->args([
service('sylius.manager.taxon'),
service('sylius.doctrine.odm.mongodb.unit_of_work'),
service('sylius.doctrine.odm.mongodb.metadata.taxon'),
]);
};
🤖 Prompt for AI Agents
In
`@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/mongodb-odm.php`
around lines 18 - 36, The closure passed to configure services currently has no
return type; update the anonymous function declaration "static function
(ContainerConfigurator $container)" to include an explicit void return type
(i.e. "static function (ContainerConfigurator $container): void") so the
configurator closure matches Symfony's typing guideline and the project's
requirement for declared return types; modify the declaration where the
ContainerConfigurator closure is defined in this services configurator.

Comment on lines +18 to +21
return static function (ContainerConfigurator $container) {
$parameters = $container->parameters();
$parameters->set('sylius.repository.taxon.class', TaxonRepository::class);
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/orm.php

Repository: Sylius/Sylius

Length of output: 273


Add a return type to the configurator closure.

The closure parameter is already typed, but the return type is missing. Per the repository's PHP typing guideline, add : void to the closure signature since it returns nothing.

🛠️ Proposed fix
-return static function (ContainerConfigurator $container) {
+return static function (ContainerConfigurator $container): void {
🤖 Prompt for AI Agents
In
`@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/orm.php`
around lines 18 - 21, The configurator closure in this file lacks a return type;
update the anonymous function signature that takes ContainerConfigurator
$container (the closure returned by the file) to declare a void return type
(i.e., add ": void") so the function signature becomes a typed closure returning
nothing; ensure you modify the closure declaration where ContainerConfigurator
is used and leave the body (parameters->set('sylius.repository.taxon.class',
TaxonRepository::class)) unchanged.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/form.php`:
- Line 20: The closure returned in
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/form.php (the static
function signature taking ContainerConfigurator $container) must declare a void
return type; update the function signature for the returned closure to include
": void" after the parameter list so it becomes a properly typed configurator
closure.
🧹 Nitpick comments (1)
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/integrations/doctrine/mongodb-odm.php (1)

16-27: Prefer imports + ::class for Doctrine types (verify against phpstan).

The guideline requires use statements for non-global classes; using class constants is safer for refactors. If phpstan currently requires string FQCNs here, please confirm before switching.

♻️ Proposed refactor
 use Sylius\Bundle\ResourceBundle\Doctrine\ODM\MongoDB\DocumentRepository;
+use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
+use Doctrine\ODM\MongoDB\UnitOfWork;
 
-return static function (ContainerConfigurator $container) {
+return static function (ContainerConfigurator $container): void {
     $services = $container->services();
 
-    $services->set('sylius.doctrine.odm.mongodb.unit_of_work', 'Doctrine\ODM\MongoDB\UnitOfWork')
+    $services->set('sylius.doctrine.odm.mongodb.unit_of_work', UnitOfWork::class)
         ->factory([service('doctrine.odm.mongodb.document_manager'), 'getUnitOfWork']);
 
     $services->alias('sylius.manager.taxon', 'doctrine.odm.mongodb.document_manager');
 
-    $services->set('sylius.doctrine.odm.mongodb.metadata.taxon', 'Doctrine\ODM\MongoDB\Mapping\ClassMetadata')
+    $services->set('sylius.doctrine.odm.mongodb.metadata.taxon', ClassMetadata::class)
         ->args(['%sylius.model.taxon.class%'])
         ->factory([service('sylius.manager.taxon'), 'getClassMetadata']);

use Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonTranslationType;
use Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonType;

return static function (ContainerConfigurator $container) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a return type to the configurator closure.

The closure is missing the required : void return type per PHP typing guidelines.

-return static function (ContainerConfigurator $container) {
+return static function (ContainerConfigurator $container): void {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return static function (ContainerConfigurator $container) {
return static function (ContainerConfigurator $container): void {
🤖 Prompt for AI Agents
In `@src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/form.php` at line
20, The closure returned in
src/Sylius/Bundle/TaxonomyBundle/Resources/config/services/form.php (the static
function signature taking ContainerConfigurator $container) must declare a void
return type; update the function signature for the returned closure to include
": void" after the parameter list so it becomes a properly typed configurator
closure.

@TheMilek TheMilek merged commit ef26c05 into Sylius:2.3 Feb 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants