Skip to content

Commit 1c643c4

Browse files
committed
Merge branch '2.8' into 3.2
* 2.8: (46 commits) [symfony#7507] fix component name [symfony#7490] minor typo fix Added a note about redirections to absolute URLs in tests Added the changes suggested by reviewers [symfony#7620] use generate() in PHP templates before 2.8 Fixed the RST syntax Improve example context [symfony#5621] Enhancing example of using bundle config [symfony#7601] minor tweak Update expiration.rst Update expiration.rst Update expiration.rst Update expiration.rst Minor reword and fixed the line length Improve specification explanation [symfony#7664] minor wording tweak Rewords and minor fixes Add an explanation about «constraints» validation [symfony#7645] enumerate ordered list items implicitly Adding a new article about "Creating a Bug Reproducer" ...
2 parents 02ca572 + a4fa352 commit 1c643c4

22 files changed

+440
-196
lines changed

_build/redirection_map

+1
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,4 @@
332332
/deployment/tools /deployment
333333
/install/bundles /setup/bundles
334334
/form /forms
335+
/testing/simulating_authentication /testing/http_authentication

bundles/configuration.rst

+48-4
Original file line numberDiff line numberDiff line change
@@ -218,18 +218,64 @@ This class can now be used in your ``load()`` method to merge configurations and
218218
force validation (e.g. if an additional option was passed, an exception will be
219219
thrown)::
220220

221+
// src/Acme/SocialBundle/DependencyInjection/AcmeSocialExtension.php
222+
221223
public function load(array $configs, ContainerBuilder $container)
222224
{
223225
$configuration = new Configuration();
224226

225227
$config = $this->processConfiguration($configuration, $configs);
226-
// ...
228+
229+
// you now have these 2 config keys
230+
// $config['twitter']['client_id'] and $config['twitter']['client_secret']
227231
}
228232

229233
The ``processConfiguration()`` method uses the configuration tree you've defined
230234
in the ``Configuration`` class to validate, normalize and merge all the
231235
configuration arrays together.
232236

237+
Now, you can use the ``$config`` variable to modify a service provided by your bundle.
238+
For example, imagine your bundle has the following example config:
239+
240+
.. code-block:: xml
241+
242+
<!-- src/Acme/SocialBundle/Resources/config/services.xml -->
243+
<?xml version="1.0" encoding="UTF-8" ?>
244+
<container xmlns="http://symfony.com/schema/dic/services"
245+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
246+
xsi:schemaLocation="http://symfony.com/schema/dic/services
247+
http://symfony.com/schema/dic/services/services-1.0.xsd">
248+
249+
<services>
250+
<service id="acme.social.twitter_client" class="Acme\SocialBundle\TwitterClient">
251+
<argument></argument> <!-- will be filled in with client_id dynamically -->
252+
<argument></argument> <!-- will be filled in with client_secret dynamically -->
253+
</service>
254+
</services>
255+
</container>
256+
257+
In your extension, you can load this and dynamically set its arguments::
258+
259+
// src/Acme/SocialBundle/DependencyInjection/AcmeSocialExtension.php
260+
// ...
261+
262+
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
263+
use Symfony\Component\Config\FileLocator;
264+
265+
public function load(array $configs, ContainerBuilder $container)
266+
{
267+
$loader = new XmlFileLoader($container, new FileLocator(dirname(__DIR__).'/Resources/config'));
268+
$loader->load('services.xml');
269+
270+
$configuration = new Configuration();
271+
$config = $this->processConfiguration($configuration, $configs);
272+
273+
$def = $container->getDefinition('acme.social.twitter_client');
274+
$def->replaceArgument(0, $config['twitter']['client_id']);
275+
$def->replaceArgument(1, $config['twitter']['client_secret']);
276+
}
277+
278+
233279
.. tip::
234280

235281
Instead of calling ``processConfiguration()`` in your extension each time you
@@ -253,9 +299,7 @@ configuration arrays together.
253299
}
254300

255301
This class uses the ``getConfiguration()`` method to get the Configuration
256-
instance. You should override it if your Configuration class is not called
257-
``Configuration`` or if it is not placed in the same namespace as the
258-
extension.
302+
instance.
259303

260304
.. sidebar:: Processing the Configuration yourself
261305

bundles/inheritance.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ The same goes for routing files and some other resources.
9393

