diff --git a/configuration/dot-env-changes.rst b/configuration/dot-env-changes.rst index 89844d991b1..7386a05966f 100644 --- a/configuration/dot-env-changes.rst +++ b/configuration/dot-env-changes.rst @@ -55,17 +55,18 @@ changes can be made to any Symfony 3.4 or higher app: #. Update ``.gitignore``: .. code-block:: diff + :dedent: 0 - # .gitignore - # ... + # .gitignore + # ... - ###> symfony/framework-bundle ### + ###> symfony/framework-bundle ### - /.env + /.env.local + /.env.local.php + /.env.*.local - # ... + # ... #. Rename ``.env`` to ``.env.local`` and ``.env.dist`` to ``.env``: diff --git a/controller.rst b/controller.rst index a5017452832..d17d719f1ac 100644 --- a/controller.rst +++ b/controller.rst @@ -97,17 +97,18 @@ Add the ``use`` statement atop your controller class and then modify ``LuckyController`` to extend it: .. code-block:: diff + :dedent: 0 - // src/Controller/LuckyController.php - namespace App\Controller; + // src/Controller/LuckyController.php + namespace App\Controller; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; - class LuckyController + class LuckyController extends AbstractController - { - // ... - } + { + // ... + } That's it! You now have access to methods like :ref:`$this->render() ` and many others that you'll learn about next. diff --git a/doctrine.rst b/doctrine.rst index f44a1c36ff1..e5707f59f33 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -279,21 +279,22 @@ This adds the new ``description`` property and ``getDescription()`` and ``setDes methods: .. code-block:: diff + :dedent: 0 - // src/Entity/Product.php - // ... + // src/Entity/Product.php + // ... - class Product - { - // ... + class Product + { + // ... + /** + * @ORM\Column(type="text") + */ + private $description; - // getDescription() & setDescription() were also added - } + // getDescription() & setDescription() were also added + } The new property is mapped, but it doesn't exist yet in the ``product`` table. No problem! Generate a new migration: diff --git a/frontend/encore/cdn.rst b/frontend/encore/cdn.rst index a7a2884c13a..f0d648d1ffe 100644 --- a/frontend/encore/cdn.rst +++ b/frontend/encore/cdn.rst @@ -5,16 +5,17 @@ Are you deploying to a CDN? That's awesome :) Once you've made sure that your built files are uploaded to the CDN, configure it in Encore: .. code-block:: diff + :dedent: 0 - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - .setOutputPath('public/build/') - // in dev mode, don't use the CDN - .setPublicPath('/build'); - // ... - ; + Encore + .setOutputPath('public/build/') + // in dev mode, don't use the CDN + .setPublicPath('/build'); + // ... + ; + if (Encore.isProduction()) { + Encore.setPublicPath('https://my-cool-app.com.global.prod.fastly.net'); diff --git a/frontend/encore/copy-files.rst b/frontend/encore/copy-files.rst index 28e8f26d80a..5925450afd5 100644 --- a/frontend/encore/copy-files.rst +++ b/frontend/encore/copy-files.rst @@ -31,12 +31,13 @@ Webpack - like a template - you can use the ``copyFiles()`` method to copy those files into your final output directory. .. code-block:: diff + :dedent: 0 - // webpack.config.js + // webpack.config.js - Encore - // ... - .setOutputPath('public/build/') + Encore + // ... + .setOutputPath('public/build/') + .copyFiles({ + from: './assets/images', diff --git a/frontend/encore/custom-loaders-plugins.rst b/frontend/encore/custom-loaders-plugins.rst index 66ce1f7c5cc..967129d226d 100644 --- a/frontend/encore/custom-loaders-plugins.rst +++ b/frontend/encore/custom-loaders-plugins.rst @@ -49,15 +49,16 @@ via the ``addPlugin()`` method. For example, if you use `Moment.js`_, you might to use the `IgnorePlugin`_ (see `moment/moment#2373`_): .. code-block:: diff + :dedent: 0 - // webpack.config.js + // webpack.config.js + var webpack = require('webpack'); - Encore - // ... + Encore + // ... + .addPlugin(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)) - ; + ; .. _`handlebars-loader`: https://github.com/pcardune/handlebars-loader .. _`plugins`: https://webpack.js.org/plugins/ diff --git a/frontend/encore/dev-server.rst b/frontend/encore/dev-server.rst index b1f72e5996b..d0c6fcbbbf3 100644 --- a/frontend/encore/dev-server.rst +++ b/frontend/encore/dev-server.rst @@ -65,13 +65,14 @@ you'll need to also tell the dev-server to use HTTPS. To do this, you can reuse server SSL certificate: .. code-block:: diff + :dedent: 0 - // webpack.config.js - // ... + // webpack.config.js + // ... + const path = require('path'); - Encore - // ... + Encore + // ... + .configureDevServerOptions(options => { + options.https = { diff --git a/frontend/encore/faq.rst b/frontend/encore/faq.rst index c6c6d86c257..6999fd424c4 100644 --- a/frontend/encore/faq.rst +++ b/frontend/encore/faq.rst @@ -62,12 +62,13 @@ If your app does not live at the root of your web server (i.e. it lives under a like ``/myAppSubdir``), you will need to configure that when calling ``Encore.setPublicPath()``: .. code-block:: diff + :dedent: 0 - // webpack.config.js - Encore - // ... + // webpack.config.js + Encore + // ... - .setOutputPath('public/build/') + .setOutputPath('public/build/') - .setPublicPath('/build') + // this is your *true* public path @@ -76,7 +77,7 @@ like ``/myAppSubdir``), you will need to configure that when calling ``Encore.se + // this is now needed so that your manifest.json keys are still `build/foo.js` + // (which is a file that's used by Symfony's `asset()` function) + .setManifestKeyPrefix('build') - ; + ; If you're using the ``encore_entry_script_tags()`` and ``encore_entry_link_tags()`` Twig shortcuts (or are :ref:`processing your assets through entrypoints.json ` diff --git a/frontend/encore/legacy-applications.rst b/frontend/encore/legacy-applications.rst index 4f1193d7e06..5660de4cd27 100644 --- a/frontend/encore/legacy-applications.rst +++ b/frontend/encore/legacy-applications.rst @@ -31,11 +31,12 @@ jQuery plugins often expect that jQuery is already available via the ``$`` or ``webpack.config.js`` file: .. code-block:: diff + :dedent: 0 - Encore - // ... + Encore + // ... + .autoProvidejQuery() - ; + ; After restarting Encore, Webpack will look for all uninitialized ``$`` and ``jQuery`` variables and automatically require ``jquery`` and set those variables for you. @@ -73,9 +74,10 @@ For example, in your ``app.js`` file that's processed by Webpack and loaded on e page, add: .. code-block:: diff + :dedent: 0 - // require jQuery normally - const $ = require('jquery'); + // require jQuery normally + const $ = require('jquery'); + // create global $ and jQuery variables + global.$ = global.jQuery = $; diff --git a/frontend/encore/postcss.rst b/frontend/encore/postcss.rst index d2322b14032..8d9a76d3ca1 100644 --- a/frontend/encore/postcss.rst +++ b/frontend/encore/postcss.rst @@ -27,13 +27,14 @@ Next, create a ``postcss.config.js`` file at the root of your project: Then, enable the loader in Encore! .. code-block:: diff + :dedent: 0 - // webpack.config.js + // webpack.config.js - Encore - // ... + Encore + // ... + .enablePostCssLoader() - ; + ; Because you just modified ``webpack.config.js``, stop and restart Encore. @@ -41,19 +42,20 @@ That's it! The ``postcss-loader`` will now be used for all CSS, Sass, etc files. You can also pass options to the `postcss-loader`_ by passing a callback: .. code-block:: diff + :dedent: 0 - // webpack.config.js + // webpack.config.js + const path = require('path'); - Encore - // ... + Encore + // ... + .enablePostCssLoader((options) => { + options.postcssOptions = { + // the directory where the postcss.config.js file is stored + config: path.resolve(__dirname, 'sub-dir', 'custom.config.js'), + }; + }) - ; + ; .. _browserslist_package_config: @@ -65,26 +67,28 @@ support. The best-practice is to configure this directly in your ``package.json` (so that all the tools can read this): .. code-block:: diff + :dedent: 0 - { + { + "browserslist": [ + "defaults" + ] - } + } The ``defaults`` option is recommended for most users and would be equivalent to the following browserslist: .. code-block:: diff + :dedent: 0 - { + { + "browserslist": [ + "> 0.5%", + "last 2 versions", + "Firefox ESR", + "not dead" + ] - } + } See `browserslist`_ for more details on the syntax. diff --git a/frontend/encore/reactjs.rst b/frontend/encore/reactjs.rst index ca3b017f13b..f7dd21096c6 100644 --- a/frontend/encore/reactjs.rst +++ b/frontend/encore/reactjs.rst @@ -16,14 +16,15 @@ Using React? First add some dependencies with Yarn: Enable react in your ``webpack.config.js``: .. code-block:: diff + :dedent: 0 - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - // ... + Encore + // ... + .enableReactPreset() - ; + ; Then restart Encore. When you do, it will give you a command you can run to diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index cda018f36e8..65a34b95bfa 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -166,9 +166,10 @@ We'll use jQuery to print this message on the page. Install it via: Great! Use ``import`` to import ``jquery`` and ``greet.js``: .. code-block:: diff + :dedent: 0 - // assets/app.js - // ... + // assets/app.js + // ... + // loads the jquery package from node_modules + import jquery from 'jquery'; @@ -208,14 +209,15 @@ etc.). To handle this, create a new "entry" JavaScript file for each page: Next, use ``addEntry()`` to tell Webpack to read these two new files when it builds: .. code-block:: diff + :dedent: 0 - // webpack.config.js - Encore - // ... - .addEntry('app', './assets/app.js') + // webpack.config.js + Encore + // ... + .addEntry('app', './assets/app.js') + .addEntry('checkout', './assets/checkout.js') + .addEntry('account', './assets/account.js') - // ... + // ... And because you just changed the ``webpack.config.js`` file, make sure to stop and restart Encore: @@ -232,9 +234,10 @@ Finally, include the ``script`` and ``link`` tags on the individual pages where you need them: .. code-block:: diff + :dedent: 0 - {# templates/.../checkout.html.twig #} - {% extends 'base.html.twig' %} + {# templates/.../checkout.html.twig #} + {% extends 'base.html.twig' %} + {% block stylesheets %} + {{ parent() }} @@ -262,21 +265,23 @@ CSS you can also use Sass, LESS or Stylus. To use Sass, rename the ``app.css`` file to ``app.scss`` and update the ``import`` statement: .. code-block:: diff + :dedent: 0 - // assets/app.js + // assets/app.js - import './styles/app.css'; + import './styles/app.scss'; Then, tell Encore to enable the Sass pre-processor: .. code-block:: diff + :dedent: 0 - // webpack.config.js - Encore - // ... + // webpack.config.js + Encore + // ... + .enableSassLoader() - ; + ; Because you just changed your ``webpack.config.js`` file, you'll need to restart Encore. When you do, you'll see an error! diff --git a/frontend/encore/split-chunks.rst b/frontend/encore/split-chunks.rst index 5569a9731f3..0582aab4f3f 100644 --- a/frontend/encore/split-chunks.rst +++ b/frontend/encore/split-chunks.rst @@ -9,15 +9,16 @@ into additional files, which will contain "shared" code. To enable this, call ``splitEntryChunks()``: .. code-block:: diff + :dedent: 0 - Encore - // ... + Encore + // ... - // multiple entry files, which probably import the same code - .addEntry('app', './assets/app.js') - .addEntry('homepage', './assets/homepage.js') - .addEntry('blog', './assets/blog.js') - .addEntry('store', './assets/store.js') + // multiple entry files, which probably import the same code + .addEntry('app', './assets/app.js') + .addEntry('homepage', './assets/homepage.js') + .addEntry('blog', './assets/blog.js') + .addEntry('store', './assets/store.js') + .splitEntryChunks() @@ -52,11 +53,12 @@ The logic for *when* and *how* to split the files is controlled by the this plugin with the ``configureSplitChunks()`` function: .. code-block:: diff + :dedent: 0 - Encore - // ... + Encore + // ... - .splitEntryChunks() + .splitEntryChunks() + .configureSplitChunks(function(splitChunks) { + // change the configuration + splitChunks.minSize = 0; diff --git a/frontend/encore/typescript.rst b/frontend/encore/typescript.rst index b1af45d9c04..73225d70acf 100644 --- a/frontend/encore/typescript.rst +++ b/frontend/encore/typescript.rst @@ -4,21 +4,22 @@ Enabling TypeScript (ts-loader) Want to use `TypeScript`_? No problem! First, enable it: .. code-block:: diff + :dedent: 0 - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - // ... + Encore + // ... + .addEntry('main', './assets/main.ts') + .enableTypeScriptLoader() - // optionally enable forked type script for faster builds - // https://www.npmjs.com/package/fork-ts-checker-webpack-plugin - // requires that you have a tsconfig.json file that is setup correctly. + // optionally enable forked type script for faster builds + // https://www.npmjs.com/package/fork-ts-checker-webpack-plugin + // requires that you have a tsconfig.json file that is setup correctly. + //.enableForkedTypeScriptTypesChecking() - ; + ; Then restart Encore. When you do, it will give you a command you can run to install any missing dependencies. After running that command and restarting @@ -29,10 +30,11 @@ also configure the `ts-loader options`_ via the ``enableTypeScriptLoader()`` method. .. code-block:: diff + :dedent: 0 - Encore - // ... - .addEntry('main', './assets/main.ts') + Encore + // ... + .addEntry('main', './assets/main.ts') - .enableTypeScriptLoader() + .enableTypeScriptLoader(function(tsConfig) { @@ -42,8 +44,8 @@ method. + // tsConfig.silent = false + }) - // ... - ; + // ... + ; See the `Encore's index.js file`_ for detailed documentation and check out the `tsconfig.json reference`_ and the `Webpack guide about Typescript`_. diff --git a/frontend/encore/versioning.rst b/frontend/encore/versioning.rst index 1f3d0cdd39e..2e7559f585c 100644 --- a/frontend/encore/versioning.rst +++ b/frontend/encore/versioning.rst @@ -11,13 +11,14 @@ instead of ``app.js``). This allows you to use aggressive caching strategies ignoring any existing cache: .. code-block:: diff + :dedent: 0 - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - .setOutputPath('public/build/') - // ... + Encore + .setOutputPath('public/build/') + // ... + .enableVersioning() To link to these assets, Encore creates two files ``entrypoints.json`` and diff --git a/frontend/encore/virtual-machine.rst b/frontend/encore/virtual-machine.rst index 068d5c8451f..f365c42f132 100644 --- a/frontend/encore/virtual-machine.rst +++ b/frontend/encore/virtual-machine.rst @@ -48,15 +48,16 @@ If your Symfony application is running on a custom domain (e.g. ``package.json``: .. code-block:: diff + :dedent: 0 - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server", + "dev-server": "encore dev-server --public http://app.vm:8080", - ... - } - } + ... + } + } After restarting Encore and reloading your web page, you will probably see different issues in the web console: @@ -77,15 +78,16 @@ Add the ``--host 0.0.0.0`` argument to the ``dev-server`` configuration in your connections: .. code-block:: diff + :dedent: 0 - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server --public http://app.vm:8080", + "dev-server": "encore dev-server --public http://app.vm:8080 --host 0.0.0.0", - ... - } - } + ... + } + } .. caution:: @@ -99,15 +101,16 @@ Webpack will respond ``Invalid Host header`` when trying to access files from the dev-server. To fix this, add the argument ``--disable-host-check``: .. code-block:: diff + :dedent: 0 - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server --public http://app.vm:8080 --host 0.0.0.0", + "dev-server": "encore dev-server --public http://app.vm:8080 --host 0.0.0.0 --disable-host-check", - ... - } - } + ... + } + } .. caution:: diff --git a/frontend/encore/vuejs.rst b/frontend/encore/vuejs.rst index eb8e2793c82..327a397ae04 100644 --- a/frontend/encore/vuejs.rst +++ b/frontend/encore/vuejs.rst @@ -9,16 +9,17 @@ Enabling Vue.js (``vue-loader``) Want to use `Vue.js`_? No problem! First enable it in ``webpack.config.js``: .. code-block:: diff + :dedent: 0 - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - // ... - .addEntry('main', './assets/main.js') + Encore + // ... + .addEntry('main', './assets/main.js') + .enableVueLoader() - ; + ; Then restart Encore. When you do, it will give you a command you can run to install any missing dependencies. After running that command and restarting @@ -84,19 +85,20 @@ You can enable `JSX with Vue.js`_ by configuring the second parameter of the ``.enableVueLoader()`` method: .. code-block:: diff + :dedent: 0 - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - // ... - .addEntry('main', './assets/main.js') + Encore + // ... + .addEntry('main', './assets/main.js') - .enableVueLoader() + .enableVueLoader(() => {}, { + useJsx: true + }) - ; + ; Next, run or restart Encore. When you do, you will see an error message helping you install any missing dependencies. After running that command and restarting diff --git a/http_cache.rst b/http_cache.rst index ca0ccf85e9f..c64e07b181a 100644 --- a/http_cache.rst +++ b/http_cache.rst @@ -92,21 +92,22 @@ Modify the code of your front controller to wrap the default kernel into the caching kernel: .. code-block:: diff + :dedent: 0 - // public/index.php + // public/index.php + use App\CacheKernel; - use App\Kernel; + use App\Kernel; - // ... - $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); + // ... + $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); + // Wrap the default Kernel with the CacheKernel one in 'prod' environment + if ('prod' === $kernel->getEnvironment()) { + $kernel = new CacheKernel($kernel); + } - $request = Request::createFromGlobals(); - // ... + $request = Request::createFromGlobals(); + // ... The caching kernel will immediately act as a reverse proxy: caching responses from your application and returning them to the client. diff --git a/logging/channels_handlers.rst b/logging/channels_handlers.rst index 8f6e9aed98a..101c8ad57c2 100644 --- a/logging/channels_handlers.rst +++ b/logging/channels_handlers.rst @@ -189,11 +189,12 @@ For example to inject the service related to the ``app`` logger channel, change your constructor like this: .. code-block:: diff + :dedent: 0 - public function __construct(LoggerInterface $logger) + public function __construct(LoggerInterface $appLogger) - { - $this->logger = $appLogger; - } + { + $this->logger = $appLogger; + } .. _`MonologBundle`: https://github.com/symfony/monolog-bundle diff --git a/mailer.rst b/mailer.rst index ed2e0ccf041..75f5340ea91 100644 --- a/mailer.rst +++ b/mailer.rst @@ -646,16 +646,17 @@ explained in the previous sections or the ``textTemplate()`` method provided by the ``TemplatedEmail`` class: .. code-block:: diff + :dedent: 0 + use Symfony\Bridge\Twig\Mime\TemplatedEmail; - $email = (new TemplatedEmail()) - // ... + $email = (new TemplatedEmail()) + // ... - ->htmlTemplate('emails/signup.html.twig') + ->htmlTemplate('emails/signup.html.twig') + ->textTemplate('emails/signup.txt.twig') - // ... - ; + // ... + ; .. _mailer-twig-embedding-images: diff --git a/page_creation.rst b/page_creation.rst index 0d7ff3e910b..e8aea943a89 100644 --- a/page_creation.rst +++ b/page_creation.rst @@ -104,22 +104,23 @@ routes. To do this, install the annotations package: You can now add your route directly *above* the controller: .. code-block:: diff + :dedent: 0 - // src/Controller/LuckyController.php + // src/Controller/LuckyController.php - // ... + // ... + use Symfony\Component\Routing\Annotation\Route; - class LuckyController - { + class LuckyController + { + /** + * @Route("/lucky/number") + */ - public function number() - { - // this looks exactly the same - } - } + public function number() + { + // this looks exactly the same + } + } That's it! The page - http://localhost:8000/lucky/number will work exactly like before! Annotations are the recommended way to configure routes. @@ -208,17 +209,18 @@ Make sure that ``LuckyController`` extends Symfony's base :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController` class: .. code-block:: diff + :dedent: 0 - // src/Controller/LuckyController.php + // src/Controller/LuckyController.php - // ... + // ... + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; - class LuckyController + class LuckyController extends AbstractController - { - // ... - } + { + // ... + } Now, use the handy ``render()`` function to render a template. Pass it a ``number`` variable so you can use it in Twig:: diff --git a/quick_tour/flex_recipes.rst b/quick_tour/flex_recipes.rst index 435b4f07351..503b461d0e3 100644 --- a/quick_tour/flex_recipes.rst +++ b/quick_tour/flex_recipes.rst @@ -74,29 +74,30 @@ Twig: Rendering a Template Thanks to Flex, after one command, you can start using Twig immediately: .. code-block:: diff + :dedent: 0 - render('default/index.html.twig', [ - + 'name' => $name, - + ]); - } - } + - class DefaultController + + class DefaultController extends AbstractController + { + /** + * @Route("/hello/{name}") + */ + public function index($name) + { + - return new Response("Hello $name!"); + + return $this->render('default/index.html.twig', [ + + 'name' => $name, + + ]); + } + } By extending ``AbstractController``, you now have access to a number of shortcut methods and tools, like ``render()``. Create the new template: diff --git a/quick_tour/the_architecture.rst b/quick_tour/the_architecture.rst index e3b388a0bc4..e529ada972b 100644 --- a/quick_tour/the_architecture.rst +++ b/quick_tour/the_architecture.rst @@ -134,13 +134,14 @@ Yes! You can use autowiring inside a service to access *other* services. The onl difference is that it's done in the constructor: .. code-block:: diff + :dedent: 0 - logger = $logger; + } - public function getRandomGreeting() - { - // ... + public function getRandomGreeting() + { + // ... + $this->logger->info('Using the greeting: '.$greeting); - return $greeting; - } - } + return $greeting; + } + } Yes! This works too: no configuration, no time wasted. Keep coding! @@ -275,8 +276,9 @@ Oh, how do you change the environment? Change the ``APP_ENV`` environment variab from ``dev`` to ``prod``: .. code-block:: diff + :dedent: 0 - # .env + # .env - APP_ENV=dev + APP_ENV=prod @@ -317,11 +319,12 @@ your app needs a database ORM. Let's install the Doctrine ORM: Thanks to a new recipe installed by Flex, look at the ``.env`` file again: .. code-block:: diff + :dedent: 0 - ###> symfony/framework-bundle ### - APP_ENV=dev - APP_SECRET=cc86c7ca937636d5ddf1b754beb22a10 - ###< symfony/framework-bundle ### + ###> symfony/framework-bundle ### + APP_ENV=dev + APP_SECRET=cc86c7ca937636d5ddf1b754beb22a10 + ###< symfony/framework-bundle ### + ###> doctrine/doctrine-bundle ### + # ... diff --git a/quick_tour/the_big_picture.rst b/quick_tour/the_big_picture.rst index 4fae7ef5991..33d9c5f26a1 100644 --- a/quick_tour/the_big_picture.rst +++ b/quick_tour/the_big_picture.rst @@ -104,33 +104,35 @@ a full HTML page. But the routing system is *much* more powerful. So let's make the route more interesting: .. code-block:: diff + :dedent: 0 - # config/routes.yaml - index: + # config/routes.yaml + index: - path: / + path: /hello/{name} - controller: 'App\Controller\DefaultController::index' + controller: 'App\Controller\DefaultController::index' The URL to this page has changed: it is *now* ``/hello/*``: the ``{name}`` acts like a wildcard that matches anything. And it gets better! Update the controller too: .. code-block:: diff + :dedent: 0 - passwordEncoder = $passwordEncoder; + } - public function load(ObjectManager $manager) - { - $user = new User(); - // ... + public function load(ObjectManager $manager) + { + $user = new User(); + // ... + $user->setPassword($this->passwordEncoder->encodePassword( + $user, + 'the_new_password' + )); - // ... - } - } + // ... + } + } You can manually encode a password by running: @@ -834,9 +835,10 @@ Thanks to the SensioFrameworkExtraBundle, you can also secure your controller using annotations: .. code-block:: diff + :dedent: 0 - // src/Controller/AdminController.php - // ... + // src/Controller/AdminController.php + // ... + use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; @@ -845,18 +847,18 @@ using annotations: + * + * @IsGranted("ROLE_ADMIN") + */ - class AdminController extends AbstractController - { + class AdminController extends AbstractController + { + /** + * Require ROLE_ADMIN for only this controller method. + * + * @IsGranted("ROLE_ADMIN") + */ - public function adminDashboard() - { - // ... - } - } + public function adminDashboard() + { + // ... + } + } For more information, see the `FrameworkExtraBundle documentation`_. diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index 1d269eba380..53952be1508 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -380,18 +380,19 @@ whole process works. You will *at least* need to fill in *where* you want your u be redirected after success: .. code-block:: diff + :dedent: 0 - // src/Security/LoginFormAuthenticator.php + // src/Security/LoginFormAuthenticator.php - // ... - public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) - { - // ... + // ... + public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) + { + // ... - throw new \Exception('TODO: provide a valid redirect inside '.__FILE__); + // redirect to some "app_homepage" route - of wherever you want + return new RedirectResponse($this->urlGenerator->generate('app_homepage')); - } + } Unless you have any other TODOs in that file, that's it! If you're loading users from the database, make sure you've loaded some :ref:`dummy users `. diff --git a/security/guard_authentication.rst b/security/guard_authentication.rst index 99d86c6c781..e8e64a39206 100644 --- a/security/guard_authentication.rst +++ b/security/guard_authentication.rst @@ -31,23 +31,24 @@ create your ``User`` class. Then add an ``apiToken`` property directly to your ``User`` class (the ``make:entity`` command is a good way to do this): .. code-block:: diff + :dedent: 0 - // src/Entity/User.php - namespace App\Entity; + // src/Entity/User.php + namespace App\Entity; - // ... + // ... - class User implements UserInterface - { - // ... + class User implements UserInterface + { + // ... + /** + * @ORM\Column(type="string", unique=true, nullable=true) + */ + private $apiToken; - // the getter and setter methods - } + // the getter and setter methods + } Don't forget to generate and run the migration: @@ -525,14 +526,15 @@ are two possible fixes: authenticated: .. code-block:: diff + :dedent: 0 - // src/Security/MyIpAuthenticator.php - // ... + // src/Security/MyIpAuthenticator.php + // ... + use Symfony\Component\Security\Core\Security; - class MyIpAuthenticator - { + class MyIpAuthenticator + { + private $security; + public function __construct(Security $security) @@ -540,8 +542,8 @@ are two possible fixes: + $this->security = $security; + } - public function supports(Request $request) - { + public function supports(Request $request) + { + // if there is already an authenticated user (likely due to the session) + // then return false and skip authentication: there is no need. + if ($this->security->getUser()) { @@ -550,8 +552,8 @@ are two possible fixes: + // the user is not logged in, so the authenticator should continue + return true; - } - } + } + } If you use autowiring, the ``Security`` service will automatically be passed to your authenticator. diff --git a/security/securing_services.rst b/security/securing_services.rst index 67b37dd792e..77462adad81 100644 --- a/security/securing_services.rst +++ b/security/securing_services.rst @@ -13,15 +13,16 @@ service. For example, suppose you have a ``SalesReportManager`` service and you want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` role: .. code-block:: diff + :dedent: 0 - // src/Newsletter/NewsletterManager.php + // src/Newsletter/NewsletterManager.php - // ... - use Symfony\Component\Security\Core\Exception\AccessDeniedException; + // ... + use Symfony\Component\Security\Core\Exception\AccessDeniedException; + use Symfony\Component\Security\Core\Security; - class SalesReportManager - { + class SalesReportManager + { + private $security; + public function __construct(Security $security) @@ -29,19 +30,19 @@ want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` ro + $this->security = $security; + } - public function sendNewsletter() - { - $salesData = []; + public function sendNewsletter() + { + $salesData = []; + if ($this->security->isGranted('ROLE_SALES_ADMIN')) { + $salesData['top_secret_numbers'] = rand(); + } - // ... - } + // ... + } - // ... - } + // ... + } If you're using the :ref:`default services.yaml configuration `, Symfony will automatically pass the ``security.helper`` to your service diff --git a/service_container.rst b/service_container.rst index 98fb5e61318..68287f11504 100644 --- a/service_container.rst +++ b/service_container.rst @@ -362,35 +362,36 @@ But there are a few cases when an argument to a service cannot be autowired. For example, suppose you want to make the admin email configurable: .. code-block:: diff + :dedent: 0 - // src/Service/SiteUpdateManager.php - // ... + // src/Service/SiteUpdateManager.php + // ... - class SiteUpdateManager - { - // ... + class SiteUpdateManager + { + // ... + private $adminEmail; - public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer) + public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer, string $adminEmail) - { - // ... + { + // ... + $this->adminEmail = $adminEmail; - } + } - public function notifyOfSiteUpdate(): bool - { - // ... + public function notifyOfSiteUpdate(): bool + { + // ... - $email = (new Email()) - // ... + $email = (new Email()) + // ... - ->to('manager@example.com') + ->to($this->adminEmail) - // ... - ; - // ... - } - } + // ... + ; + // ... + } + } If you make this change and refresh, you'll see an error: diff --git a/setup/flex.rst b/setup/flex.rst index 52708275077..df4d3442b93 100644 --- a/setup/flex.rst +++ b/setup/flex.rst @@ -57,15 +57,16 @@ manual steps: it will not be installed again: .. code-block:: diff - - { - "require": { - "symfony/flex": "^1.0", - + }, - + "conflict": { - + "symfony/symfony": "*" - } - } + :dedent: 0 + + { + "require": { + "symfony/flex": "^1.0", + + }, + + "conflict": { + + "symfony/symfony": "*" + } + } Now you must add in ``composer.json`` all the Symfony dependencies required by your project. A quick way to do that is to add all the components that diff --git a/setup/unstable_versions.rst b/setup/unstable_versions.rst index 5e11526b20e..881477c5d6a 100644 --- a/setup/unstable_versions.rst +++ b/setup/unstable_versions.rst @@ -32,15 +32,16 @@ project. Then, edit the value of all of the ``symfony/*`` libraries to the new version and change your ``minimum-stability`` to ``beta``: .. code-block:: diff + :dedent: 0 - { - "require": { + { + "require": { + "symfony/framework-bundle": "^4.0", + "symfony/finder": "^4.0", - "...": "..." - }, + "...": "..." + }, + "minimum-stability": "beta" - } + } You can also use set ``minimum-stability`` to ``dev``, or omit this line entirely, and opt into your stability on each package by using constraints diff --git a/setup/upgrade_major.rst b/setup/upgrade_major.rst index 89f80ae109f..7b0d2117376 100644 --- a/setup/upgrade_major.rst +++ b/setup/upgrade_major.rst @@ -130,41 +130,43 @@ Composer by modifying your ``composer.json`` file and changing all the libraries starting with ``symfony/`` to the new major version: .. code-block:: diff + :dedent: 0 - { - "...": "...", + { + "...": "...", - "require": { + "require": { - "symfony/cache": "4.4.*", + "symfony/cache": "5.0.*", - "symfony/config": "4.4.*", + "symfony/config": "5.0.*", - "symfony/console": "4.4.*", + "symfony/console": "5.0.*", - "...": "...", + "...": "...", - "...": "A few libraries starting with - symfony/ follow their own versioning scheme. You - do not need to update these versions: you can - upgrade them independently whenever you want", - "symfony/monolog-bundle": "^3.5", - }, - "...": "...", - } + "...": "A few libraries starting with + symfony/ follow their own versioning scheme. You + do not need to update these versions: you can + upgrade them independently whenever you want", + "symfony/monolog-bundle": "^3.5", + }, + "...": "...", + } At the bottom of your ``composer.json`` file, in the ``extra`` block you can find a data setting for the Symfony version. Make sure to also upgrade this one. For instance, update it to ``5.0.*`` to upgrade to Symfony 5.0: .. code-block:: diff + :dedent: 0 - "extra": { - "symfony": { - "allow-contrib": false, + "extra": { + "symfony": { + "allow-contrib": false, - "require": "4.4.*" + "require": "5.0.*" - } - } + } + } Next, use Composer to download new versions of the libraries: diff --git a/setup/upgrade_minor.rst b/setup/upgrade_minor.rst index 09a88124fa8..99059813559 100644 --- a/setup/upgrade_minor.rst +++ b/setup/upgrade_minor.rst @@ -27,40 +27,42 @@ probably need to update the version constraint next to each library starting ``symfony/``. Suppose you are upgrading from Symfony 4.3 to 4.4: .. code-block:: diff + :dedent: 0 - { - "...": "...", + { + "...": "...", - "require": { + "require": { - "symfony/cache": "4.3.*", + "symfony/cache": "4.4.*", - "symfony/config": "4.3.*", + "symfony/config": "4.4.*", - "symfony/console": "4.3.*", + "symfony/console": "4.4.*", - "...": "...", + "...": "...", - "...": "A few libraries starting with - symfony/ follow their versioning scheme. You - do not need to update these versions: you can - upgrade them independently whenever you want", - "symfony/monolog-bundle": "^3.5", - }, - "...": "...", - } + "...": "A few libraries starting with + symfony/ follow their versioning scheme. You + do not need to update these versions: you can + upgrade them independently whenever you want", + "symfony/monolog-bundle": "^3.5", + }, + "...": "...", + } Your ``composer.json`` file should also have an ``extra`` block that you will *also* need to update: .. code-block:: diff + :dedent: 0 - "extra": { - "symfony": { - "...": "...", + "extra": { + "symfony": { + "...": "...", - "require": "4.3.*" + "require": "4.4.*" - } - } + } + } Next, use Composer to download new versions of the libraries: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy