Skip to content

Commit da156dd

Browse files
committed
Merge branch '3.2' into 3.3
* 3.2: [#7907] add some use statements Updating Doctrine syntax for getRepository method Reworded the tip about property_info and Symfony framework remove useless space Add information for enable property_info service Updating doctrine class use Fixed the parse() method in the ExpressionLanguage AST examples [#7909] fix some typos Explained the locateResource() method of HttpKernel Reworded the note about dump() not being available in prod Symfony Installer Instructions for Windows Typo Fixing a typo in the Final Thoughts section Stop recommending the use of "doctrine:generate:entities" Use "null" so the lock is named automatically Added a help note about translating routes Use a safer code sample for Twig best practices Use the Twig namespaced syntax for all templates Updated the screenshot of deprecation messages Update lockable_trait.rst
2 parents eee16a4 + e0b8106 commit da156dd

34 files changed

+193
-188
lines changed
14.2 KB
Loading

best_practices/controllers.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ for the homepage of our app:
9595
9696
namespace AppBundle\Controller;
9797
98+
use AppBundle\Entity\Post;
9899
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
99100
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
100101
@@ -106,7 +107,7 @@ for the homepage of our app:
106107
public function indexAction()
107108
{
108109
$posts = $this->getDoctrine()
109-
->getRepository('AppBundle:Post')
110+
->getRepository(Post::class)
110111
->findLatest();
111112
112113
return $this->render('default/index.html.twig', array(
@@ -186,7 +187,7 @@ manually. In our application, we have this situation in ``CommentController``:
186187
public function newAction(Request $request, $postSlug)
187188
{
188189
$post = $this->getDoctrine()
189-
->getRepository('AppBundle:Post')
190+
->getRepository(Post::class)
190191
->findOneBy(array('slug' => $postSlug));
191192
192193
if (!$post) {

best_practices/security.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ more advanced use-case, you can always do the same security check in PHP:
227227
public function editAction($id)
228228
{
229229
$post = $this->getDoctrine()
230-
->getRepository('AppBundle:Post')
230+
->getRepository(Post::class)
231231
->find($id);
232232
233233
if (!$post) {

best_practices/templates.rst

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,20 @@ Template Locations
3030
Store all your application's templates in ``app/Resources/views/`` directory.
3131

3232
Traditionally, Symfony developers stored the application templates in the
33-
``Resources/views/`` directory of each bundle. Then they used the logical name
34-
to refer to them (e.g. ``AcmeDemoBundle:Default:index.html.twig``).
33+
``Resources/views/`` directory of each bundle. Then they used the Twig namespaced
34+
path to refer to them (e.g. ``@AcmeDemo/Default/index.html.twig``).
3535

3636
But for the templates used in your application, it's much more convenient
3737
to store them in the ``app/Resources/views/`` directory. For starters, this
3838
drastically simplifies their logical names:
3939

40-
================================================= ==================================
41-
Templates Stored inside Bundles Templates Stored in ``app/``
42-
================================================= ==================================
43-
``AcmeDemoBundle:Default:index.html.twig`` ``default/index.html.twig``
44-
``::layout.html.twig`` ``layout.html.twig``
45-
``AcmeDemoBundle::index.html.twig`` ``index.html.twig``
46-
``AcmeDemoBundle:Default:subdir/index.html.twig`` ``default/subdir/index.html.twig``
47-
``AcmeDemoBundle:Default/subdir:index.html.twig`` ``default/subdir/index.html.twig``
48-
================================================= ==================================
40+
============================================ ==================================
41+
Templates Stored inside Bundles Templates Stored in ``app/``
42+
============================================ ==================================
43+
``@AcmeDemo/index.html.twig`` ``index.html.twig``
44+
``@AcmeDemo/Default/index.html.twig`` ``default/index.html.twig``
45+
``@AcmeDemo/Default/subdir/index.html.twig`` ``default/subdir/index.html.twig``
46+
============================================ ==================================
4947

5048
Another advantage is that centralizing your templates simplifies the work
5149
of your designers. They don't need to look for templates in lots of directories
@@ -121,7 +119,7 @@ class in the constructor of the Twig extension:
121119
new \Twig_SimpleFilter(
122120
'md2html',
123121
array($this, 'markdownToHtml'),
124-
array('is_safe' => array('html'))
122+
array('is_safe' => array('html'), 'pre_escape' => 'html')
125123
),
126124
);
127125
}

bundles/best_practices.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,21 @@ The ``composer.json`` file should include at least the following metadata:
429429
In order to make it easier for developers to find your bundle, register it on
430430
`Packagist`_, the official repository for Composer packages.
431431

432+
Resources
433+
---------
434+
435+
If the bundle references any resources (config files, translation files, etc.),
436+
don't use physical paths (e.g. ``__DIR__/config/services.xml``) but logical
437+
paths (e.g. ``@AppBundle/Resources/config/services.xml``).
438+
439+
The logical paths are required because of the bundle overriding mechanism that
440+
lets you override any resource/file of any bundle. See :ref:`http-kernel-resource-locator`
441+
for more details about transforming physical paths into logical paths.
442+
443+
Beware that templates use a simplified version of the logical path shown above.
444+
For example, an ``index.html.twig`` template located in the ``Resources/views/Default/``
445+
directory of the AppBundle, is referenced as ``@App/Default/index.html.twig``.
446+
432447
Learn more
433448
----------
434449

bundles/override.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ How to Override any Part of a Bundle
77
This document is a quick reference for how to override different parts of
88
third-party bundles.
99

10+
.. tip::
11+
12+
The bundle overriding mechanism means that you cannot use physical paths to
13+
refer to bundle's resources (e.g. ``__DIR__/config/services.xml``). Always
14+
use logical paths in your bundles (e.g. ``@AppBundle/Resources/config/services.xml``)
15+
and call the :ref:`locateResource() method <http-kernel-resource-locator>`
16+
to turn them into physical paths when needed.
17+
1018
Templates
1119
---------
1220

components/expression_language/ast.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ method after parsing any expression to get its AST::
2121
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
2222

2323
$ast = (new ExpressionLanguage())
24-
->parse('1 + 2')
24+
->parse('1 + 2', array())
2525
->getNodes()
2626
;
2727

@@ -41,7 +41,7 @@ method to turn the AST into an array::
4141
// ...
4242

4343
$astAsArray = (new ExpressionLanguage())
44-
->parse('1 + 2')
44+
->parse('1 + 2', array())
4545
->getNodes()
4646
->toArray()
4747
;

components/form.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ is created from the form factory.
418418
->add('dueDate', DateType::class)
419419
->getForm();
420420
421-
return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
421+
return $this->render('@AcmeTask/Default/new.html.twig', array(
422422
'form' => $form->createView(),
423423
));
424424
}

components/http_kernel.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,32 @@ look like this::
742742
// ...
743743
}
744744

745+
.. _http-kernel-resource-locator:
746+
747+
Locating Resources
748+
------------------
749+
750+
The HttpKernel component is responsible of the bundle mechanism used in Symfony
751+
applications. The key feature of the bundles is that they allow to override any
752+
resource used by the application (config files, templates, controllers,
753+
translation files, etc.)
754+
755+
This overriding mechanism works because resources are referenced not by their
756+
physical path but by their logical path. For example, the ``services.xml`` file
757+
stored in the ``Resources/config/`` directory of a bundle called AppBundle is
758+
referenced as ``@AppBundle/Resources/config/services.xml``. This logical path
759+
will work when the application overrides that file and even if you change the
760+
directory of AppBundle.
761+
762+
The HttpKernel component provides a method called :method:`Symfony\\Component\\HttpKernel\\Kernel::locateResource`
763+
which can be used to transform logical paths into physical paths::
764+
765+
use Symfony\Component\HttpKernel\HttpKernel;
766+
767+
// ...
768+
$kernel = new HttpKernel($dispatcher, $resolver);
769+
$path = $kernel->locateResource('@AppBundle/Resources/config/services.xml');
770+
745771
Learn more
746772
----------
747773

components/property_info.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,17 @@ Using PHP reflection, the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\R
348348
provides list, type and access information from setter and accessor methods.
349349
It can also provide return and scalar types for PHP 7+.
350350

351-
This service is automatically registered with the ``property_info`` service in
352-
the Symfony Framework.
351+
.. note::
352+
353+
When using the Symfony framework, this service is automatically registered
354+
when the ``property_info`` feature is enabled:
355+
356+
.. code-block:: yaml
357+
358+
# app/config/config.yml
359+
framework:
360+
property_info:
361+
enabled: true
353362
354363
.. code-block:: php
355364

components/security/authorization.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ on a "remember-me" cookie, or even authenticated anonymously?
110110
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
111111
112112
$anonymousClass = AnonymousToken::class;
113-
$rememberMeClass = RememberMeToken::Class;
113+
$rememberMeClass = RememberMeToken::class;
114114
115115
$trustResolver = new AuthenticationTrustResolver($anonymousClass, $rememberMeClass);
116116

console/lockable_trait.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ that adds two convenient methods to lock and release commands::
3030
}
3131

3232
// If you prefer to wait until the lock is released, use this:
33-
// $this->lock(true);
33+
// $this->lock(null, true);
3434

3535
// ...
3636

doctrine.rst

Lines changed: 16 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -445,56 +445,8 @@ Even though Doctrine now knows how to persist a ``Product`` object to the
445445
database, the class itself isn't really useful yet. Since ``Product`` is just
446446
a regular PHP class with ``private`` properties, you need to create ``public``
447447
getter and setter methods (e.g. ``getName()``, ``setName($name)``) in order
448-
to access its properties in the rest of your application's code. Fortunately,
449-
the following command can generate these boilerplate methods automatically:
450-
451-
.. code-block:: terminal
452-
453-
$ php bin/console doctrine:generate:entities AppBundle/Entity/Product
454-
455-
This command makes sure that all the getters and setters are generated
456-
for the ``Product`` class. This is a safe command - you can run it over and
457-
over again: it only generates getters and setters that don't exist (i.e. it
458-
doesn't replace your existing methods).
459-
460-
.. caution::
461-
462-
Keep in mind that Doctrine's entity generator produces simple getters/setters.
463-
You should review the generated methods and add any logic, if necessary,
464-
to suit the needs of your application.
465-
466-
.. sidebar:: More about ``doctrine:generate:entities``
467-
468-
With the ``doctrine:generate:entities`` command you can:
469-
470-
* generate getter and setter methods in entity classes;
471-
472-
* generate repository classes on behalf of entities configured with the
473-
``@ORM\Entity(repositoryClass="...")`` annotation;
474-
475-
* generate the appropriate constructor for 1:n and n:m relations.
476-
477-
The ``doctrine:generate:entities`` command saves a backup of the original
478-
``Product.php`` named ``Product.php~``. In some cases, the presence of
479-
this file can cause a "Cannot redeclare class" error. It can be safely
480-
removed. You can also use the ``--no-backup`` option to prevent generating
481-
these backup files.
482-
483-
Note that you don't *need* to use this command. You could also write the
484-
necessary getters and setters by hand. This option simply exists to save
485-
you time, since creating these methods is often a common task during
486-
development.
487-
488-
You can also generate all known entities (i.e. any PHP class with Doctrine
489-
mapping information) of a bundle or an entire namespace:
490-
491-
.. code-block:: terminal
492-
493-
# generates all entities in the AppBundle
494-
$ php bin/console doctrine:generate:entities AppBundle
495-
496-
# generates all entities of bundles in the Acme namespace
497-
$ php bin/console doctrine:generate:entities Acme
448+
to access its properties in the rest of your application's code. Add these
449+
methods manually or with your own IDE.
498450

499451
.. _doctrine-creating-the-database-tables-schema:
500452

@@ -637,7 +589,7 @@ on its ``id`` value::
637589
public function showAction($productId)
638590
{
639591
$product = $this->getDoctrine()
640-
->getRepository('AppBundle:Product')
592+
->getRepository(Product::class)
641593
->find($productId);
642594

643595
if (!$product) {
@@ -660,18 +612,19 @@ as its "repository". You can think of a repository as a PHP class whose only
660612
job is to help you fetch entities of a certain class. You can access the
661613
repository object for an entity class via::
662614

663-
$repository = $em->getRepository('AppBundle:Product');
615+
$repository = $this->getDoctrine()
616+
->getRepository(Product::class);
664617

665618
.. note::
666619

667-
The ``AppBundle:Product`` string is a shortcut you can use anywhere
620+
You can also use ``AppBundle:Product`` syntax. This string is a shortcut you can use anywhere
668621
in Doctrine instead of the full class name of the entity (i.e. ``AppBundle\Entity\Product``).
669622
As long as your entity lives under the ``Entity`` namespace of your bundle,
670623
this will work.
671624

672625
Once you have a repository object, you can access all sorts of helpful methods::
673626

674-
$repository = $em->getRepository('AppBundle:Product');
627+
$repository = $this->getDoctrine()->getRepository(Product::class);
675628

676629
// query for a single product by its primary key (usually "id")
677630
$product = $repository->find($productId);
@@ -694,7 +647,7 @@ Once you have a repository object, you can access all sorts of helpful methods::
694647
You can also take advantage of the useful ``findBy()`` and ``findOneBy()`` methods
695648
to easily fetch objects based on multiple conditions::
696649

697-
$repository = $em->getRepository('AppBundle:Product');
650+
$repository = $this->getDoctrine()->getRepository(Product::class);
698651

699652
// query for a single product matching the given name and price
700653
$product = $repository->findOneBy(
@@ -727,11 +680,13 @@ Updating an Object
727680
Once you've fetched an object from Doctrine, updating it is easy. Suppose
728681
you have a route that maps a product id to an update action in a controller::
729682

683+
use AppBundle\Entity\Post;
684+
// ...
685+
730686
public function updateAction($productId)
731687
{
732-
$product = $this->getDoctrine()
733-
->getRepository('AppBundle:Product')
734-
->find($productId);
688+
$em = $this->getDoctrine()->getManager();
689+
$product = $em->getRepository(Product::class)->find($productId);
735690

736691
if (!$product) {
737692
throw $this->createNotFoundException(
@@ -777,7 +732,7 @@ Querying for Objects
777732
You've already seen how the repository object allows you to run basic queries
778733
without any work::
779734

780-
$repository = $em->getRepository('AppBundle:Product');
735+
$repository = $this->getDoctrine()->getRepository(Product::class);
781736

782737
$product = $repository->find($productId);
783738
$product = $repository->findOneByName('Keyboard');
@@ -836,7 +791,8 @@ Instead of writing a DQL string, you can use a helpful object called the
836791
depends on dynamic conditions, as your code soon becomes hard to read with
837792
DQL as you start to concatenate strings::
838793

839-
$repository = $em->getRepository('AppBundle:Product');
794+
$repository = $this->getDoctrine()
795+
->getRepository(Product::class);
840796

841797
// createQueryBuilder() automatically selects FROM AppBundle:Product
842798
// and aliases it to "p"

0 commit comments

Comments
 (0)