Skip to content

Commit e497155

Browse files
committed
Merge branch '1.3.x'
* 1.3.x: Don't apply filters and discriminators when using $indexStats Adapt API to BlogPostRepositoryInterface Updated RepositoryClass::class syntax and added an Interface Some errors or confusing class names changed
2 parents 89c4da8 + 3dc2c8c commit e497155

File tree

3 files changed

+63
-26
lines changed

3 files changed

+63
-26
lines changed

docs/en/cookbook/mapping-classes-to-orm-and-odm.rst

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
Mapping Classes to the ORM and ODM
22
==================================
33

4-
Because of the non intrusive design of Doctrine it is possible for you to have plain PHP classes
5-
that are mapped to both a relational database with the Doctrine2 Object Relational Mapper and
6-
MongoDB with the Doctrine MongoDB Object Document Mapper, or any other persistence layer that
4+
Because of the non-intrusive design of Doctrine, it is possible for you to have plain PHP classes
5+
that are mapped to both a relational database (with the Doctrine2 Object Relational Mapper) and
6+
MongoDB (with the Doctrine MongoDB Object Document Mapper), or any other persistence layer that
77
implements the Doctrine Common `persistence`_ interfaces.
88

99
Test Subject
1010
------------
1111

12-
For this cookbook entry we need to define a class that can be persisted to both MySQL and MongoDB.
12+
For this cookbook entry, we need to define a class that can be persisted to both MySQL and MongoDB.
1313
We'll use a ``BlogPost`` as you may want to write some generic blogging functionality that has support
1414
for multiple Doctrine persistence layers:
1515

