Skip to content

Commit 03b67ea

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 2253d5e + 078bb2d commit 03b67ea

File tree

346 files changed

+8878
-5726
lines changed

Some content is hidden

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

346 files changed

+8878
-5726
lines changed

best_practices/business-logic.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ The blog application needs a utility that can transform a post title (e.g.
5656
"Hello World") into a slug (e.g. "hello-world"). The slug will be used as
5757
part of the post URL.
5858

59-
Let's, create a new ``Slugger`` class inside ``src/AppBundle/Utils/`` and
59+
Let's create a new ``Slugger`` class inside ``src/AppBundle/Utils/`` and
6060
add the following ``slugify()`` method:
6161

6262
.. code-block:: php

best_practices/configuration.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ they have nothing to do with the application's behavior. In other words, your
4242
application doesn't care about the location of your database or the credentials
4343
to access to it, as long as the database is correctly configured.
4444

45+
.. _best-practices-canonical-parameters:
46+
4547
Canonical Parameters
4648
~~~~~~~~~~~~~~~~~~~~
4749

@@ -101,8 +103,8 @@ to control the number of posts to display on the blog homepage:
101103
parameters:
102104
homepage.num_items: 10
103105
104-
If you ask yourself when the last time was that you changed the value of
105-
*any* option like this, odds are that you *never* have. Creating a configuration
106+
If you've done something like this in the past, it's likely that you've in fact
107+
*never* actually needed to change that value. Creating a configuration
106108
option for a value that you are never going to configure just isn't necessary.
107109
Our recommendation is to define these values as constants in your application.
108110
You could, for example, define a ``NUM_ITEMS`` constant in the ``Post`` entity:
@@ -124,7 +126,7 @@ everywhere in your application. When using parameters, they are only available
124126
from places with access to the Symfony container.
125127

126128
Constants can be used for example in your Twig templates thanks to the
127-
``constant()`` function:
129+
`constant() function`_:
128130

129131
.. code-block:: html+jinja
130132

best_practices/controllers.rst

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,15 @@ Template Configuration
7676
Don't use the ``@Template()`` annotation to configure the template used by
7777
the controller.
7878

79-
The ``@Template`` annotation is useful, but also involves some magic. For
80-
that reason, we don't recommend using it.
79+
The ``@Template`` annotation is useful, but also involves some magic. We
80+
don't think its benefit is worth the magic, and so recommend against using
81+
it.
8182

