Skip to content

Commit 2df4d5e

Browse files
committed
Merge branch 'master' into security
Conflicts: book/security/authorization.rst cookbook/map.rst.inc
2 parents eca314f + 2c100cc commit 2df4d5e

File tree

13 files changed

+310
-23
lines changed

13 files changed

+310
-23
lines changed

book/doctrine/orm.rst

Lines changed: 169 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ any PHP class:
4747

4848
.. code-block:: php
4949
50-
// Acme/HelloBundle/Entity/User.php
50+
// src/Acme/HelloBundle/Entity/User.php
5151
namespace Acme\HelloBundle\Entity;
5252
5353
class User
@@ -85,7 +85,7 @@ write mapping information with annotations, XML, or YAML:
8585

8686
.. code-block:: php-annotations
8787
88-
// Acme/HelloBundle/Entity/User.php
88+
// src/Acme/HelloBundle/Entity/User.php
8989
namespace Acme\HelloBundle\Entity;
9090
9191
/**
@@ -108,7 +108,7 @@ write mapping information with annotations, XML, or YAML:
108108
109109
.. code-block:: yaml
110110
111-
# Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.yml
111+
# src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.yml
112112
Acme\HelloBundle\Entity\User:
113113
type: entity
114114
table: user
@@ -124,7 +124,7 @@ write mapping information with annotations, XML, or YAML:
124124
125125
.. code-block:: xml
126126
127-
<!-- Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.xml -->
127+
<!-- src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.xml -->
128128
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
129129
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
130130
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
@@ -167,7 +167,7 @@ Eventually, use your entity and manage its persistent state with Doctrine:
167167

168168
.. code-block:: php
169169
170-
// Acme/HelloBundle/Controller/UserController.php
170+
// src/Acme/HelloBundle/Controller/UserController.php
171171
namespace Acme\HelloBundle\Controller;
172172
173173
use Acme\HelloBundle\Entity\User;
@@ -215,6 +215,7 @@ losing your existing data. So first let's just add a new property to our
215215

216216
.. code-block:: php
217217
218+
// src/Acme/HelloBundle/Entity/User.php
218219
namespace Acme\HelloBundle\Entity;
219220
220221
/** @orm:Entity */
@@ -234,6 +235,166 @@ you just need to run the following command:
234235
Now your database will be updated and the new column added to the database
235236
table.
236237