1616
.. code-block:: php
1717
1818
<?php
1919
20-
namespace Doctrine\Blog;
20+
namespace Documents\Blog;
2121
2222
class BlogPost
2323
{
@@ -45,9 +45,11 @@ First define the mapping for the ORM:
4545
4646
<?php
4747
48-
namespace Doctrine\Blog;
48+
namespace Documents\Blog;
4949
50-
/** @Entity(repositoryClass="Doctrine\Blog\ORM\BlogPostRepository") */
50+
use Documents\Blog\Repository\ORM\BlogPostRepository;
51+
52+
/** @Entity(repositoryClass=BlogPostRepository::class) */
5153
class BlogPost
5254
{
5355
/** @Id @Column(type="integer") */
@@ -70,20 +72,20 @@ First define the mapping for the ORM:
7072
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
7173
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
7274
73-
<entity name="Documents\BlogPost" repository-class="Doctrine\Blog\ORM\BlogPostRepository">
75+
<entity name="Documents\Blog\BlogPost" repository-class="Documents\Blog\Repository\ORM\BlogPostRepository">
7476
<id name="id" type="integer" />
7577
<field name="name" type="string" />
7678
<field name="email" type="text" />
7779
</entity>
7880
</doctrine-mapping>
7981
80-
Now you are able to persist the ``Documents\BlogPost`` with an instance of ``EntityManager``:
82+
Now you are able to persist the ``Documents\Blog\BlogPost`` with an instance of ``EntityManager``:
8183

8284
.. code-block:: php
8385
8486
<?php
8587
86-
$blogPost = new BlogPost()
88+
$blogPost = new BlogPost();
8789
$blogPost->setTitle('test');
8890
8991
$em->persist($blogPost);
@@ -95,7 +97,7 @@ You can find the blog post:
9597
9698
<?php
9799
98-
$blogPost = $em->getRepository(Documents\BlogPost::class)->findOneBy(['title' => 'test']);
100+
$blogPost = $em->getRepository(BlogPost::class)->findOneBy(array('title' => 'test'));
99101
100102
MongoDB ODM
101103
~~~~~~~~~~~
@@ -108,9 +110,11 @@ Now map the same class to the Doctrine MongoDB ODM:
108110
109111
<?php
110112
111-
namespace Documents;
113+
namespace Documents\Blog;
114+
115+
use Documents\Blog\Repository\ODM\BlogPostRepository;
112116
113-
/** @Document(repositoryClass="Doctrine\Blog\ODM\MongoDB\BlogPostRepository") */
117+
/** @Document(repositoryClass=BlogPostRepository::class) */
114118
class BlogPost
115119
{
116120
/** @Id */
@@ -133,8 +137,8 @@ Now map the same class to the Doctrine MongoDB ODM:
133137
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
134138
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
135139
136-
<document name="Documents\BlogPost" repository-class="Doctrine\Blog\ODM\MongoDB\BlogPostRepository">
137-
<field field-name="id" type="id" />
140+
<document name="Documents\Blog\BlogPost" repository-class="Documents\Blog\Repository\ODM\BlogPostRepository">
141+
<id strategy="INCREMENT" type="int" />
138142
<field field-name="name" type="string" />
139143
<field field-name="email" type="text" />
140144
</document>
@@ -146,7 +150,7 @@ Now the same class is able to be persisted in the same way using an instance of
146150
147151
<?php
148152
149-
$blogPost = new BlogPost()
153+
$blogPost = new BlogPost();
150154
$blogPost->setTitle('test');
151155
152156
$dm->persist($blogPost);
@@ -158,23 +162,39 @@ You can find the blog post:
158162
159163
<?php
160164
161-
$blogPost = $dm->getRepository(Documents\BlogPost::class)->findOneBy(['title' => 'test']);
165+
$blogPost = $dm->getRepository(BlogPost::class)->findOneBy(array('title' => 'test'));
162166
163167
Repository Classes
164168
------------------
165169

166-
You can implement the same repository interface for the ORM and MongoDB ODM easily:
170+
You can implement the same repository interface for the ORM and MongoDB ODM easily, e.g. by creating ``BlogPostRepositoryInterface``:
167171

168172
.. code-block:: php
169173
170174
<?php
175+
// An Interface to ensure ORM and ODM Repository classes have the same methods implemented
176+
177+
namespace Documents\Blog\Repository;
178+
179+
use Documents\Blog\BlogPost;
180+
181+
interface BlogPostRepositoryInterface
182+
{
183+
public function findPostById(int $id): ?BlogPost;
184+
}
171185
172-
namespace Doctrine\Blog\ORM;
186+
Define repository methods required by the interface for the ORM:
173187

174-
use Doctrine\Blog\BlogPost;
188+
.. code-block:: php
189+
190+
<?php
191+
192+
namespace Documents\Blog\Repository\ORM;
193+
194+
use Documents\Blog\Repository\BlogPostRepositoryInterface;
175195
use Doctrine\ORM\EntityRepository;
176196
177-
class BlogPostRepository extends EntityRepository
197+
class BlogPostRepository extends EntityRepository implements BlogPostRepositoryInterface
178198
{
179199
public function findPostById(int $id): ?BlogPost
180200
{
@@ -188,14 +208,14 @@ Now define the same repository methods for the MongoDB ODM:
188208
189209
<?php
190210
191-
namespace Doctrine\Blog\ODM\MongoDB;
211+
namespace Documents\Blog\Repository\ODM;
192212
193-
use Documents\BlogPost;
194-
use Doctrine\ODM\MongoDB\DocumentRepository;
213+
use Documents\Blog\Repository\BlogPostRepositoryInterface;
214+
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
195215
196-
class BlogPostRepository extends DocumentRepository
216+
class BlogPostRepository extends DocumentRepository implements BlogPostRepositoryInterface
197217
{
198-
public function findPostById(string $id): ?BlogPost
218+
public function findPostById(int $id): ?BlogPost
199219
{
200220
return $this->findOneBy(['id' => $id]);
201221
}

lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ static function (Stage $stage) {
233233

234234
if ($this->getStage(0) instanceof Stage\GeoNear) {
235235
$pipeline[0]['$geoNear']['query'] = $this->applyFilters($pipeline[0]['$geoNear']['query']);
236+
} elseif ($this->getStage(0) instanceof Stage\IndexStats) {
237+
// Don't apply any filters when using an IndexStats stage: since it
238+
// needs to be the first pipeline stage, prepending a match stage
239+
// with discriminator information will not work
240+
241+
return $pipeline;
236242
} else {
237243
$matchExpression = $this->applyFilters([]);
238244
if ($matchExpression !== []) {

tests/Doctrine/ODM/MongoDB/Tests/Aggregation/BuilderTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
use Documents\BlogTagAggregation;
1414
use Documents\CmsComment;
1515
use Documents\GuestServer;
16+
use Documents\Project;
1617
use Documents\Tag;
1718
use MongoDB\BSON\UTCDateTime;
19+
use function array_keys;
1820

1921
class BuilderTest extends BaseTest
2022
{
@@ -343,6 +345,15 @@ public function testBuilderWithOutStageReturnsNoData()
343345
$this->assertCount(0, $result);
344346
}
345347

348+
public function testBuilderWithIndexStatsStageDoesNotApplyFilters()
349+
{
350+
$builder = $this->dm
351+
->createAggregationBuilder(Project::class)
352+
->indexStats();
353+
354+
$this->assertSame('$indexStats', array_keys($builder->getPipeline()[0])[0]);
355+
}
356+
346357
private function insertTestData()
347358
{
348359
$baseballTag = new Tag('baseball');

0 commit comments

Comments
 (0)