8283
Most of the time, ``@Template`` is used without any parameters, which makes
8384
it more difficult to know which template is being rendered. It also makes
8485
it less obvious to beginners that a controller should always return a Response
8586
object (unless you're using a view layer).
8687

87-
Lastly, the ``@Template`` annotation uses a ``TemplateListener`` class that hooks
88-
into the ``kernel.view`` event dispatched by the framework. This listener introduces
89-
a measurable performance impact. In the sample blog application, rendering the
90-
homepage took 5 milliseconds using the ``$this->render()`` method and 26 milliseconds
91-
using the ``@Template`` annotation.
92-
9388
How the Controller Looks
9489
------------------------
9590

best_practices/creating-the-project.rst

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,15 @@ In the past, Symfony projects were created with `Composer`_, the dependency mana
88
for PHP applications. However, the current recommendation is to use the **Symfony
99
Installer**, which has to be installed before creating your first project.
1010

11-
Linux and Mac OS X Systems
12-
~~~~~~~~~~~~~~~~~~~~~~~~~~
13-
14-
Open your command console and execute the following:
15-
16-
.. code-block:: bash
17-
18-
$ curl -LsS http://symfony.com/installer > symfony.phar
19-
$ sudo mv symfony.phar /usr/local/bin/symfony
20-
$ chmod a+x /usr/local/bin/symfony
21-
22-
Now you can execute the Symfony Installer as a global system command called
23-
``symfony``.
24-
25-
Windows Systems
26-
~~~~~~~~~~~~~~~
27-
28-
Open your command console and execute the following:
29-
30-
.. code-block:: bash
31-
32-
c:\> php -r "readfile('http://symfony.com/installer');" > symfony.phar
11+
.. best-practice::
3312

34-
Then, move the downloaded ``symfony.phar`` file to your projects directory and
35-
execute it as follows:
13+
Use the Symfony Installer to create new Symfony-based projects.
3614

37-
.. code-block:: bash
15+
Read the :doc:`installation chapter </book/installation>` of the Symfony Book to
16+
learn how to install and use the Symfony Installer.
3817

39-
c:\> php symfony.phar
18+
.. _linux-and-mac-os-x-systems:
19+
.. _windows-systems:
4020

4121
Creating the Blog Application
4222
-----------------------------
@@ -114,7 +94,7 @@ ProductBundle, InvoiceBundle, etc.
11494

11595
But a bundle is *meant* to be something that can be reused as a stand-alone
11696
piece of software. If UserBundle cannot be used *"as is"* in other Symfony
117-
apps, then it shouldn't be its own bundle. Moreover InvoiceBundle depends on
97+
apps, then it shouldn't be its own bundle. Moreover, if InvoiceBundle depends on
11898
ProductBundle, then there's no advantage to having two separate bundles.
11999

120100
.. best-practice::

best_practices/forms.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,21 @@ Second, we recommend using ``$form->isSubmitted()`` in the ``if`` statement
207207
for clarity. This isn't technically needed, since ``isValid()`` first calls
208208
``isSubmitted()``. But without this, the flow doesn't read well as it *looks*
209209
like the form is *always* processed (even on the GET request).
210+
211+
Custom Form Field Types
212+
-----------------------
213+
214+
.. best-practice::
215+
216+
Add the ``app_`` prefix to your custom form field types to avoid collisions.
217+
218+
Custom form field types inherit from the ``AbstractType`` class, which defines the
219+
``getName()`` method to configure the name of that form type. These names must
220+
be unique in the application.
221+
222+
If a custom form type uses the same name as any of the Symfony's built-in form
223+
types, it will override it. The same happens when the custom form type matches
224+
any of the types defined by the third-party bundles installed in your application.
225+
226+
Add the ``app_`` prefix to your custom form field types to avoid name collisions
227+
that can lead to hard to debug errors.

best_practices/i18n.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ following ``translator`` configuration option and set your application locale:
1111
# app/config/config.yml
1212
framework:
1313
# ...
14-
translator: { fallback: "%locale%" }
14+
translator: { fallbacks: ["%locale%"] }
1515
1616
# app/config/parameters.yml
1717
parameters:
@@ -80,7 +80,7 @@ English in the application would be:
8080

8181
.. code-block:: xml
8282
83-
<!-- app/Resources/translations/messages.en.xliff -->
83+
<!-- app/Resources/translations/messages.en.xlf -->
8484
<?xml version="1.0"?>
8585
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
8686
<file source-language="en" target-language="en" datatype="plaintext" original="file.ext">

best_practices/introduction.rst

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
The Symfony Framework Best Practices
55
====================================
66

7-
The Symfony framework is well-known for being *really* flexible and is used
7+
The Symfony Framework is well-known for being *really* flexible and is used
88
to build micro-sites, enterprise applications that handle billions of connections
99
and even as the basis for *other* frameworks. Since its release in July 2011,
1010
the community has learned a lot about what's possible and how to do things *best*.
@@ -19,7 +19,7 @@ What is this Guide About?
1919
-------------------------
2020

2121
This guide aims to fix that by describing the **best practices for developing
22-
web apps with the Symfony full-stack framework**. These are best practices that
22+
web apps with the Symfony full-stack Framework**. These are best practices that
2323
fit the philosophy of the framework as envisioned by its original creator
2424
`Fabien Potencier`_.
2525

@@ -32,7 +32,7 @@ fit the philosophy of the framework as envisioned by its original creator
3232

3333
This guide is **specially suited** for:
3434

35-
* Websites and web applications developed with the full-stack Symfony framework.
35+
* Websites and web applications developed with the full-stack Symfony Framework.
3636

3737
For other situations, this guide might be a good **starting point** that you can
3838
then **extend and fit to your specific needs**:
@@ -62,22 +62,30 @@ Symfony to follow everything. If you are totally new to Symfony, welcome!
6262
Start with :doc:`The Quick Tour </quick_tour/the_big_picture>` tutorial first.
6363

6464
We've deliberately kept this guide short. We won't repeat explanations that
65-
you can find in the vast Symfony documentation, like discussions about dependency
66-
injection or front controllers. We'll solely focus on explaining how to do
65+
you can find in the vast Symfony documentation, like discussions about Dependency
66+
Injection or front controllers. We'll solely focus on explaining how to do
6767
what you already know.
6868

6969
The Application
7070
---------------
7171

72-
In addition to this guide, you'll find a sample application developed with
73-
all these best practices in mind. **The application is a simple blog engine**,
74-
because that will allow us to focus on the Symfony concepts and features without
75-
getting buried in difficult details.
72+
In addition to this guide, a sample application has been developed with all these
73+
best practices in mind. This project, called the Symfony Demo application, can
74+
be obtained through the Symfony Installer. First, `download and install`_ the
75+
installer and then execute this command to download the demo application:
7676

77-
Instead of developing the application step by step in this guide, you'll find
78-
selected snippets of code through the chapters. Please refer to the last chapter
79-
of this guide to find more details about this application and the instructions
80-
to install it.
77+
.. code-block:: bash
78+
79+
# Linux and Mac OS X
80+
$ symfony demo
81+
82+
# Windows
83+
c:\> php symfony demo
84+
85+
**The demo application is a simple blog engine**, because that will allow us to
86+
focus on the Symfony concepts and features without getting buried in difficult
87+
implementation details. Instead of developing the application step by step in
88+
this guide, you'll find selected snippets of code through the chapters.
8189

8290
Don't Update Your Existing Applications
8391
---------------------------------------
@@ -95,3 +103,4 @@ practices**. The reasons for not doing it are various:
95103
your tests or adding features that provide real value to the end users.
96104

97105
.. _`Fabien Potencier`: https://connect.sensiolabs.com/profile/fabpot
106+
.. _`download and install`: http://symfony.com/download

best_practices/security.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,16 @@ more advanced use-case, you can always do the same security check in PHP:
234234
}
235235
236236
if (!$post->isAuthor($this->getUser())) {
237-
throw $this->createAccessDeniedException();
237+
$this->denyAccessUnlessGranted('edit', $post);
238+
239+
// or without the shortcut:
240+
//
241+
// use Symfony\Component\Security\Core\Exception\AccessDeniedException;
242+
// ...
243+
//
244+
// if (!$this->get('security.authorization_checker')->isGranted('edit', $post)) {
245+
// throw $this->createAccessDeniedException();
246+
// }
238247
}
239248
240249
// ...
@@ -334,6 +343,9 @@ via the even easier shortcut in a controller:
334343
335344
// or without the shortcut:
336345
//
346+
// use Symfony\Component\Security\Core\Exception\AccessDeniedException;
347+
// ...
348+
//
337349
// if (!$this->get('security.authorization_checker')->isGranted('edit', $post)) {
338350
// throw $this->createAccessDeniedException();
339351
// }

