Repository: Sylius/Sylius
Pull request #18008: Allow ORM 3 on Promotion bundle
Author: login: loic425
Created: 2025-05-13T09:36:22Z | Merged: 2025-05-15T05:05:02Z

| Q               | A
|-----------------|-----
| Branch?         | orm-3
| Bug fix?        | no
| New feature?    | no
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | related to #17972 
| License         | MIT

I've refactored the test application, cause it was not working anymore with ORM mapping configuration.

<!--
 - Bug fixes must be submitted against the 1.14 or 2.0 branch
 - Features and deprecations must be submitted against the 2.1 branch
 - Make sure that the correct base branch is set

 To be sure you are not breaking any Backward Compatibilities, check the documentation:
 https://docs.sylius.com/en/latest/book/organization/backward-compatibility-promise.html
-->



Diff:
diff --git a/src/Sylius/Bundle/PromotionBundle/composer.json b/src/Sylius/Bundle/PromotionBundle/composer.json
index 27ecd0f6f64..2091a047fe5 100644
--- a/src/Sylius/Bundle/PromotionBundle/composer.json
+++ b/src/Sylius/Bundle/PromotionBundle/composer.json
@@ -32,17 +32,16 @@
         "sylius/money-bundle": "^2.0",
         "sylius/promotion": "^2.0",
         "sylius/registry": "^1.6",
-        "sylius/resource-bundle": "^1.12",
+        "sylius/resource-bundle": "^1.12 || ^1.13@alpha",
         "symfony/clock": "^6.4 || ^7.2",
         "symfony/framework-bundle": "^6.4.1 || ^7.2"
     },
     "conflict": {
-        "doctrine/orm": ">= 3.0",
         "phpstan/phpdoc-parser": ">= 2.0"
     },
     "require-dev": {
         "doctrine/doctrine-bundle": "^2.13",
-        "doctrine/orm": "^2.18",
+        "doctrine/orm": "^2.18 || ^3.3",
         "matthiasnoback/symfony-dependency-injection-test": "^5.1",
         "phpspec/phpspec": "^7.5",
         "phpspec/prophecy-phpunit": "^2.2",
@@ -74,7 +73,7 @@
         "psr-4": {
             "Sylius\\Bundle\\PromotionBundle\\spec\\": "spec/",
             "Sylius\\Bundle\\PromotionBundle\\Tests\\": "Tests/",
-            "AppBundle\\": "test/src/AppBundle/"
+            "App\\": "test/src/"
         },
         "classmap": [
             "test/app/AppKernel.php"
diff --git a/src/Sylius/Bundle/PromotionBundle/test/app/AppKernel.php b/src/Sylius/Bundle/PromotionBundle/test/app/AppKernel.php
index 169b1300948..e7dcc9c929a 100644
--- a/src/Sylius/Bundle/PromotionBundle/test/app/AppKernel.php
+++ b/src/Sylius/Bundle/PromotionBundle/test/app/AppKernel.php
@@ -25,7 +25,6 @@ public function registerBundles(): array
             new Sylius\Bundle\PromotionBundle\SyliusPromotionBundle(),
             new Sylius\Bundle\ResourceBundle\SyliusResourceBundle(),
             new Symfony\Bundle\TwigBundle\TwigBundle(),
-            new AppBundle\AppBundle(),
         ];
     }
 
diff --git a/src/Sylius/Bundle/PromotionBundle/test/app/config/config.yml b/src/Sylius/Bundle/PromotionBundle/test/app/config/config.yml
index bbaa126c0c5..312102a10e9 100644
--- a/src/Sylius/Bundle/PromotionBundle/test/app/config/config.yml
+++ b/src/Sylius/Bundle/PromotionBundle/test/app/config/config.yml
@@ -26,18 +26,23 @@ doctrine:
         path: "%database_path%"
         charset: UTF8
     orm:
-        entity_managers:
-            default:
-                auto_mapping: true
+        auto_mapping: true
+        mappings:
+            App:
+                type: attribute
+                is_bundle: false
+                dir: "%kernel.project_dir%/src/Entity"
+                prefix: 'App\Entity'
+                alias: App
 
 sylius_resource:
     resources:
         app.promotion_subject:
             classes:
-                model: AppBundle\Entity\PromotionSubject
+                model: App\Entity\PromotionSubject
 
 sylius_promotion:
     resources:
         promotion_subject:
             classes:
-                model: AppBundle\Entity\PromotionSubject
+                model: App\Entity\PromotionSubject
diff --git a/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/AppBundle.php b/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/AppBundle.php
deleted file mode 100644
index a5d113ba8b6..00000000000
--- a/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/AppBundle.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-
-/*
- * This file is part of the Sylius package.
- *
- * (c) Sylius Sp. z o.o.
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace AppBundle;
-
-use Symfony\Component\HttpKernel\Bundle\Bundle;
-
-class AppBundle extends Bundle
-{
-}
diff --git a/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/Resources/config/doctrine/PromotionSubject.orm.yml b/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/Resources/config/doctrine/PromotionSubject.orm.yml
deleted file mode 100644
index 1bfdca879d5..00000000000
--- a/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/Resources/config/doctrine/PromotionSubject.orm.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-AppBundle\Entity\PromotionSubject:
-    type: entity
-    table: app_promotion_subject
-    id:
-        id:
-            type: integer
-            id: true
-            generator:
-                strategy: AUTO
diff --git a/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/Entity/PromotionSubject.php b/src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
similarity index 75%
rename from src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/Entity/PromotionSubject.php
rename to src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
index 1827785480b..fe34b6c7db1 100644
--- a/src/Sylius/Bundle/PromotionBundle/test/src/AppBundle/Entity/PromotionSubject.php
+++ b/src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
@@ -11,21 +11,33 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
+use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
+#[ORM\Table(name: 'app_promotion_subject')]
 class PromotionSubject implements ResourceInterface, PromotionSubjectInterface
 {
-    private int $id;
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column(type: 'integer')]
+    private ?int $id = null;
 
     /** @var Collection<array-key, PromotionInterface> */
-    protected $promotions;
+    private Collection $promotions;
 
-    public function getId(): int
+    public function __construct()
+    {
+        $this->promotions = new ArrayCollection();
+    }
+
+    public function getId(): ?int
     {
         return $this->id;
     }


Reviews:
user: login: diimpp
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-13T11:22:00Z
user: login: Prometee
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T12:29:01Z
user: login: loic425
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-13T12:59:36Z
user: login: diimpp
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-15T01:12:39Z
user: login: diimpp
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T01:17:51Z
user: login: loic425
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T05:04:01Z

Review comments:
diff_hunk: @@ -11,15 +11,21 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
+#[ORM\Table(name: 'app_promotion_subject')]
 class PromotionSubject implements ResourceInterface, PromotionSubjectInterface
 {
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column(type: 'integer')]
     private int $id;
path: src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
user: login: diimpp
body: Is it a good time to update this Entity as well? No constructor with ArrayCollection assign looks broken.


```suggestion
    private ?int $id;
```
and

```patch
    /** @var Collection<array-key, PromotionInterface> */
---    protected $promotions;
+++    protected Collection $promotions;
```
and

```patch
+++    public __construct()
+++    {
+++        $this->promotions = new ArrayCollection();
+++    }
```
created_at: 2025-05-13T11:20:03Z
author_association: MEMBER
diff_hunk: @@ -11,15 +11,21 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
path: src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
user: login: diimpp
body: Checking just in case, do we use attribute mappings in sylius/sylius?
created_at: 2025-05-13T11:20:50Z
author_association: MEMBER
diff_hunk: @@ -11,15 +11,21 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
path: src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
user: login: Prometee
body: No we don't always XML mapping
created_at: 2025-05-13T12:29:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -11,15 +11,21 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
path: src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
user: login: loic425
body: Yes, but that's normal that Sylius uses external configuration files. but in test application, that's better to use sth easier and more conventional (sth close to userland applications).
created_at: 2025-05-13T12:59:36Z
author_association: MEMBER
diff_hunk: @@ -11,15 +11,21 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
path: src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
user: login: diimpp
body: I tend to agree on test app using attributes.

Here is example in the `sylius/sylius`, which is using annotations for tests.
https://github.com/Sylius/Sylius/blob/2.1/tests/Functional/Doctrine/Dump/Model.php
https://github.com/Sylius/Sylius/blob/2.1/tests/Functional/Doctrine/Dump/CompositeKeysModel.php
created_at: 2025-05-15T01:11:41Z
author_association: MEMBER
diff_hunk: @@ -11,15 +11,21 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
path: src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
user: login: diimpp
body: P.S. tests annotation usages reported https://github.com/Sylius/Sylius/issues/18030
created_at: 2025-05-15T01:17:51Z
author_association: MEMBER
diff_hunk: @@ -11,15 +11,21 @@
 
 declare(strict_types=1);
 
-namespace AppBundle\Entity;
+namespace App\Entity;
 
 use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
 use Sylius\Component\Promotion\Model\PromotionInterface;
 use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
 use Sylius\Resource\Model\ResourceInterface;
 
+#[ORM\Entity]
path: src/Sylius/Bundle/PromotionBundle/test/src/Entity/PromotionSubject.php
user: login: loic425
body: Already fixed in a next PR cause we need to remove annotations. I'll mention your issue there.
created_at: 2025-05-15T05:04:01Z
author_association: MEMBER

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-13T09:36:29Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: skip review by coderabbit.ai -->

> [!IMPORTANT]
> ## Review skipped
> 
> Auto reviews are disabled on base/target branches other than the default branch.
> 
> 
> 
> Please check the settings in the CodeRabbit UI or the `.coderabbit.yaml` file in this repository. To trigger a single review, invoke the `@coderabbitai review` command.
> 
> You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file.

<!-- end of auto-generated comment: skip review by coderabbit.ai -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Sylius/Sylius&utm_content=18008):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-13T09:43:47Z
body: ### :x: Preview Environment deleted from [Bunnyshell](https://www.bunnyshell.com)

Available commands:
  - :rocket: `/bns:deploy` to redeploy the environment
<!-- thollander/actions-comment-pull-request "bunnyshell-preview-env" -->
author_association: NONE