Skip to content

Commit 796b466

Browse files
committed
Merge branch '3.0' into 3.1
* 3.0: [#6566] fix indentation Update options_resolver.rst Fixing a typo - thanks to @tacman Fix build [#6564] Revert doc removal in 2.8 Replace property_accessor by property_access Remove extra spaces in Nginx template [#6539] Some small improvements Documented the "autoescape" TwigBundle config option [PhpUnitBridge] Add versionadded directive to clock mocking section [PhpUnitBridge] Remove section about clock mocking fixing special shortcut syntax Add missed link to the external PSR-4 specification. Editing the Doctrine section to improve accuracy and readability Typo fix in the Serializer deserialization example drop AppBundle examples in components section merge choice_translation_domain files remove 2.x versionadded directives Make ClockMock Tests\\ namespace matching less specific Improved "optional argument" documentation"
2 parents a5547b8 + f8d5f44 commit 796b466

23 files changed

+307
-239
lines changed

book/controller.rst

+2-6
Original file line numberDiff line numberDiff line change
@@ -431,10 +431,6 @@ If you want to redirect the user to another page, use the ``redirectToRoute()``
431431
// return $this->redirect($this->generateUrl('homepage'));
432432
}
433433

434-
.. versionadded:: 2.6
435-
The ``redirectToRoute()`` method was introduced in Symfony 2.6. Previously (and still now), you
436-
could use ``redirect()`` and ``generateUrl()`` together for this (see the example above).
437-
438434
By default, the ``redirectToRoute()`` method performs a 302 (temporary) redirect. To
439435
perform a 301 (permanent) redirect, modify the third argument::
440436

@@ -500,8 +496,8 @@ The Symfony templating engine is explained in great detail in the
500496
.. sidebar:: Templating Naming Pattern
501497

502498
You can also put templates in the ``Resources/views`` directory of a bundle and
503-
reference them with a special shortcut syntax like ``@AppBundle/Hello/index.html.twig``
504-
or ``@AppBundle/layout.html.twig``. These would live in at ``Resources/views/Hello/index.html.twig``
499+
reference them with a special shortcut syntax like ``@App/Hello/index.html.twig``
500+
or ``@App/layout.html.twig``. These would live in at ``Resources/views/Hello/index.html.twig``
505501
and ``Resources/views/layout.html.twig`` inside the bundle respectively.
506502

507503
.. index::

book/doctrine.rst

+140-118
Original file line numberDiff line numberDiff line change
@@ -766,31 +766,31 @@ Doctrine Query Language (DQL). DQL is similar to SQL except that you should
766766
imagine that you're querying for one or more objects of an entity class (e.g. ``Product``)
767767
instead of querying for rows on a table (e.g. ``product``).
768768

769-
When querying in Doctrine, you have two options: writing pure Doctrine queries
769+
When querying in Doctrine, you have two main options: writing pure DQL queries
770770
or using Doctrine's Query Builder.
771771

772772
Querying for Objects with DQL
773773
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
774774

775-
Imagine that you want to query for products, but only return products that
776-
cost more than ``19.99``, ordered from cheapest to most expensive. You can use
777-
Doctrine's native SQL-like language called DQL to make a query for this::
775+
Imagine that you want to query for products that cost more than ``19.99``,
776+
ordered from least to most expensive. You can use DQL, Doctrine's native
777+
SQL-like language, to construct a query for this scenario::
778778

779779
$em = $this->getDoctrine()->getManager();
780780
$query = $em->createQuery(
781781
'SELECT p
782782
FROM AppBundle:Product p
783783
WHERE p.price > :price
784784
ORDER BY p.price ASC'
785-
)->setParameter('price', '19.99');
785+
)->setParameter('price', 19.99);
786786

787787
$products = $query->getResult();
788788

789789
If you're comfortable with SQL, then DQL should feel very natural. The biggest
790-
difference is that you need to think in terms of "objects" instead of rows
791-
in a database. For this reason, you select *from* the ``AppBundle:Product``
792-
*object* (an optional shortcut for ``AppBundle\Entity\Product``) and then
793-
alias it as ``p``.
790+
difference is that you need to think in terms of selecting PHP objects,
791+
instead of rows in a database. For this reason, you select *from* the
792+
``AppBundle:Product`` *entity* (an optional shortcut for the
793+
``AppBundle\Entity\Product`` class) and then alias it as ``p``.
794794

