If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeOk, remember our goal: to move our code - which mostly lives in config/
- into the new directory structure.
The next section is doctrine
... and there's nothing special here: this is the default config from Symfony 3. Compare this with config/packages/doctrine.yaml
. If you look closely, they're almost the same - but with a few improvements!
Instead of having multiple config entries for the database host, username and password, it's all combined into one url
. The DATABASE_URL
environment variable is waiting to be configured in the .env
file.
But there is one important difference: mappings
. In a Flex project, we expect your entities to live in src/Entity
. But currently, our classes live in src/AppBundle/Entity
.
And yes yes, we are going to move them... eventually. But let's pretend like moving them is too big of a change right now: I want to make my files work where they are. How can we do that? Add a second mapping! This one will look in the src/AppBundle/Entity
directory for classes that start with AppBundle\Entity
. Update the alias to AppBundle
- that's what lets you say AppBundle:Genus
.
... lines 1 - 7 | |
doctrine: | |
... lines 9 - 16 | |
orm: | |
... lines 18 - 20 | |
mappings: | |
... lines 22 - 27 | |
AppBundle: | |
is_bundle: false | |
type: annotation | |
dir: '%kernel.project_dir%/src/AppBundle/Entity' | |
prefix: 'AppBundle\Entity' | |
alias: AppBundle |
Simple & explicit. I love it! Go delete the old doctrine
config!
The last two sections are for doctrine_cache
and stof_doctrine_extensions
. Both bundles are installed, so we just need to move the config. Huh, but the DoctrineCacheBundle did not create a config file. That's normal: some bundles don't need configuration, so their recipes don't add a file. Create it manually: doctrine_cache.yaml
. And move all the config into it.
doctrine_cache: | |
providers: | |
my_markdown_cache: | |
type: '%cache_type%' | |
file_system: | |
directory: '%kernel.cache_dir%/markdown_cache' |
All of the files in this directory are automatically loaded, so we don't need to do anything else.
Then, for stof_doctrine_extensions
, it does have a config file, but we need to paste our custom config at the bottom.
... lines 1 - 2 | |
stof_doctrine_extensions: | |
... line 4 | |
orm: | |
default: | |
sluggable: true |
And... that's it! Delete config.yml
. Victory!
Close a few files, but keep the new services.yaml
open... because this is our next target! Open the old services.yml
file. This has the normal autowiring and auto-registration stuff, as well as some aliases and custom service wiring.
Because we're not going to move our classes out of AppBundle yet, we need to continue to register those classes as services. But in the new file, to get things working, we explicitly excluded the AppBundle
directory, because those classes do not have the App\
namespace.
No problem! Copy the 2 auto-registration sections from services.yml
and paste them into the new file. And I'll add a comment: when we eventually move everything out of AppBundle, we can delete this. Change the paths: we're now one level less deep.
... lines 1 - 6 | |
services: | |
... lines 8 - 27 | |
# REMOVE when AppBundle is removed | |
AppBundle\: | |
resource: '../src/AppBundle/*' | |
# you can exclude directories or files | |
# but if a service is unused, it's removed anyway | |
exclude: '../src/AppBundle/{Entity,Repository}' | |
AppBundle\Controller\: | |
resource: '../src/AppBundle/Controller' | |
public: true | |
tags: ['controller.service_arguments'] | |
# END REMOVE | |
... lines 39 - 68 |
Next, copy the existing aliases and services and paste them into the new file.
... lines 1 - 6 | |
services: | |
... lines 8 - 39 | |
# add more service definitions when explicit configuration is needed | |
# please note that last definitions always *replace* previous ones | |
Knp\Bundle\MarkdownBundle\MarkdownParserInterface: '@markdown.parser' | |
Doctrine\ORM\EntityManager: '@doctrine.orm.default_entity_manager' | |
AppBundle\Service\MarkdownTransformer: | |
arguments: | |
$cacheDriver: '@doctrine_cache.providers.my_markdown_cache' | |
AppBundle\Doctrine\HashPasswordListener: | |
tags: [doctrine.event_subscriber] | |
AppBundle\Form\TypeExtension\HelpFormExtension: | |
tags: | |
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType } | |
AppBundle\Service\MessageManager: | |
arguments: | |
- ['You can do it!', 'Dude, sweet!', 'Woot!'] | |
- ['We are *never* going to figure this out', 'Why even try again?', 'Facepalm'] | |
AppBundle\EventSubscriber\AddNiceHeaderEventSubscriber: | |
arguments: | |
$showDiscouragingMessage: true | |
# example of adding aliases, if one does not exist | |
# Symfony\Component\Security\Guard\GuardAuthenticatorHandler: '@security.authentication.guard_handler' |
And... ready? Delete services.yml
! That was a big step! Suddenly, almost all of our existing code is being used: we just hooked our old code into the new app.
But, does it work! Maybe....? Try it!
./bin/console
Ah! Not quite: a class not found error from Symfony's Guard security component. Why? Because we haven't installed security yet! Let's do it:
composer require security
It downloads and then... another error! Interesting:
LoginFormAuthenticator contains 1 abstract method
Ah! I think we missed a deprecation warning, and now we're seeing a fatal error. Open AppBundle/Security/LoginFormAuthenticator.php
.
PhpStorm agrees: class must implement method onAuthenticationSuccess
. Let's walk through this change together. First, remove getDefaultSuccessRedirectUrl()
: that's not used anymore. Then, go to the Code->Generate menu - or Command+N on a Mac - select "Implement methods" and choose onAuthenticationSuccess
.
Previously, this method was handled by the base class for you. But now, it's your responsibility. No worries: it's pretty simple. To help, at the top, use a trait called TargetPathTrait
.
... lines 1 - 19 | |
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator | |
{ | |
use TargetPathTrait; | |
... lines 23 - 74 | |
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) | |
{ | |
... lines 77 - 81 | |
} | |
... lines 83 - 87 | |
} |
Back down in onAuthenticationSuccess
, this allows us to say if $targetPath = $this->getTargetPath()
with $request->getSession()
and main
.
... lines 1 - 19 | |
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator | |
{ | |
... lines 22 - 74 | |
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) | |
{ | |
if ($targetPath = $this->getTargetPath($request->getSession(), 'main')) { | |
... line 78 | |
} | |
... line 81 | |
} | |
... lines 83 - 87 | |
} |
Let's break this down. First, the main
string is just the name of our firewall. In both the old and new security config, that's its key.
Second, what does getTargetPath()
do? Well, suppose the user originally tried to go to /admin
, and then they were redirected to the login page. After they login, we should probably send them back to /admin
, right? The getTargetPath()
method returns the URL that the user originally tried to access, if any.
So if there is a target path, return new RedirectResponse($targetPath)
. Else, return new RedirectResponse
and generate a URL to the homepage.
... lines 1 - 19 | |
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator | |
{ | |
... lines 22 - 74 | |
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) | |
{ | |
if ($targetPath = $this->getTargetPath($request->getSession(), 'main')) { | |
return new RedirectResponse($targetPath); | |
} | |
return new RedirectResponse($this->router->generate('homepage')); | |
} | |
... lines 83 - 87 | |
} |
PhpStorm thinks this isn't a real route, but it is!
Problem solved! Is that enough to make our app happy? Find out!
./bin/console
It is! But before we move on, we need to migrate the security config. Copy all of the old security.yml
, and completely replace the new security.yaml
. To celebrate, delete the old file!
... lines 1 - 2 | |
security: | |
encoders: | |
AppBundle\Entity\User: bcrypt | |
role_hierarchy: | |
ROLE_ADMIN: [ROLE_MANAGE_GENUS, ROLE_ALLOWED_TO_SWITCH] | |
... lines 9 - 14 | |
firewalls: | |
... lines 16 - 20 | |
main: | |
anonymous: ~ | |
guard: | |
authenticators: | |
- AppBundle\Security\LoginFormAuthenticator | |
logout: | |
path: /logout | |
switch_user: ~ | |
logout_on_user_change: true | |
... lines 31 - 38 | |
access_control: | |
# - { path: ^/admin, roles: ROLE_ADMIN } |
And... ah! We're super close. Only a few more files to deal with! By the end of the next chapter, our app/config/
directory will be gone!
Just posted this but it got marked as spam, so I'll try it again 😎
Moving from symfony 3 to 4 I started injecting the service according to this.
Most functions where I inject the "helper" service it works fine, but for some reason it fails on a few of them and I can't figure out what I've done differently... Here's the error:
Could not resolve argument $helper of
"App\Controller\Poslog\OperatorController::historyindividualaction()",
maybe you forgot to register the controller as a service or missed
tagging it with the "controller.service_arguments"?
I've omitted the contents if the functions completely as it doesn't matter what they contain, I can comment out the entire code inside the HistoryIndividualAction() and still get the exact same error message.
The OperatorController::newAction() below works perfectly fine (as well as a number of other functions within the same object), while the OperatorController::HistoryIndividualAction() fails.
use App\Service\globalHelper as globalHelper;
...
class OperatorController extends AbstractController
{
public function newAction(Request $request, ACRGroup $ACRGroup = null, globalHelper $helper)
{
...
}
public function HistoryIndividualAction($operatorId, globalHelper $helper)
{
...
}
}
The routing looks like this
operator_new:
path: /new/{ACRGroup}
defaults: { _controller: App\Controller\Poslog\OperatorController::newAction, ACRGroup: null }
methods: [GET, POST]
operator_history_individual:
path: /history/individual/{operatorId}
defaults: { _controller: App\Controller\Poslog\OperatorController::historyIndividualAction }
methods: GET
Services.yml
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
globalHelper:
class: App\Service\globalHelper
public: false
arguments: ['@service_container', '@doctrine.orm.entity_manager']
GlobalHelper starts out like this:
namespace App\Service;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
//use Doctrine\ORM\EntityManager as EntityManager; //gave deprecation notice, profiler suggested to change to below and the deprecation notice disappeared.
use Doctrine\ORM\EntityManagerInterface as EntityManager;
class globalHelper {
private $container;
private $em;
public function __construct(Container $container, EntityManager $em) {
$this->container = $container;
$this->em = $em;
}
Just posted a question (below). I went to format it a little nicer (adding the PRE tags to the code blocks) and then it got marked as SPAM for some reason...
Moving from symfony 3 to 4 I started injecting the service according to this.
Most functions where I inject the "helper" service it works fine, but for some reason it fails on a few of them and I can't figure out what I've done differently... Here's the error:
<blockquote>Could not resolve argument $helper of "App\Controller\Poslog\OperatorController::historyindividualaction()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?</blockquote>
I've omitted the contents if the functions completely as it doesn't matter what they contain, I can comment out the entire code inside the HistoryIndividualAction() and still get the exact same error message.
The OperatorController::newAction() below works perfectly fine (as well as a number of other functions within the same object), while the OperatorController::HistoryIndividualAction() fails.
use App\Service\globalHelper as globalHelper;
...
class OperatorController extends AbstractController
{
public function newAction(Request $request, ACRGroup $ACRGroup = null, globalHelper $helper)
{
...
}
public function HistoryIndividualAction($operatorId, globalHelper $helper)
{
...
}
The routing looks like this
operator_new:
path: /new/{ACRGroup}
defaults: { _controller: App\Controller\Poslog\OperatorController::newAction, ACRGroup: null }
methods: [GET, POST]
operator_history_individual:
path: /history/individual/{operatorId}
defaults: { _controller: App\Controller\Poslog\OperatorController::historyIndividualAction }
methods: GET```
Services.yml
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
globalHelper:
class: App\Service\globalHelper
public: false
arguments: ['@service_container', '@doctrine.orm.entity_manager']```
GlobalHelper starts out like this:
namespace App\Service;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
//use Doctrine\ORM\EntityManager as EntityManager; //gave deprecation notice, profiler suggested to change to below and the deprecation notice disappeared.
use Doctrine\ORM\EntityManagerInterface as EntityManager;
class globalHelper {
private $container;
private $em;
public function __construct(Container $container, EntityManager $em) {
$this->container = $container;
$this->em = $em;
}```
Hey Mattias,
This problem is unexpected, let's try a few things. First, capitalize your class name GlobalHelper
, double-check that the name of the class match the name of the file (this is just to be compliant with PSR-4)
Second, update your services.yaml
config. Change it to:
services:
...
App\Service\GlobalHelper:
public: false
arguments: ['@service_container', '@doctrine.orm.entity_manager']
We need the service ID to be the FQNS of the class
Give it a try and let me know. Oh, by the way, we use Disqus for the comments and it decided to mark your messages as a spam, possibly due to the length of the comment
Cheers!
Thank you - I found the solution. In the controller, the function name is with a leading capital "H"
public function HistoryIndividualAction
Whereas in the routing yaml file, it is written with a small leading "h"
defaults: { _controller: App\Controller\Poslog\OperatorController::historyIndividualAction }
Changing the routing to
defaults: { _controller: App\Controller\Poslog\OperatorController::HistoryIndividualAction }
fixed the problem =)
Hi, the video only shows a bundle called AppBundle but I have several bundles. Do I have to create a mapping for each bundle?
In a Symfony 3.4 project, I have several bundles in the src
directory. Each of these bundles has a services.yml
file and an DependencyInjection/Extension
class. Some also have a config.yml
file and a DependencyInjection/Configuration
class.
Now I'm trying to convert to Symfony 4.3.
Hey halifaxious
You can merge all your services.yml
files into config/services.yaml
, or just move them there config/
and tell the Kernel to load them:
// src/Kernel.php
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
...
$loader->load($confDir.'/services_bundleOne'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/services_bundleTwo'.self::CONFIG_EXTS, 'glob');
...
}
About config.yml
files, those are trickier because you will have to split the configuration into multiple files. For example, if in any of your config.yml
files you have something like this.
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
sluggable: true
timestampable: true
...
You have to copy the whole block stof_doctrine_extensions
and move it into config/packages/stof_doctrine_extensions.yaml
file
About your DependencyInjection
files you can just move them into src/DependencyInjection
and it should just work out of the box (just check for name collision)
- And more importantly, how do I deal with bundle configuration of these internal bundles when internal bundles aren't supposed to exist anymore?
What kind of configuration do you have?
Cheers!
My most problematic internal bundle is HazardBundle. Its services look like this:
HazardBundle\:
resource: '../src/HazardBundle/*'
exclude: '../src/HazardBundle/{Entity,Repository}'
HazardBundle\Controller\:
resource: '../src/HazardBundle/Controller'
public: true
tags: ['controller.service_arguments']
HazardBundle\Manager\PictogramManager:
arguments: ['%acrd_hazard.pictograms%']
There is a config file that I have moved to /config/packages/hazard.yaml
which is the source for the %acrd_hazard.pictograms%
parameter. The parameter is built in the HazardBundle/DependencyInjection/HazardExtension
class using the HazardBundle/DependencyInjection/Configuration
class as follows:
class HazardExtension extends Extension
{
const ALIAS = 'acrd_hazard';
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$fileLocator = new FileLocator(__DIR__.'/../Resources/config');
$configs[] = Yaml::parse(file_get_contents($fileLocator->locate('hazard.yml')));
$configuration = new Configuration();
$processedConfig = $this->processConfiguration($configuration, $configs);
$container->setParameter(self::ALIAS.'.pictograms', $processedConfig['hazard']['pictograms']);
$container->setParameter(self::ALIAS.'.GHS', $processedConfig['hazard']['GHS']);
$container->setParameter(self::ALIAS.'.icon_class_prefix', $processedConfig['hazard']['icon_class_prefix']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');
}
//etc.
}
The hazard.yaml
begins like this:
hazard:
icon_class_prefix: 'haz'
pictograms:
explosive:
title: 'pict.explosive'
//etc.
GHS:
//etc.
Before I moved hazard.yaml to /config/packages, my services file failed because the %acrd_hazard.pictogram% parameter was undefined. After I moved it, I got the error "There is no extension able to load the configuration for hazard". Moving HazardExtension
to src/DependencyInjection
does not change that.
What am I missing?
Ok, so your Extension is not being detected for some reason. Double check its namespace and it should extend from Symfony\Component\DependencyInjection\Extension\Extension
. Also it must live inside src/DepedencyInjection
folder
I hope it helps
Hi,
I must have skipped one page, I don't have the config/packages/doctrine.yaml file. I tried "composer require doctrine/doctrine-bundle" which added "doctrine/doctrine-bundle": "^1.9" in my composer.json but nothing else happens. What am I missing here ? How can I install Doctrine in my project ?
Thanks.
Edit : I found that I should use "require symfony/orm-pack" but the console answers "nothing to install or update"
Edit 2 : I deleted the vendor directory then re-ran (?) the previous command. Suddenly 83 installs, including doctrine, and "doctrine.yaml" is now in the packages directory (with several others - previously missing too - like google_recaptcha.yaml). All right, then, I can continue the migration ! I'll be back for many other questions ;)
Hey Jean-tilapin
I'm glad to hear that you could fix your problem, but I believe what happened was that for some reason the doctrine bundle recipe didn't get installed. When that happens, you can run composer fix-recipes
and if it was missing, it will install it for you :)
Cheers!
Hi !
I'm actually facing a really weird error, the problem is 99% due to me, but I'm stuck.
First my error is :
In FileLoader.php line 168:
Expected to find class "UTM\CoreBundle\Controller\CoreController" in file "C:\Users\legof\Documents\GitHub\utm-website\src\UTM/CoreBundle\Controller\CoreController.php" while importing services from resource "../src/UTM/*", but it was not found! Check the namespa
ce prefix used with the resource in C:\Users\legof\Documents\GitHub\utm-website\config/services.yaml (which is loaded in resource "C:\Users\legof\Documents\GitHub\utm-website\config/services.yaml").
But I checked it couple times, the file and the namespace are ok.
Here are my services.yaml and the CoreController.php file
locale: fr
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,UTM}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# REMOVE when AppBundle is removed
UTM\:
resource: '../src/UTM/*'
exclude: '../src/UTM/{Entity,Repository}'
UTM\Controller\:
resource: '../src/UTM/Controller'
public: true
tags: ['controller.service_arguments']
# END REMOVE
UTM\UserBundle\Security\LoginFormAuthenticator: ~
UTM\UserBundle\Security\UserProvider: ~
UTM\UserBundle\Mojang\MojangAPI: ~
UTM\UserBundle\Mojang\Uuid: ~
UTM\FactionBundle\Twig\Extension\FactionExtension: ~
namespace UTM\CoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class CoreController extends Controller
{
public function indexAction()
{
return $this->render('UTMCoreBundle:Core:index.html.twig');
}
}
Hey Hugo L.
I believe I found your problem, here:
UTM\Controller\:
resource: '../src/UTM/Controller'
you specified the folder ../src/UTM/Controller
, but it actually lives in: ../src/UTM/CoreBundle/Controller
, isn't it?
I think I clearly don't get the utility of the AppBundle lines in services.yaml. I guess it is loading my old code, but I at least don't get how doing it. In my project I have in src folder another folder called UTM where there is 6 bundles (CoreBundle, User Bundle...).
I tried to only load CoreBundle by making the changes you suggested to me but I was facing the same error.
So I removed the "AppBundle" block for the moment and it's working fine, but I guess it is the wrong way to do it.
It would be super cool if you quickly explain me how to do it properly.
Thank you very much !
EDIT:
Ok, I'm now moving my bundles into src, so maybe I do not need anymore those lines. Instead, I have another question, as I said, actually on my src folder I have a UTM folder where there is 6 bundles like this :
src
├───Controller
├───Entity
├───Repository
└───UTM
--├───CoreBundle
--├───FactionBundle
--├───ForumBundle
--├───LimitsBundle
--├───ShopBundle
--└───UserBundle
Now should I move all thoses bundles on src and rename them without the "Bundle" like this (and also remove the Controller, Entity and Repository folder) ?
src
├───Core
├───Faction
├───Forum
├───Limits
├───Shop
└───User
Thank you again
In Symfony4 there is no more a bundle structure, everything lives inside "src" folder (if you check composer.json you will notice that "App" namespace points to the "src" folder), so, yes, you have to move all your files living in bundles into the root of "src", but without deleting "Entity", "Controller", etc. folders, you just have to merge them
After moving the files, you have to double check that all your namespaces did change correctly, and fix any service configuration problem you may face (because all your classes will be automatically registered and configured as services)
Yes, that's what I figured out after this message, that's easier to use and manage at all.
Thank you !
// composer.json
{
"require": {
"php": "^7.1.3",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/doctrine-bundle": "^1.6", // 1.8.1
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.2
"doctrine/doctrine-migrations-bundle": "^1.1", // v1.3.1
"doctrine/orm": "^2.5", // v2.7.2
"fzaninotto/faker": "^1.7", // v1.7.1
"knplabs/knp-markdown-bundle": "^1.4", // 1.6.0
"sensio/framework-extra-bundle": "^5.0", // v5.1.3
"stof/doctrine-extensions-bundle": "dev-master", // dev-master
"symfony/asset": "^4.0", // v4.0.1
"symfony/console": "^4.0", // v4.0.1
"symfony/flex": "^1.0", // v1.9.10
"symfony/form": "^4.0", // v4.0.1
"symfony/framework-bundle": "^4.0", // v4.0.1
"symfony/lts": "^4@dev", // dev-master
"symfony/maker-bundle": "^1.0", // v1.0.2
"symfony/monolog-bundle": "^3.1", // v3.1.2
"symfony/polyfill-apcu": "^1.0", // v1.6.0
"symfony/profiler-pack": "^1.0", // v1.0.3
"symfony/security-bundle": "^4.0", // v4.0.1
"symfony/security-csrf": "^4.0",
"symfony/swiftmailer-bundle": "^3.1", // v3.1.6
"symfony/translation": "^4.0", // v4.0.1
"symfony/twig-bundle": "^4.0", // v4.0.1
"symfony/validator": "^4.0", // v4.0.1
"symfony/web-server-bundle": "^4.0", // v4.0.1
"symfony/yaml": "^4.0" // v4.0.1
},
"require-dev": {
"symfony/dotenv": "^4.0", // v4.0.1
"symfony/phpunit-bridge": "^4.0", // v4.0.1
"doctrine/doctrine-fixtures-bundle": "^3.0" // 3.0.2
}
}
Don't know if I missed some forum rule or something, I tried twice with my question and it just gets removed, not sure whether that's automatic or intentionally done by someone. Too much code sample in the question?