Skip to content

Commit 3ac74f0

Browse files
committed
Merge branch '4.4' into 5.1
* 4.4: Update doctrine.rst Update multiple_kernels.rst Fixed DOCtor [Cache] Custom pool namespaces [#12802] Updated XML and PHP examples Security: How to Build a Login Form: sync with recent Maker Bundle changes Added PHP typehints to getting started guides Update deployment docs with new .env loading Missing format parameter in a serialize call
2 parents 77a53e4 + 2cc077f commit 3ac74f0

11 files changed

+217
-84
lines changed

cache.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,53 @@ with either :class:`Symfony\\Contracts\\Cache\\CacheInterface` or
325325
// ...
326326
}
327327

328+
.. tip::
329+
330+
If you need the namespace to be interoperable with a third-party app,
331+
you can take control over auto-generation by setting the ``namespace``
332+
attribute of the ``cache.pool`` service tag. For example, you can
333+
override the service definition of the adapter:
334+
335+
.. configuration-block::
336+
337+
.. code-block:: yaml
338+
339+
# config/services.yaml
340+
services:
341+
app.cache.adapter.redis:
342+
parent: 'cache.adapter.redis'
343+
tags:
344+
- { name: 'cache.pool', namespace: 'my_custom_namespace' }
345+
346+
.. code-block:: xml
347+
348+
<!-- config/services.xml -->
349+
<?xml version="1.0" encoding="UTF-8" ?>
350+
<container xmlns="http://symfony.com/schema/dic/services"
351+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
352+
xsi:schemaLocation="http://symfony.com/schema/dic/services
353+
https://symfony.com/schema/dic/services/services-1.0.xsd">
354+
355+
<services>
356+
<service id="app.cache.adapter.redis" parent="cache.adapter.redis">
357+
<tag name="cache.pool" namespace="my_custom_namespace"/>
358+
</service>
359+
</services>
360+
</container>
361+
362+
.. code-block:: php
363+
364+
// config/services.php
365+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
366+
367+
return function(ContainerConfigurator $configurator) {
368+
$services = $configurator->services();
369+
370+
$services->set('app.cace.adapter.redis')
371+
->parent('cache.adapter.redis')
372+
->tag('cache.pool', ['namespace' => 'my_custom_namespace'])
373+
};
374+
328375
Custom Provider Options
329376
-----------------------
330377

components/serializer.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ defines a ``Person`` entity with a ``firstName`` property:
616616
This custom mapping is used to convert property names when serializing and
617617
deserializing objects::
618618

619-
$serialized = $serializer->serialize(new Person("Kévin"));
619+
$serialized = $serializer->serialize(new Person("Kévin"), 'json');
620620
// {"customer_name": "Kévin"}
621621

622622
Serializing Boolean Attributes
@@ -1456,7 +1456,7 @@ and ``BitBucketCodeRepository`` classes:
14561456
14571457
Once configured, the serializer uses the mapping to pick the correct class::
14581458

1459-
$serialized = $serializer->serialize(new GitHubCodeRepository());
1459+
$serialized = $serializer->serialize(new GitHubCodeRepository(), 'json');
14601460
// {"type": "github"}
14611461

14621462
$repository = $serializer->deserialize($serialized, CodeRepository::class, 'json');

configuration.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,12 +753,13 @@ use the ``getParameter()`` helper::
753753
namespace App\Controller;
754754

755755
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
756+
use Symfony\Component\HttpFoundation\Response;
756757