795795
.. tip::
796796

@@ -844,11 +844,11 @@ Custom Repository Classes
844844
~~~~~~~~~~~~~~~~~~~~~~~~~
845845

846846
In the previous sections, you began constructing and using more complex queries
847-
from inside a controller. In order to isolate, test and reuse these queries,
848-
it's a good practice to create a custom repository class for your entity and
849-
add methods with your query logic there.
847+
from inside a controller. In order to isolate, reuse and test these queries,
848+
it's a good practice to create a custom repository class for your entity.
849+
Methods containing your query logic can then be stored in this class.
850850

851-
To do this, add the name of the repository class to your mapping definition:
851+
To do this, add the repository class name to your entity's mapping definition:
852852

853853
.. configuration-block::
854854

@@ -892,16 +892,22 @@ To do this, add the name of the repository class to your mapping definition:
892892
</entity>
893893
</doctrine-mapping>
894894
895-
Doctrine can generate the repository class for you by running the same command
896-
used earlier to generate the missing getter and setter methods:
895+
Doctrine can generate empty repository classes for all the entities in your
896+
application via the same command used earlier to generate the missing getter
897+
and setter methods:
897898

898899
.. code-block:: bash
899900
900901
$ php bin/console doctrine:generate:entities AppBundle
901902
902-
Next, add a new method - ``findAllOrderedByName()`` - to the newly generated
903-
repository class. This method will query for all the ``Product`` entities,
904-
ordered alphabetically.
903+
.. tip::
904+
905+
If you opt to create the repository classes yourself, they must extend
906+
``Doctrine\ORM\EntityRepository``.
907+
908+
Next, add a new method - ``findAllOrderedByName()`` - to the newly-generated
909+
``ProductRepository`` class. This method will query for all the ``Product``
910+
entities, ordered alphabetically by name.
905911

906912
.. code-block:: php
907913
@@ -943,11 +949,13 @@ You can use this new method just like the default finder methods of the reposito
943949
Entity Relationships/Associations
944950
---------------------------------
945951

946-
Suppose that the products in your application all belong to exactly one "category".
947-
In this case, you'll need a ``Category`` object and a way to relate a ``Product``
948-
object to a ``Category`` object. Start by creating the ``Category`` entity.
949-
Since you know that you'll eventually need to persist the class through Doctrine,
950-
you can let Doctrine create the class for you.
952+
Suppose that each product in your application belongs to exactly one category.
953+
In this case, you'll need a ``Category`` class, and a way to relate a
954+
``Product`` object to a ``Category`` object.
955+
956+
Start by creating the ``Category`` entity. Since you know that you'll eventually
957+
need to persist category objects through Doctrine, you can let Doctrine create
958+
the class for you.
951959

952960
.. code-block:: bash
953961
@@ -961,8 +969,81 @@ a ``name`` field and the associated getter and setter functions.
961969
Relationship Mapping Metadata
962970
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
963971