9494
The overriding of resources only works when you refer to resources with
9595
the ``@FOSUserBundle/Resources/config/routing/security.xml`` method.
96-
If you refer to resources without using the ``@BundleName`` shortcut, they
97-
can't be overridden in this way.
96+
You need to use the ``@BundleName`` shortcut when referring to resources
97+
so they can be successfully overridden (except templates, which are
98+
overridden in a different way, as explained in :doc:`/templating/overriding`).
9899

99100
.. caution::
100101

bundles/installation.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ version, include it as the second argument of the `composer require`_ command:
4848
B) Enable the Bundle
4949
--------------------
5050

51-
At this point, the bundle is installed in your Symfony project (in
51+
At this point, the bundle is installed in your Symfony project (e.g.
5252
``vendor/friendsofsymfony/``) and the autoloader recognizes its classes.
5353
The only thing you need to do now is register the bundle in ``AppKernel``::
5454

bundles/override.rst

+4-12
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Services & Configuration
3939

4040
If you want to modify service definitions of another bundle, you can use a compiler
4141
pass to change the class of the service or to modify method calls. In the following
42-
example, the implementing class for the ``original-service-id`` is changed to
42+
example, the implementing class for the ``original-service-id`` is changed to
4343
``Acme\DemoBundle\YourService``::
4444

4545
// src/Acme/DemoBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php
@@ -72,16 +72,8 @@ associations. Learn more about this feature and its limitations in
7272
Forms
7373
-----
7474

75-
Form types are referred to by their fully-qualified class name::
76-
77-
$builder->add('name', CustomType::class);
78-
79-
This means that you cannot override this by creating a sub-class of ``CustomType``
80-
and registering it as a service and tagging it with ``form.type`` (you *could*
81-
do this in earlier version).
82-
83-
Instead, you should use a "form type extension" to modify the existing form type.
84-
For more information, see :doc:`/form/create_form_type_extension`.
75+
Existing form types can be modified defining
76+
:doc:`form type extensions </form/create_form_type_extension>`.
8577

8678
.. _override-validation:
8779

@@ -92,7 +84,7 @@ Symfony loads all validation configuration files from every bundle and
9284
combines them into one validation metadata tree. This means you are able to
9385
add new constraints to a property, but you cannot override them.
9486

95-
To override this, the 3rd party bundle needs to have configuration for
87+
To overcome this, the 3rd party bundle needs to have configuration for
9688
:doc:`validation groups </validation/groups>`. For instance, the FOSUserBundle
9789
has this configuration. To create your own validation, add the constraints
9890
to a new validation group:

bundles/prepend_extension.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
single: Configuration; Semantic
33
single: Bundle; Extension configuration
44

5-
How to Simplify Configuration of multiple Bundles
5+
How to Simplify Configuration of Multiple Bundles
66
=================================================
77

88
When building reusable and extensible applications, developers are often
@@ -12,9 +12,9 @@ users to choose to remove functionality they are not using. Creating multiple
1212
bundles has the drawback that configuration becomes more tedious and settings
1313
often need to be repeated for various bundles.
1414

15-
Using the below approach, it is possible to remove the disadvantage of the
16-
multiple bundle approach by enabling a single Extension to prepend the settings
17-
for any bundle. It can use the settings defined in the ``app/config/config.yml``
15+
It is possible to remove the disadvantage of the multiple bundle approach
16+
by enabling a single Extension to prepend the settings for any bundle.
17+
It can use the settings defined in the ``app/config/config.yml``
1818
to prepend settings just as if they had been written explicitly by
1919
the user in the application configuration.
2020

console/coloring.rst

+6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ You can also set these colors and options directly inside the tagname::
6868
// bold text with underscore
6969
$output->writeln('<options=bold,underscore>foo</>');
7070

71+
.. note::
72+
73+
If you need to render a tag literally, escape it with a backslash: ``\<info>``
74+
or use the :method:`Symfony\\Component\\Console\\Formatter\\OutputFormatter::escape`
75+
method to escape all the tags included in the given string.
76+
7177
.. _Cmder: http://cmder.net/
7278
.. _ConEmu: https://conemu.github.io/
7379
.. _ANSICON: https://github.com/adoxa/ansicon/releases

contributing/code/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Contributing Code
55
:maxdepth: 2
66

77
bugs
8+
reproducer
89
patches
910
maintenance
1011
core_team

contributing/code/reproducer.rst

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
Creating a Bug Reproducer
2+
=========================
3+
4+
The main Symfony code repository receives thousands of issues reports per year.
5+
Some of those issues are so obvious or easy to understand, that Symfony Core
6+
developers can fix them without any other information. However, other issues are
7+
much harder to understand because developers can't easily reproduce them in their
8+
computers. That's when we'll ask you to create a "bug reproducer", which is the
9+
minimum amount of code needed to make the bug appear when executed.
10+
11+
Reproducing Simple Bugs
12+
-----------------------
13+
14+
If you are reporting a bug related to some Symfony component used outside the
15+
Symfony framework, it's enough to share a small PHP script that when executed
16+
shows the bug::
17+
18+
// First, run "composer require symfony/validator"
19+
// Then, execute this file:
20+
<?php
21+
require_once __DIR__.'/vendor/autoload.php';
22+
use Symfony\Component\Validator\Constraints;
23+
24+
$wrongUrl = 'http://example.com/exploit.html?<script>alert(1);</script>';
25+
$urlValidator = new Constraints\UrlValidator();
26+
$urlConstraint = new Constraints\Url();
27+
28+
// The URL is wrong, so var_dump() should display an error, but it displays
29+
// "null" instead because there is no context to build a validator violation
30+
var_dump($urlValidator->validate($wrongUrl, $urlConstraint));
31+
32+
Reproducing Complex Bugs
33+
------------------------
34+
35+
If the bug is related to the Symfony Framework or if it's too complex to create
36+
a PHP script, it's better to reproduce the bug by forking the Symfony Standard
37+
edition. To do so:
38+
39+
#. Go to https://github.com/symfony/symfony-standard and click on the **Fork**
40+
button to make a fork of that repository or go to your already forked copy.
41+
#. Clone the forked repository into your computer:
42+
``git clone git://github.com/YOUR-GITHUB-USERNAME/symfony-standard.git``
43+
#. Browse the project and create a new branch (e.g. ``issue_23567``,
44+
``reproduce_23657``, etc.)
45+
#. Now you must add the minimum amount of code to reproduce the bug. This is the
46+
trickiest part and it's explained a bit more later.
47+
#. Add, commit and push all your changes.
48+
#. Add a comment in your original issue report to share the URL of your forked
49+
project (e.g. ``https://github.com/YOUR-GITHUB-USERNAME/symfony-standard/tree/issue_23567``)
50+
and, if necessary, explain the steps to reproduce (e.g. "browse this URL",
51+
"fill in this data in the form and submit it", etc.)
52+
53+
Adding the Minimum Amount of Code Possible
54+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55+
56+
The key to create a bug reproducer is to solely focus on the feature that you
57+
suspect is failing. For example, imagine that you suspect that the bug is related
58+
to a route definition. Then, after forking the Symfony Standard Edition:
59+
60+
#. Don't edit any of the default Symfony configuration options.
61+
#. Don't copy your original application code and don't use the same structure
62+
of bundles, controllers, actions, etc. as in your original application.
63+
#. Open the default controller class of the AppBundle and add your routing
64+
definition using annotations.
65+
#. Don't create or modify any other file.
66+
#. Execute the ``server:run`` command and browse the previously defined route
67+
to see if the bug appears or not.
68+
#. If you can see the bug, you're done and you can already share the code with us.
69+
#. If you can't see the bug, you must keep making small changes. For example, if
70+
your original route was defined using XML, forget about the previous route
71+
annotation and define the route using XML instead. Or maybe your application
72+
uses bundle inheritance and that's where the real bug is. Then, forget about
73+
AppBundle and quickly generate a new AppParentBundle, make AppBundle inherit
74+
from it and test if the route is working.
75+
76+
In short, the idea is to keep adding small and incremental changes to the default
77+
Symfony Standard edition until you can reproduce the bug.

deployment/platformsh.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ soon be able to see it in your browser.
186186

187187
.. _`Platform.sh`: https://platform.sh
188188
.. _`Platform.sh documentation`: https://docs.platform.sh/frameworks/symfony.html
189-
.. _`Platform.sh project`: https://marketplace.commerceguys.com/platform/buy-now
190-
.. _`Platform.sh configuration files`: https://docs.platform.sh/reference/configuration-files
189+
.. _`Platform.sh project`: https://accounts.platform.sh/platform/buy-now
190+
.. _`Platform.sh configuration files`: https://docs.platform.sh/configuration/services.html
191191
.. _`GitHub`: https://github.com/platformsh/platformsh-examples
192192
.. _`available services`: https://docs.platform.sh/reference/configuration-files/#configure-services
193-
.. _`migrating your database and files`: https://docs.platform.sh/toolstacks/php/symfony/migrate-existing-site/
193+
.. _`migrating your database and files`: https://docs.platform.sh/tutorials/migrating.html

form/action_method.rst

+92-15
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,108 @@ URL under which the form was rendered. Sometimes you want to change these
99
parameters. You can do so in a few different ways.
1010

1111
If you use the :class:`Symfony\\Component\\Form\\FormBuilder` to build your
12-
form, you can use ``setAction()`` and ``setMethod()``::
12+
form, you can use ``setAction()`` and ``setMethod()``:
1313

14-
$form = $this->createFormBuilder($task)
15-
->setAction($this->generateUrl('target_route'))
16-
->setMethod('GET')
17-
->add('task', TextType::class)
18-
->add('dueDate', DateType::class)
19-
->add('save', SubmitType::class)
20-
->getForm();
14+
.. configuration-block::
15+
16+
.. code-block:: php-symfony
17+
18+
// AppBundle/Controller/DefaultController.php
19+
namespace AppBundle\Controller;
20+
21+
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
22+
use Symfony\Component\Form\Extension\Core\Type\DateType;
23+
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
24+
use Symfony\Component\Form\Extension\Core\Type\TextType;
25+
26+
class DefaultController extends Controller
27+
{
28+
public function newAction()
29+
{
30+
$form = $this->createFormBuilder($task)
31+
->setAction($this->generateUrl('target_route'))
32+
->setMethod('GET')
33+
->add('task', TextType::class)
34+
->add('dueDate', DateType::class)
35+
->add('save', SubmitType::class)
36+
->getForm();
37+
38+
// ...
39+
}
40+
}
41+
42+
.. code-block:: php-standalone
43+
44+
use Symfony\Component\Form\Forms;
45+
use Symfony\Component\Form\Extension\Core\Type\DateType;
46+
use Symfony\Component\Form\Extension\Core\Type\FormType;
47+
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
48+
use Symfony\Component\Form\Extension\Core\Type\TextType;
49+
50+
// ...
51+
52+
$formFactoryBuilder = Forms::createFormFactoryBuilder();
53+
54+
// Form factory builder configuration ...
55+
56+
$formFactory = $formFactoryBuilder->getFormFactory();
57+
58+
$form = $formFactory->createBuilder(FormType::class, $task)
59+
->setAction($this->generateUrl('target_route'))
60+
->setMethod('GET')
61+
->add('task', TextType::class)
62+
->add('dueDate', DateType::class)
63+
->add('save', SubmitType::class)
64+
->getForm();
2165
2266
.. note::
2367

2468
This example assumes that you've created a route called ``target_route``
2569
that points to the controller that processes the form.
2670

2771
When using a form type class, you can pass the action and method as form
28-
options::
72+
options:
2973

30-
use AppBundle\Form\TaskType;
31-
// ...
74+
.. configuration-block::
75+
76+
.. code-block:: php-symfony
77+
78+
// AppBundle/Controller/DefaultController.php
79+
namespace AppBundle\Controller;
80+
81+
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
82+
use AppBundle\Form\TaskType;
83+
84+
class DefaultController extends Controller
85+
{
86+
public function newAction()
87+
{
88+
// ...
89+
90+
$form = $this->createForm(TaskType::class, $task, array(
91+
'action' => $this->generateUrl('target_route'),
92+
'method' => 'GET',
93+
));
94+
95+
// ...
96+
}
97+
}
3298
33-
$form = $this->createForm(TaskType::class, $task, array(
34-
'action' => $this->generateUrl('target_route'),
35-
'method' => 'GET',
36-
));
99+
.. code-block:: php-standalone
100+
101+
use Symfony\Component\Form\Forms;
102+
use AppBundle\Form\TaskType;
103+
104+
$formFactoryBuilder = Forms::createFormFactoryBuilder();
105+
106+
// Form factory builder configuration ...
107+
108+
$formFactory = $formFactoryBuilder->getFormFactory();
109+
110+
$form = $formFactory->create(TaskType::class, $task, array(
111+
'action' => $this->generateUrl('target_route'),
112+
'method' => 'GET',
113+
));
37114
38115
Finally, you can override the action and method in the template by passing them
39116
to the ``form()`` or the ``form_start()`` helper functions:

0 commit comments

Comments
 (0)