757758
class UserController extends AbstractController
758759
{
759760
// ...
760761

761-
public function index()
762+
public function index(): Response
762763
{
763764
$projectDir = $this->getParameter('kernel.project_dir');
764765
$adminEmail = $this->getParameter('app.admin_email');

configuration/multiple_kernels.rst

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,31 +88,50 @@ files so they don't collide with the files from ``src/Kernel.php``::
8888

8989
class ApiKernel extends Kernel
9090
{
91-
// ...
91+
use MicroKernelTrait;
9292

9393
public function registerBundles()
9494
{
95-
// load only the bundles strictly needed for the API...
95+
// load only the bundles strictly needed for the API
96+
$contents = require $this->getProjectDir().'/config/api_bundles.php';
97+
foreach ($contents as $class => $envs) {
98+
if ($envs[$this->environment] ?? $envs['all'] ?? false) {
99+
yield new $class();
100+
}
101+
}
102+
}
103+
104+
public function getProjectDir(): string
105+
{
106+
return \dirname(__DIR__);
96107
}
97108

98-
public function getCacheDir()
109+
public function getCacheDir(): string
99110
{
100-
return dirname(__DIR__).'/var/cache/api/'.$this->getEnvironment();
111+
return $this->getProjectDir().'/var/cache/api/'.$this->getEnvironment();
101112
}
102113

103-
public function getLogDir()
114+
public function getLogDir(): string
104115
{
105-
return dirname(__DIR__).'/var/log/api';
116+
return $this->getProjectDir().'/var/log/api';
106117
}
107118

108119
public function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
109120
{
110-
// load only the config files strictly needed for the API
111-
$confDir = $this->getProjectDir().'/config';
112-
$loader->load($confDir.'/api/*'.self::CONFIG_EXTS, 'glob');
113-
if (is_dir($confDir.'/api/'.$this->environment)) {
114-
$loader->load($confDir.'/api/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
115-
}
121+
$container->addResource(new FileResource($this->getProjectDir().'/config/api_bundles.php'));
122+
$container->setParameter('container.dumper.inline_factories', true);
123+
$confDir = $this->getProjectDir().'/config/api';
124+
125+
$loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
126+
$loader->load($confDir.'/{packages}/'.$this->environment.'/*'.self::CONFIG_EXTS, 'glob');
127+
$loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
128+
$loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
129+
}
130+
131+
protected function configureRoutes(RouteCollectionBuilder $routes): void
132+
{
133+
$confDir = $this->getProjectDir().'/config/api';
134+
// ... load only the config routes strictly needed for the API
116135
}
117136
}
118137

controller.rst

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class::
3636
/**
3737
* @Route("/lucky/number/{max}", name="app_lucky_number")
3838
*/
39-
public function number($max)
39+
public function number(int $max): Response
4040
{
4141
$number = random_int(0, $max);
4242

@@ -134,7 +134,7 @@ and ``redirect()`` methods::
134134
use Symfony\Component\HttpFoundation\RedirectResponse;
135135

136136
// ...
137-
public function index()
137+
public function index(): RedirectResponse
138138
{
139139
// redirects to the "homepage" route
140140
return $this->redirectToRoute('homepage');
@@ -196,12 +196,13 @@ If you need a service in a controller, type-hint an argument with its class
196196
(or interface) name. Symfony will automatically pass you the service you need::
197197

198198
use Psr\Log\LoggerInterface;
199+
use Symfony\Component\HttpFoundation\Response;
199200
// ...
200201

201202
/**
202203
* @Route("/lucky/number/{max}")
203204
*/
204-
public function number($max, LoggerInterface $logger)
205+
public function number(int $max, LoggerInterface $logger): Response
205206
{
206207
$logger->info('We are logging!');
207208
// ...
@@ -322,10 +323,11 @@ Managing Errors and 404 Pages
322323
When things are not found, you should return a 404 response. To do this, throw a
323324
special type of exception::
324325

326+
use Symfony\Component\HttpFoundation\Response;
325327
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
326328

327329
// ...
328-
public function index()
330+
public function index(): Response
329331
{
330332
// retrieve the object from database
331333
$product = ...;
@@ -370,8 +372,10 @@ object. To access it in your controller, add it as an argument and
370372
**type-hint it with the Request class**::
371373

372374
use Symfony\Component\HttpFoundation\Request;
375+
use Symfony\Component\HttpFoundation\Response;
376+
// ...
373377

374-
public function index(Request $request, $firstName, $lastName)
378+
public function index(Request $request, string $firstName, string $lastName): Response
375379
{
376380
$page = $request->query->get('page', 1);
377381

@@ -401,9 +405,11 @@ Session storage and other configuration can be controlled under the
401405
To get the session, add an argument and type-hint it with
402406
:class:`Symfony\\Component\\HttpFoundation\\Session\\SessionInterface`::
403407

408+
use Symfony\Component\HttpFoundation\Response;
404409
use Symfony\Component\HttpFoundation\Session\SessionInterface;
410+
// ...
405411

406-
public function index(SessionInterface $session)
412+
public function index(SessionInterface $session): Response
407413
{
408414
// stores an attribute for reuse during a later user request
409415
$session->set('foo', 'bar');
@@ -413,6 +419,8 @@ To get the session, add an argument and type-hint it with
413419

414420
// uses a default value if the attribute doesn't exist
415421
$filters = $session->get('filters', []);
422+
423+
// ...
416424
}
417425

418426
Stored attributes remain in the session for the remainder of that user's session.
@@ -435,8 +443,10 @@ from the session automatically as soon as you retrieve them. This feature makes
435443
For example, imagine you're processing a :doc:`form </forms>` submission::
436444

437445
use Symfony\Component\HttpFoundation\Request;
446+
use Symfony\Component\HttpFoundation\Response;
447+
// ...
438448

439-
public function update(Request $request)
449+
public function update(Request $request): Response
440450
{
441451
// ...
442452

@@ -515,8 +525,9 @@ pass the ``Request`` object to any controller argument that is type-hinted with
515525
the ``Request`` class::
516526

517527
use Symfony\Component\HttpFoundation\Request;
528+
use Symfony\Component\HttpFoundation\Response;
518529

519-
public function index(Request $request)
530+
public function index(Request $request): Response
520531
{
521532
$request->isXmlHttpRequest(); // is it an Ajax request?
522533

@@ -572,7 +583,7 @@ To get the value of any :ref:`configuration parameter <configuration-parameters>
572583
from a controller, use the ``getParameter()`` helper method::
573584

574585
// ...
575-
public function index()
586+
public function index(): Response
576587
{
577588
$contentsDir = $this->getParameter('kernel.project_dir').'/contents';
578589
// ...
@@ -584,8 +595,10 @@ Returning JSON Response
584595
To return JSON from a controller, use the ``json()`` helper method. This returns a
585596
``JsonResponse`` object that encodes the data automatically::
586597

598+
use Symfony\Component\HttpFoundation\Response;
587599
// ...
588-
public function index()
600+
601+
public function index(): Response
589602
{
590603
// returns '{"username":"jane.doe"}' and sets the proper Content-Type header
591604
return $this->json(['username' => 'jane.doe']);
@@ -604,7 +617,10 @@ Streaming File Responses
604617
You can use the :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::file`
605618
helper to serve a file from inside a controller::
606619

607-
public function download()
620+
use Symfony\Component\HttpFoundation\Response;
621+
// ...
622+
623+
public function download(): Response
608624
{
609625
// send the file contents and force the browser to download it
610626
return $this->file('/path/to/some_file.pdf');
@@ -614,8 +630,9 @@ The ``file()`` helper provides some arguments to configure its behavior::
614630

615631
use Symfony\Component\HttpFoundation\File\File;
616632
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
633+
// ...
617634

618-
public function download()
635+
public function download(): Response
619636
{
620637
// load the file from the filesystem
621638
$file = new File('/path/to/some_file.pdf');

deployment.rst

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,21 +126,29 @@ While developing locally, you'll usually store these in ``.env`` and ``.env.loca
126126

127127
1. Create "real" environment variables. How you set environment variables, depends
128128
on your setup: they can be set at the command line, in your Nginx configuration,
129-
or via other methods provided by your hosting service.
129+
or via other methods provided by your hosting service;
130130

131-
2. Or, create a ``.env.local`` file like your local development (see note below)
131+
2. Or, create a ``.env.local`` file like your local development.
132132

133133
There is no significant advantage to either of the two options: use whatever is
134134
most natural in your hosting environment.
135135

136-
.. note::
136+
.. tip::
137+
138+
You might not want your application to process the ``.env.*`` files on
139+
every request. You can generate an optimized ``.env.local.php`` which
140+
overrides all other configuration files:
141+
142+
.. code-block:: terminal
143+
144+
$ composer dump-env prod
137145
138-
If you use the ``.env.*`` files on production, you may need to move your
139-
``symfony/dotenv`` dependency from ``require-dev`` to ``require`` in ``composer.json``:
146+
The generated file will contain all the configuration stored in ``.env``. If you
147+
want to rely only on environment variables, generate one without any values using:
140148

141149
.. code-block:: terminal
142150
143-
$ composer require symfony/dotenv
151+
$ composer dump-env prod --empty
144152
145153
C) Install/Update your Vendors
146154
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

doctrine.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,4 +875,4 @@ Learn more
875875
.. _`API Platform`: https://api-platform.com/docs/core/validation/
876876
.. _`PDO`: https://www.php.net/pdo
877877
.. _`available Doctrine extensions`: https://github.com/Atlantic18/DoctrineExtensions
878-
.. _`StofDoctrineExtensionsBundle`: https://github.com/antishov/StofDoctrineExtensionsBundle
878+
.. _`StofDoctrineExtensionsBundle`: https://github.com/stof/StofDoctrineExtensionsBundle

page_creation.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,15 @@ variable so you can use it in Twig::
226226
// src/Controller/LuckyController.php
227227
namespace App\Controller;
228228

229+
use Symfony\Component\HttpFoundation\Response;
229230
// ...
231+
230232
class LuckyController extends AbstractController
231233
{
232234
/**
233235
* @Route("/lucky/number")
234236
*/
235-
public function number()
237+
public function number(): Response
236238
{
237239
$number = random_int(0, 100);
238240

0 commit comments

Comments
 (0)