Skip to content

Commit

Permalink
Merge pull request #2677 from doctrine/2.9.x-merge-up-into-3.0.x_f7Yv…
Browse files Browse the repository at this point in the history
…smfj

Merge release 2.9.0 into 3.0.x
  • Loading branch information
alcaeus authored Sep 20, 2024
2 parents 296b025 + 3c9b1e8 commit 39c5285
Show file tree
Hide file tree
Showing 78 changed files with 1,573 additions and 781 deletions.
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ updates:
directory: "/"
schedule:
interval: "weekly"
labels:
- "CI"
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"ext-bcmath": "*",
"doctrine/annotations": "^1.12 || ^2.0",
"doctrine/coding-standard": "^12.0",
"doctrine/orm": "^3.2",
"jmikola/geojson": "^1.0",
"phpbench/phpbench": "^1.0.0",
"phpstan/phpstan": "~1.10.67",
Expand Down
86 changes: 39 additions & 47 deletions docs/en/cookbook/blending-orm-and-mongodb-odm.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Blending the ORM and MongoDB ODM
================================

Since the start of the `Doctrine MongoDB Object Document Mapper`_ project people have asked how it can be integrated with the `ORM`_. This article will demonstrates how you can integrate the two transparently, maintaining a clean domain model.
This article demonstrates how you can integrate the `Doctrine MongoDB ODM`_
and the `ORM`_ transparently, maintaining a clean domain model. This is
something that is supported indirectly by the libraries by using the events.

This example will have a ``Product`` that is stored in MongoDB and the ``Order`` stored in a MySQL database.
This example will have a ``Product`` that is stored in MongoDB and the ``Order``
stored in a SQL database like MySQL, PostgreSQL or SQLite.

Define Product
--------------
Expand All @@ -20,31 +23,17 @@ First lets define our ``Product`` document:
class Product
{
#[Id]
private $id;
public string $id;
#[Field(type: 'string')]
private $title;
public function getId(): ?string
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): void
{
$this->title = $title;
}
public string $title;
}
Define Entity
-------------

Next create the ``Order`` entity that has a ``$product`` and ``$productId`` property linking it to the ``Product`` that is stored with MongoDB:
Next create the ``Order`` entity that has a ``$product`` and ``$productId``
property linking it to the ``Product`` that is stored with MongoDB:

.. code-block:: php
Expand All @@ -61,15 +50,12 @@ Next create the ``Order`` entity that has a ``$product`` and ``$productId`` prop
#[Id]
#[Column(type: 'int')]
#[GeneratedValue(strategy: 'AUTO')]
private $id;
public int $id;
#[Column(type: 'string')]
private $productId;
private string $productId;
/**
* @var Documents\Product
*/
private $product;
private Product $product;
public function getId(): ?int
{
Expand All @@ -96,7 +82,10 @@ Next create the ``Order`` entity that has a ``$product`` and ``$productId`` prop
Event Subscriber
----------------

Now we need to setup an event subscriber that will set the ``$product`` property of all ``Order`` instances to a reference to the document product so it can be lazily loaded when it is accessed the first time. So first register a new event subscriber:
Now we need to setup an event subscriber that will set the ``$product`` property
of all ``Order`` instances to a reference to the document product so it can be
lazily loaded when it is accessed the first time. So first register a new event
subscriber:

.. code-block:: php
Expand All @@ -107,15 +96,17 @@ Now we need to setup an event subscriber that will set the ``$product`` property
[\Doctrine\ORM\Events::postLoad], new MyEventSubscriber($dm)
);
or in .yaml
or in YAML configuration of the Symfony container:

.. code-block:: yaml
App\Listeners\MyEventSubscriber:
tags:
- { name: doctrine.event_listener, connection: default, event: postLoad}
- { name: doctrine.event_listener, connection: default, event: postLoad }
So now we need to define a class named ``MyEventSubscriber`` and pass ``DocumentManager`` as a dependency. It will have a ``postLoad()`` method that sets the product document reference:
So now we need to define a class named ``MyEventSubscriber`` and pass
``DocumentManager`` as a dependency. It will have a ``postLoad()`` method that
sets the product document reference:

.. code-block:: php
Expand All @@ -126,10 +117,9 @@ So now we need to define a class named ``MyEventSubscriber`` and pass ``Document
class MyEventSubscriber
{
public function __construct(DocumentManager $dm)
{
$this->dm = $dm;
}
public function __construct(
private readonly DocumentManager $dm,
) {}
public function postLoad(LifecycleEventArgs $eventArgs): void
{
Expand All @@ -139,13 +129,13 @@ So now we need to define a class named ``MyEventSubscriber`` and pass ``Document
return;
}
$em = $eventArgs->getEntityManager();
$productReflProp = $em->getClassMetadata(Order::class)
->reflClass->getProperty('product');
$productReflProp->setAccessible(true);
$productReflProp->setValue(
$order, $this->dm->getReference(Product::class, $order->getProductId())
);
$product = $this->dm->getReference(Product::class, $order->getProductId());
$eventArgs->getObjectManager()
->getClassMetadata(Order::class)
->reflClass
->getProperty('product')
->setValue($order, $product);
}
}
Expand All @@ -165,7 +155,7 @@ First create a new ``Product``:
<?php
$product = new \Documents\Product();
$product->setTitle('Test Product');
$product->title = 'Test Product';
$dm->persist($product);
$dm->flush();
Expand All @@ -180,19 +170,21 @@ Now create a new ``Order`` and link it to a ``Product`` in MySQL:
$em->persist($order);
$em->flush();
Later we can retrieve the entity and lazily load the reference to the document in MongoDB:
Later we can retrieve the entity and lazily load the reference to the document
in MongoDB:

.. code-block:: php
<?php
$order = $em->find(Order::class, $order->getId());
$order = $em->find(Order::class, $order->id);
$product = $order->getProduct();
echo "Order Title: " . $product->getTitle();
echo "Order Title: " . $product->title;
If you were to print the ``$order`` you would see that we got back regular PHP objects:
If you were to print the ``$order`` you would see that we got back regular PHP
objects:

.. code-block:: php
Expand All @@ -216,5 +208,5 @@ The above would output the following:
)
)
.. _Doctrine MongoDB Object Document Mapper: http://www.doctrine-project.org/projects/mongodb_odm
.. _Doctrine MongoDB ODM: http://www.doctrine-project.org/projects/mongodb_odm
.. _ORM: http://www.doctrine-project.org/projects/orm
77 changes: 0 additions & 77 deletions docs/en/cookbook/implementing-wakeup-or-clone.rst

This file was deleted.

Loading

0 comments on commit 39c5285

Please sign in to comment.