Skip to content

Commit 84ddb53

Browse files
committed
Merge branch '3.3' into 3.4
* 3.3: (36 commits) [symfony#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 [symfony#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 Updated the screenshot of exceptions in dev environment 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 incorrect session short description Use of Setters and Getters Small mistype edits Changed text how to get button label ...
2 parents 03f46c1 + da156dd commit 84ddb53

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+347
-202
lines changed
Loading
14.2 KB
Loading

best_practices/controllers.rst

+3-2
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 Symfony\Component\Routing\Annotation\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

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

best_practices/templates.rst

+10-12
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

+15
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

+8
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/dom_crawler.rst

+11-2
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,19 @@ given text. This method is especially useful because you can use it to return
396396
a :class:`Symfony\\Component\\DomCrawler\\Form` object that represents the
397397
form that the button lives in::
398398

399-
$form = $crawler->selectButton('validate')->form();
399+
// button example: <button id="my-super-button" type="submit">My super button</button>
400+
401+
// you can get button by its label
402+
$form = $crawler->selectButton('My super button')->form();
403+
404+
// or by button id (#my-super-button) if the button doesn't have a label
405+
$form = $crawler->selectButton('my-super-button')->form();
406+
407+
// or you can filter the whole form, for example a form has a class attribute: <form class="form-vertical" method="POST">
408+
$crawler->filter('.form-vertical')->form();
400409

401410
// or "fill" the form fields with data
402-
$form = $crawler->selectButton('validate')->form(array(
411+
$form = $crawler->selectButton('my-super-button')->form(array(
403412
'name' => 'Ryan',
404413
));
405414

components/expression_language/ast.rst

+2-2
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

+1-1
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

+26
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

+11-2
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

+1-1
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

+1-1
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

controller.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ Managing the Session
453453
--------------------
454454

455455
Symfony provides a nice session object that you can use to store information
456-
about the user between requests. By default, Symfony stores the attributes in a
457-
cookie by using native PHP sessions.
456+
about the user between requests. By default, Symfony stores the token in a
457+
cookie and writes the attributes to a file by using native PHP sessions.
458458

459459
.. versionadded:: 3.3
460460
The ability to request a ``Session`` instance in controllers was introduced

controller/upload_file.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ logic to a separate service::
239239
{
240240
$fileName = md5(uniqid()).'.'.$file->guessExtension();
241241

242-
$file->move($this->targetDir, $fileName);
242+
$file->move($this->getTargetDir(), $fileName);
243243

244244
return $fileName;
245245
}

doctrine.rst

+16-60
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)