best_practices/templates.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ Another advantage is that centralizing your templates simplifies the work
5151
of your designers. They don't need to look for templates in lots of directories
5252
scattered through lots of bundles.
5353

54+
.. best-practice::
55+
56+
Use lowercased snake_case for directory and template names.
57+
5458
Twig Extensions
5559
---------------
5660

best_practices/tests.rst

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,35 @@ A functional test can be as easy as this:
3030

3131
.. code-block:: php
3232
33-
/** @dataProvider provideUrls */
34-
public function testPageIsSuccessful($url)
35-
{
36-
$client = self::createClient();
37-
$client->request('GET', $url);
33+
// src/AppBundle/Tests/ApplicationAvailabilityFunctionalTest.php
34+
namespace AppBundle\Tests;
3835
39-
$this->assertTrue($client->getResponse()->isSuccessful());
40-
}
36+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
4137
42-
public function provideUrls()
38+
class ApplicationAvailabilityFunctionalTest extends WebTestCase
4339
{
44-
return array(
45-
array('/'),
46-
array('/posts'),
47-
array('/post/fixture-post-1'),
48-
array('/blog/category/fixture-category'),
49-
array('/archives'),
50-
// ...
51-
);
40+
/**
41+
* @dataProvider urlProvider
42+
*/
43+
public function testPageIsSuccessful($url)
44+
{
45+
$client = self::createClient();
46+
$client->request('GET', $url);
47+
48+
$this->assertTrue($client->getResponse()->isSuccessful());
49+
}
50+
51+
public function urlProvider()
52+
{
53+
return array(
54+
array('/'),
55+
array('/posts'),
56+
array('/post/fixture-post-1'),
57+
array('/blog/category/fixture-category'),
58+
array('/archives'),
59+
// ...
60+
);
61+
}
5262
}
5363
5464
This code checks that all the given URLs load successfully, which means that

best_practices/web-assets.rst

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ much more concise:
2929
.. note::
3030

3131
Keep in mind that ``web/`` is a public directory and that anything stored
32-
here will be publicly accessible. For that reason, you should put your
33-
compiled web assets here, but not their source files (e.g. SASS files).
32+
here will be publicly accessible, including all the original asset files
33+
(e.g. Sass, LESS and CoffeScript files).
3434

3535
Using Assetic
3636
-------------
@@ -51,16 +51,15 @@ tools like GruntJS.
5151

5252
:doc:`Assetic </cookbook/assetic/asset_management>` is an asset manager capable
5353
of compiling assets developed with a lot of different frontend technologies
54-
like LESS, Sass and CoffeeScript.
55-
Combining all your assets with Assetic is a matter of wrapping all the assets
56-
with a single Twig tag:
54+
like LESS, Sass and CoffeeScript. Combining all your assets with Assetic is a
55+
matter of wrapping all the assets with a single Twig tag:
5756

5857
.. code-block:: html+jinja
5958

6059
{% stylesheets
6160
'css/bootstrap.min.css'
6261
'css/main.css'
63-
filter='cssrewrite' output='css/compiled/all.css' %}
62+
filter='cssrewrite' output='css/compiled/app.css' %}
6463
<link rel="stylesheet" href="{{ asset_url }}" />
6564
{% endstylesheets %}
6665

@@ -69,7 +68,7 @@ with a single Twig tag:
6968
{% javascripts
7069
'js/jquery.min.js'
7170
'js/bootstrap.min.js'
72-
output='js/compiled/all.js' %}
71+
output='js/compiled/app.js' %}
7372
<script src="{{ asset_url }}"></script>
7473
{% endjavascripts %}
7574

0 commit comments

Comments
 (0)