238+
.. index::
239+
single: Doctrine ORM; Queries;
240+
241+
Queries
242+
~~~~~~~
243+
244+
As you have already seen, working with single objects is straightforward and
245+
easy with the entity manager. But how can you query for a set of objects?
246+
As every with any Doctrine operation, this is done via the entity manager.
247+
Change the delete action used in the previous example to use a query instead
248+
of loading the object and then deleting it afterwards:
249+
250+
.. code-block:: php
251+
252+
public function deleteAction($id)
253+
{
254+
$query = $this->get('doctrine')->getEntityManager()
255+
->createQuery('DELETE FROM Acme\HelloBundle\Entity\User u
256+
WHERE u.id = :id');
257+
$query->setParameters(array(
258+
'id' => $id
259+
));
260+
261+
$query->execute();
262+
263+
// ...
264+
}
265+
266+
Of course you can use SELECT and UPDATE queries too. Doctrine brings its own
267+
Query Language called DQL (Doctrine Query Language). The DQL has some
268+
similarities with SQL but is a query language with its own syntax.
269+
270+
.. tip::
271+
272+
You can read more about the Doctrine Query Language on the official
273+
`Doctrine Query Language documentation`_ website. The advantage of DQL
274+
is that it is database-agnostic - the same queries can be written in
275+
DQL and work with any supported database engine.
276+
277+
.. note::
278+
279+
There is a drawback when using a DQL DELETE or UPDATE statement. Specifically,
280+
since this operation is made directly to the database, Doctrine isn't
281+
aware of the option internally. For example, if you query for an object
282+
and then make an update to that object directly in the database via an
283+
UPDATE statement, the object itself won't reflect that update. So, be
284+
careful when using these statements - your objects can become out-of-sync
285+
with your database inside a single request.
286+
287+
.. index::
288+
single: Doctrine ORM; Repository;
289+
290+
Repositories
291+
~~~~~~~~~~~~
292+
293+
It is bad practice to make queries in the Symfony controllers. Such queries
294+
should be done in the model layer of your bundle so that they can be tested
295+
and reused through your application. Fortunately, Doctrine allows you to
296+
use special classes called Repositories to encapsulate queries.
297+
298+
Doctrine provides a default implementation for your repository classes, so you
299+
can use their common methods to query your entities data. One of them is the
300+
``findAll`` function.
301+
302+
.. code-block:: php
303+
304+
$em = $this->get('doctrine')->getEntityManager();
305+
$users = $em->getRepository('AcmeHelloBundle:User')->findAll();
306+
307+
If you want to create your own function to query or manipulate your data, you
308+
need to create a custom repository class for an entity. To do so, you need to
309+
add the name of the repository class to your mapping definition.
310+
311+
.. configuration-block::
312+
313+
.. code-block:: php-annotations
314+
315+
// src/Acme/HelloBundle/Entity/User.php
316+
namespace Acme\HelloBundle\Entity;
317+
318+
/**
319+
* @orm:Entity(repositoryClass="Acme\HelloBundle\Repository\UserRepository")
320+
*/
321+
class User
322+
{
323+
//...
324+
}
325+
326+
.. code-block:: yaml
327+
328+
# src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.yml
329+
Acme\HelloBundle\Entity\User:
330+
type: entity
331+
table: user
332+
repositoryClass: Acme\HelloBundle\Repository\UserRepository
333+
#...
334+
335+
.. code-block:: xml
336+
337+
<!-- src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.xml -->
338+
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
339+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
340+
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
341+
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
342+
343+
<entity name="Acme\HelloBundle\Entity\User" table="user"
344+
repository-class="Acme\HelloBundle\Repository\UserRepository">
345+
<id name="id" type="integer" column="id">
346+
<generator strategy="AUTO"/>
347+
</id>
348+
<field name="name" column="name" type="string" length="255" />
349+
</entity>
350+
351+
</doctrine-mapping>
352+
353+
The repository class is created for you if you run the following command
354+
to generate your entities.
355+
356+
$ php app/console doctrine:generate:entities
357+
358+
If you have already generated your entity class before adding the ``repositoryClass``
359+
mapping, you have to create the class on your own. Fortunately, it's pretty
360+
easy. Simply create the class in the ``Repository`` directory of your bundle
361+
and be sure it extends ``Doctrine\ORM\EntityRepository``. Once you've created
362+
the class, you can add any method to query your entities.
363+
364+
The following code shows a sample repository class.
365+
366+
.. code-block:: php
367+
368+
// src/Acme/HelloBundle/Repository/UserRepository.php
369+
namespace Acme\HelloBundle\Repository;
370+
371+
use Doctrine\ORM\EntityRepository;
372+
373+
class UserRepository extends EntityRepository
374+
{
375+
public function findAllOrderedByName()
376+
{
377+
return $this->getEntityManager()
378+
->createQuery('SELECT u FROM Acme\HelloBundle\Entity\User u
379+
ORDER BY u.name ASC')
380+
->getResult();
381+
}
382+
}
383+
384+
.. tip::
385+
386+
The entity manager can be accessed via ``$this->getEntityManager()`` in the
387+
repositories functions.
388+
389+
The usage of this new method is the same as with the default finder functions.
390+
391+
.. code-block:: php
392+
393+
$em = $this->get('doctrine')->getEntityManager();
394+
$users = $em->getRepository('AcmeHelloBundle:User')
395+
->findAllOrderedByName();
396+
397+
237398
.. index::
238399
single: Configuration; Doctrine ORM
239400
single: Doctrine; ORM Configuration
@@ -242,7 +403,7 @@ Configuration
242403
-------------
243404

244405
In the overview we already described the only necessary configuration option
245-
to get the Doctrine ORM running with Symfony 2. All the other configuration
406+
to get the Doctrine ORM running with Symfony2. All the other configuration
246407
options are used with reasonable default values.
247408

248409
This following configuration example shows all the configuration defaults that
@@ -356,7 +517,7 @@ The following configuration shows a bunch of mapping examples:
356517
Multiple Entity Managers
357518
~~~~~~~~~~~~~~~~~~~~~~~~
358519

359-
You can use multiple ``EntityManager``s in a Symfony2 application. This is
520+
You can use multiple entity managers in a Symfony2 application. This is
360521
necessary if you are using different databases or even vendors with entirely
361522
different sets of entities.
362523

@@ -617,3 +778,4 @@ get the choices. If not set all entities will be used.
617778

618779
.. _documentation: http://www.doctrine-project.org/docs/orm/2.0/en
619780
.. _Doctrine: http://www.doctrine-project.org
781+
.. _Doctrine Query Language documentation: http://www.doctrine-project.org/docs/orm/2.0/en/reference/dql-doctrine-query-language.html

book/forms.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,8 @@ the common form fields and data types you'll encounter:
368368
.. include:: /reference/forms/types/map.rst.inc
369369

370370
Of course, you can also create your own custom field types. This topic is
371-
covered in the ":doc:`/cookbook/forms/create_custom_fields`" article of the
372-
cookbook.
371+
covered in the ":doc:`/cookbook/forms/create_custom_field_type`" article
372+
of the cookbook.
373373

374374
.. index::
375375
single: Forms; Field type options
@@ -1149,7 +1149,6 @@ Learn more from the Cookbook
11491149

11501150
* :doc:`Handling File Uploads </cookbook/forms/file_uploads>`
11511151
* :doc:`Creating Custom Field Types </cookbook/forms/custom_field_types>`
1152-
* :doc:`Dynamically adding Fields to a Form </cookbook/forms/dynamically_adding_fields>`
11531152
* :doc:`/cookbook/form/twig_form_customization`
11541153

11551154
.. _`Symfony2 Form Component`: https://github.com/symfony/Form

book/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ Book
1717
security
1818
http_cache
1919
translation
20-
console
2120
bundles
2221
service_container
2322
internals/index

book/internals/overview.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ variables:
4343
:class:`Symfony\\Component\\HttpFoundation\\SessionStorage\\SessionStorageInterface`
4444
interface abstract session management ``session_*()`` functions.
4545

46-
.. seealso::
47-
48-
Read more about the :doc:`HttpFoundation <http_foundation>` component.
49-
5046
``HttpKernel`` Component
5147
------------------------
5248

book/routing.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ routing system can be:
710710
711711
article_show:
712712
pattern: /articles/{culture}/{year}/{title}.{_format}
713-
defaults { _controller: AcmeDemoBundle:Article:show, _format: html }
713+
defaults: { _controller: AcmeDemoBundle:Article:show, _format: html }
714714
requirements:
715715
culture: en|fr
716716
_format: html|rss

cookbook/cache/varnish.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,5 @@ that will invalidate the cache for a given resource:
8888

8989
You must protect the ``PURGE`` HTTP method somehow to avoid random people
9090
purging your cached data.
91+
92+
.. _`Edge Architecture`: http://www.w3.org/TR/edge-arch
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
.. index::
2+
single: Session; Database Storage
3+
4+
How to use PdoSessionStorage to store Sessions in the Database
5+
==============================================================
6+
7+
The default session storage of Symfony2 writes the session information to
8+
file(s). Most medium to large websites use a database to store the session
9+
values instead of files, because databases are easier to use and scale in
10+
a multi-webserver environment.
11+
12+
Symfony2 has a built-in solution for database session storage called
13+
:class:`Symfony\\\Component\\HttpFoundation\\SessionStorage\\PdoSessionStorage`.
14+
To use it, you just need to change some parameters in ``config.yml`` (or the
15+
configuration format of your choice).
16+
17+
.. configuration-block::
18+
19+
.. code-block:: yaml
20+
21+
# app/config/config.yml
22+
session:
23+
# ...
24+
storage_id: session.storage.pdo
25+
26+
parameters:
27+
pdo.db_options:
28+
db_table: session
29+
db_id_col: session_id
30+
db_data_col: session_value
31+
db_time_col: session_time
32+
33+
services:
34+
session.storage.pdo:
35+
class: Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage
36+
arguments: [@pdo, %pdo.db_options%]
37+
38+
pdo:
39+
class: PDO
40+
arguments:
41+
dsn: "mysql:dbname=mydatabase"
42+
user: myuser
43+
password: mypassword
44+
45+
46+
* ``db_table``: The name of the session table in your database
47+
* ``db_id_col``: The name of the id column in your session table (VARCHAR(255) or larger)
48+
* ``db_data_col``: The name of the value column in your session table (TEXT or CLOB)
49+
* ``db_time_col``: The name of the time column in your session table (INTEGER)
50+
51+
Sharing your Database Connection Information
52+
--------------------------------------------
53+
54+
With the given configuration, the database connection settings are defined
55+
for the session storage connection only. This is OK when you use a separate
56+
database for the session data.
57+
58+
But if you'd like to store the session data in the same database as the rest
59+
of your project's data, you can use the connection settings from the parameter.ini
60+
by referencing the database-related parameters defined there:
61+
62+
.. configuration-block::
63+
64+
.. code-block:: yaml
65+
66+
pdo:
67+
class: PDO
68+
arguments:
69+
dsn: "mysql:dbname=%database_name%"
70+
user: %database_user%
71+
password: %database_password%
72+
73+
Example MySQL Statement
74+
-----------------------
75+
76+
The SQL-Statement for creating the needed Database-Table could look like
77+
the following (MySQL):
78+
79+
.. code-block:: sql
80+
81+
CREATE TABLE `session` (
82+
`session_id` varchar(255) NOT NULL,
83+
`session_value` text NOT NULL,
84+
`session_time` int(11) NOT NULL,
85+
PRIMARY KEY (`session_id`),
86+
UNIQUE KEY `session_id_idx` (`session_id`)
87+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

0 commit comments

Comments
 (0)