964-
To relate the ``Category`` and ``Product`` entities, start by creating a
965-
``products`` property on the ``Category`` class:
972+
In this example, each category can be associated with *many* products, while
973+
each product can be associated with only *one* category. This relationship
974+
can be summarized as: *many* products to *one* category (or equivalently,
975+
*one* category to *many* products).
976+
977+
From the perspective of the ``Product`` entity, this is a many-to-one relationship.
978+
From the perspective of the ``Category`` entity, this is a one-to-many relationship.
979+
This is important, because the relative nature of the relationship determines
980+
which mapping metadata to use. It also determines which class *must* hold
981+
a reference to the other class.
982+
983+
To relate the ``Product`` and ``Category`` entities, simply create a ``category``
984+
property on the ``Product`` class, annotated as follows:
985+
986+
.. configuration-block::
987+
988+
.. code-block:: php-annotations
989+
990+
// src/AppBundle/Entity/Product.php
991+
992+
// ...
993+
class Product
994+
{
995+
// ...
996+
997+
/**
998+
* @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
999+
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
1000+
*/
1001+
private $category;
1002+
}
1003+
1004+
.. code-block:: yaml
1005+
1006+
# src/AppBundle/Resources/config/doctrine/Product.orm.yml
1007+
AppBundle\Entity\Product:
1008+
type: entity
1009+
# ...
1010+
manyToOne:
1011+
category:
1012+
targetEntity: Category
1013+
inversedBy: products
1014+
joinColumn:
1015+
name: category_id
1016+
referencedColumnName: id
1017+
1018+
.. code-block:: xml
1019+
1020+
<!-- src/AppBundle/Resources/config/doctrine/Product.orm.xml -->
1021+
<?xml version="1.0" encoding="UTF-8" ?>
1022+
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
1023+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1024+
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
1025+
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
1026+
1027+
<entity name="AppBundle\Entity\Product">
1028+
<!-- ... -->
1029+
<many-to-one
1030+
field="category"
1031+
target-entity="Category"
1032+
inversed-by="products"
1033+
join-column="category">
1034+
1035+
<join-column name="category_id" referenced-column-name="id" />
1036+
</many-to-one>
1037+
</entity>
1038+
</doctrine-mapping>
1039+
1040+
This many-to-one mapping is critical. It tells Doctrine to use the ``category_id``
1041+
column on the ``product`` table to relate each record in that table with
1042+
a record in the ``category`` table.
1043+
1044+
Next, since a single ``Category`` object will relate to many ``Product``
1045+
objects, a ``products`` property can be added to the ``Category`` class
1046+
to hold those associated objects.
9661047

9671048
.. configuration-block::
9681049

@@ -1024,126 +1105,67 @@ To relate the ``Category`` and ``Product`` entities, start by creating a
10241105
</entity>
10251106
</doctrine-mapping>
10261107
1027-
First, since a ``Category`` object will relate to many ``Product`` objects,
1028-
a ``products`` array property is added to hold those ``Product`` objects.
1029-
Again, this isn't done because Doctrine needs it, but instead because it
1030-
makes sense in the application for each ``Category`` to hold an array of
1031-
``Product`` objects.
1108+
While the many-to-one mapping shown earlier was mandatory, this one-to-many
1109+
mapping is optional. It is included here to help demonstrate Doctrine's range
1110+
of relationship management capabailties. Plus, in the context of this application,
1111+
it will likely be convenient for each ``Category`` object to automatically
1112+
own a collection of its related ``Product`` objects.
10321113

10331114
.. note::
10341115

1035-
The code in the ``__construct()`` method is important because Doctrine
1036-
requires the ``$products`` property to be an ``ArrayCollection`` object.
1037-
This object looks and acts almost *exactly* like an array, but has some
1038-
added flexibility. If this makes you uncomfortable, don't worry. Just
1039-
imagine that it's an ``array`` and you'll be in good shape.
1116+
The code in the constructor is important. Rather than being instantiated
1117+
as a traditional ``array``, the ``$products`` property must be of a type
1118+
that implements Doctrine's ``Collection`` interface. In this case, an
1119+
``ArrayCollection`` object is used. This object looks and acts almost
1120+
*exactly* like an array, but has some added flexibility. If this makes
1121+
you uncomfortable, don't worry. Just imagine that it's an ``array``
1122+
and you'll be in good shape.
10401123

10411124
.. tip::
10421125

1043-
The targetEntity value in the decorator used above can reference any entity
1126+
The targetEntity value in the metadata used above can reference any entity
10441127
with a valid namespace, not just entities defined in the same namespace. To
10451128
relate to an entity defined in a different class or bundle, enter a full
10461129
namespace as the targetEntity.
10471130

1048-
Next, since each ``Product`` class can relate to exactly one ``Category``
1049-
object, you'll want to add a ``$category`` property to the ``Product`` class:
1050-
1051-
.. configuration-block::
1052-
1053-
.. code-block:: php-annotations
1054-
1055-
// src/AppBundle/Entity/Product.php
1056-
1057-
// ...
1058-
class Product
1059-
{
1060-
// ...
1061-
1062-
/**
1063-
* @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
1064-
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
1065-
*/
1066-
private $category;
1067-
}
1068-
1069-
.. code-block:: yaml
1070-
1071-
# src/AppBundle/Resources/config/doctrine/Product.orm.yml
1072-
AppBundle\Entity\Product:
1073-
type: entity
1074-
# ...
1075-
manyToOne:
1076-
category:
1077-
targetEntity: Category
1078-
inversedBy: products
1079-
joinColumn:
1080-
name: category_id
1081-
referencedColumnName: id
1082-
1083-
.. code-block:: xml
1084-
1085-
<!-- src/AppBundle/Resources/config/doctrine/Product.orm.xml -->
1086-
<?xml version="1.0" encoding="UTF-8" ?>
1087-
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
1088-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1089-
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
1090-
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
1091-
1092-
<entity name="AppBundle\Entity\Product">
1093-
<!-- ... -->
1094-
<many-to-one
1095-
field="category"
1096-
target-entity="Category"
1097-
inversed-by="products"
1098-
join-column="category">
1099-
1100-
<join-column name="category_id" referenced-column-name="id" />
1101-
</many-to-one>
1102-
</entity>
1103-
</doctrine-mapping>
1104-
1105-
Finally, now that you've added a new property to both the ``Category`` and
1106-
``Product`` classes, tell Doctrine to generate the missing getter and setter
1107-
methods for you:
1131+
Now that you've added new properties to both the ``Product`` and ``Category``
1132+
classes, tell Doctrine to generate the missing getter and setter methods for you:
11081133

11091134
.. code-block:: bash
11101135
11111136
$ php bin/console doctrine:generate:entities AppBundle
11121137
1113-
Ignore the Doctrine metadata for a moment. You now have two classes - ``Category``
1114-
and ``Product`` with a natural one-to-many relationship. The ``Category``
1115-
class holds an array of ``Product`` objects and the ``Product`` object can
1116-
hold one ``Category`` object. In other words - you've built your classes
1117-
in a way that makes sense for your needs. The fact that the data needs to
1118-
be persisted to a database is always secondary.
1119-
1120-
Now, look at the metadata above the ``$category`` property on the ``Product``
1121-
class. The information here tells Doctrine that the related class is ``Category``
1122-
and that it should store the ``id`` of the category record on a ``category_id``
1123-
field that lives on the ``product`` table. In other words, the related ``Category``
1124-
object will be stored on the ``$category`` property, but behind the scenes,
1125-
Doctrine will persist this relationship by storing the category's id value
1126-
on a ``category_id`` column of the ``product`` table.
1138+
Ignore the Doctrine metadata for a moment. You now have two classes - ``Product``
1139+
and ``Category``, with a natural many-to-one relationship. The ``Product``
1140+
class holds a *single* ``Category`` object, and the ``Category`` class holds
1141+
a *collection* of ``Product`` objects. In other words, you've built your classes
1142+
in a way that makes sense for your application. The fact that the data needs
1143+
to be persisted to a database is always secondary.
1144+
1145+
Now, review the metadata above the ``Product`` entity's ``$category`` property.
1146+
It tells Doctrine that the related class is ``Category``, and that the ``id``
1147+
of the related category record should be stored in a ``category_id`` field
1148+
on the ``product`` table.
1149+
1150+
In other words, the related ``Category`` object will be stored in the
1151+
``$category`` property, but behind the scenes, Doctrine will persist this
1152+
relationship by storing the category's id in the ``category_id`` column
1153+
of the ``product`` table.
11271154

11281155
.. image:: /images/book/doctrine_image_2.png
11291156
:align: center
11301157

1131-
The metadata above the ``$products`` property of the ``Category`` object
1132-
is less important, and simply tells Doctrine to look at the ``Product.category``
1158+
The metadata above the ``Category`` entity's ``$products`` property is less
1159+
complicated. It simply tells Doctrine to look at the ``Product.category``
11331160
property to figure out how the relationship is mapped.
11341161

11351162
Before you continue, be sure to tell Doctrine to add the new ``category``
1136-
table, and ``product.category_id`` column, and new foreign key:
1163+
table, the new ``product.category_id`` column, and the new foreign key:
11371164

11381165
.. code-block:: bash
11391166
11401167
$ php bin/console doctrine:schema:update --force
11411168
1142-
.. note::
1143-
1144-
This command should only be used during development. For a more robust
1145-
method of systematically updating your production database, read about
1146-
`migrations`_.
11471169
11481170
Saving Related Entities
11491171
~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)