Symfony 2 problems with validating form - php

I want to validate my form. I created validation.yml file in the config folder, my bundle is registered and the file is loaded in DependencyInjection. I get the following error:
There is no extension able to load the configuration for "Developer\Forum\ForumBundle\Entity\Registration" (in /var/www/html/forum/src/Developer/Forum/ForumBundle/DependencyInjection/../Resources/config/validation.yml). Looked for namespace "Developer\Forum\ForumBundle\Entity\Registration", found none
My validation.yml:
Developer\Forum\ForumBundle\Entity\Registration:
properties:
name:
- NotBlank: ~
surname:
- NotBlank: ~
DependencyInjection:
namespace Developer\Forum\ForumBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Developer\Forum\ForumBundle\Entity\Registration;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class DeveloperForumForumExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
$loader->load('validation.yml');
}
}
The form itself is working fine, data is saved into the database, but I need some validation. What is missing?

/app/Resources/config/validation.yml is loaded automatically. Don't load it for your configuration, this is wrong.
Add this to your configuration instead, to enable validation and don't let PHP parse annotations.
framework:
validation:
enabled: true
enable_annotations: false
If you want to add userdefined ymls for validation, you can append it to the parameter validator.mapping.loader.yaml_files_loader.mapping_files, (Symfony2 how to load validation.yml)

Related

Symfony 3.4 Use view inside my bundle

I've some trouble for the configuration of a new repository using Symfony 3.4. I've used the symfony command for create him with last LTS (3.4) and I add a new Bundle using command too. My new Bundle is up and work well but I can't use view stored inside this bundle.
I show you the structure of my Bundle :
I want to use this index.html.twig in my controller like this :
<?php
namespace Lister\ListerBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class DefaultController extends Controller
{
/**
* #Route("/lister")
*/
public function indexAction()
{
return $this->render('ListerListerBundle:Default:index.html.twig');
}
}
But when I try to render it I've this error.
Unable to find template "ListerListerBundle:Default:index.html.twig" (looked into: /home/emendiel/Data/Code/Perso/WebLister/app/Resources/views, /home/emendiel/Data/Code/Perso/WebLister/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form).
I understand what that say, my folder is not where symfony search my view but I don't found how I can said to Symfony go in "ListerBundle/Ressources/views"
In my oldest project that was work without other configuration.
Info: I use my bundle as reusable bundle.
Regards,
PS: This is my autoload part in composer.json
"autoload": {
"psr-4": {
"": "src/"
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
PSS: My AppKernel :
public function registerBundles()
{
$bundles = [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new AppBundle\AppBundle(),
new Lister\ListerBundle\ListerListerBundle(),
];
...
And Again: Here My dependencyInjection
And the content of files :
Configuration.php
<?php
namespace Lister\ListerBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files.
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/configuration.html}
*/
class Configuration implements ConfigurationInterface
{
/**
* {#inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('lister_lister');
// Here you should define the parameters that are allowed to
// configure your bundle. See the documentation linked above for
// more information on that topic.
return $treeBuilder;
}
}
ListerListerExtension.php
<?php
namespace Lister\ListerBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration.
*
* #link http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class ListerListerExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
Solution: from #Cerad
#ListerLister/Default/index.html.twig
Original response from #Cerad
For some reason, S3.4 no longer likes the Bundle:Dir:name approach to specifying twig paths and the generate:bundle command has not yet been updated. Not sure if it is a bug or feature. The #ListerLister/Default/index.html.twig path suggested above should work. Try bin/console debug:twig to see your twig namespaces paths. – Cerad
The basic problem appears to be that in S3.4, twig template paths such as 'ListerListerBundle:Default:index.html.twig' are no longer supported.
Replace the path in the controller with:
'#ListerLister/Default/index.html.twig'
And all should be well. If you are ever not sure what the actual namespace prefix is then run:
bin/console debug:twig
to list them.
S3.3 still works fine so this is something that changed in 3.4. Supposed to be using the namespaced format anyways so this is not a big deal.
I did file an issue about this on github: https://github.com/sensiolabs/SensioGeneratorBundle/issues/587
We shall see what the maintainers have to say.
Update: The great and powerful Fabpot himself replied to my issue. If you want to keep using the 'ListerListerBundle:Default:index.html.twig' format for templates then edit your app/config/config.yml file:
# app/config/config.yml
framework:
templating:
engines: ['twig']
You should only do this if you have legacy code which still uses the old format. Use twig namespaces for all new code.
#config/config.yml
#after router add like
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
templating:
engines: [twig]

Manage Common Dependencies with Parent Services in symfony 3

I noticed a strange thing with managing common dependencies with parent services in symfony 3.1.6.
http://symfony.com/doc/current/service_container/parent_services.html
I try to define a user_manager service which extends fos user manager service.
// AppBundle/Service/UserManager.php
namespace AppBundle\Service;
use FOS\UserBundle\Doctrine\UserManager as BaseUserManager;
class UserManager extends BaseUserManager
{
}
// AppBundle/DependencyInjection/AppExtension.php
namespace AppBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
class AppExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
# AppBundle/Resources/config/services.yml
services:
app.user_manager:
class: AppBundle\Service\UserManager
parent: fos_user.user_manager.default
When trying to get service in contoller
$this->get('app.user_manager');
Then the exception is thrown:
'You have requested a non-existent service "app.user_manager".'
However, if I define my custom service in a different way:
# AppBundle/Resources/config/services.yml
services:
app.user_manager:
class: AppBundle\Service\UserManager
arguments:
- '#fos_user.util.password_updater'
- '#fos_user.util.canonical_fields_updater'
- '#fos_user.object_manager'
- '%fos_user.model.user.class%'
Then it works fine.
Moreover, it used to work like this with a "parent" before, in symfony 2.8
What could be wrong here and how it should be done properly with symfony 3.1?
p.s. I tried to clear cache, and also remove var/cache* directory, but that doesn't help

Services not loaded at Resources/config/services.yml, why?

I'm running a issue here and I don't know why or where this is failing, perhaps I miss some configuration or so, anyway, I have this code at DependencyInjection\AppExtension.php file:
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
class AppExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
Then at Resources/config/services.yml I have this:
services:
pdone.twig.extension:
class: GroupDCA\PDOneBundle\Extension\PDOneTwigExtension
tags:
- { name: twig.extension }
For some reason isn't working. This mean I got this error:
The filter "empty" does not exist in PDOneBundle::pdone.html.twig at line 1
Now if I move the services definition to config/config.yml I got this error instead:
Compile Error: Cannot use isset() on the result of an expression (you can use "null !== expression" instead)
Which makes me think the bundle is not going through DependecyInjection, what I am missing here? Why different errors?
1) Did you add your bundle to AppKernel?
2) I am not sure, but I think you must follow the naming convention of your Extension class:
Bundle's root directory should contain DependencyInjection directory
Within the DependencyInjection, Extension class should be named as <BUNDLE>Extension, without "Bundle" suffix. That would be PDOOneExtension in your case.

Symfony container has no extensions when loading my bundle

I have a bundle which was working quite well for some time. However, I had to add some custom configuration params to it, so I wrote some lines in the bundle's config.yml, something like this:
# ...
acme_my_bundle:
special_params: ['param_1', 'param_2']
The configuration is defined in the bundle's Configuration class:
namespace ACME\MyBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
*/
class Configuration implements ConfigurationInterface {
/**
* {#inheritdoc}
*/
public function getConfigTreeBuilder() {
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_my_bundle');
$rootNode
->children()
->arrayNode('special_params')
->end()
->end();
return $treeBuilder;
}
}
The bundle is properly registered in AppKernel.php:
public function registerBundles() {
$bundles = array(
// ...
new ACME\MyBundle(),
// ...
);
// ...
return $bundles;
}
However, when I try to use my app, I get an error:
There is no extension able to load the configuration for "acme_my_bundle" (in (path_to_bundle)/MyBundle/DependencyInjection/../Resources/config/config.yml). Looked for namespace "acme_my_bundle", found none
I looked it up, but most results found were unsatisfactory - I eliminated the problems that came up during searching:
improper configuration structure
bundle not registered in the app kernel
config root node name different than the one returned from ACMEMyBundleExtension::getAlias()
I tried debugging the cause of the exception being thrown and discovered that when the YAML file loader tries to validate my config file, the container has no extensions:
var_dump($container->getExtensions()); // prints empty array - array(0) { }
It causes the validation to fail and the none part of the message to be displayed - there a no available extensions.
I tried debugging $this->extensions in ContainerBuilder::hasExtension() and for some reason the list is complete when the method is launched for the vendor bundles, but is empty for my bundle. It looks like that something in my bundle is still defined or registered incorrectly.
I changed the names off classes, etc. not to expose company code, excuse me for that if it causes confusion.
EDIT: I didn't explicitly mention it, but the Extension class is defined and the exception occurs when it is loaded - just as I have written above:
when the YAML file loader tries to validate my config file
To be more clear, here is my Extension class:
namespace ACME\MyBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class ACMEMyBundleExtension extends Extension {
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container) {
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
// The exception is thrown here
$loader->load('config.yml');
}
}
Check your configuration reader in ACME\MyBundle\DependencyInjection\Configuration for $rootNode = $treeBuilder->root('BUNDLE_CONFIG_KEY');.
BUNDLE_CONFIG_KEY should be:
valid (same in ACME\MyBundle\DependencyInjection\Configuration and your config.yml
unique for the app
Also please check you're defining bundle configuration in correct way - it should be added to app/config/*.yml (one of global config files). Maybe you have added acme_my_bundle config in other custom bundle config files?
You have missed bundle extension class (ACME\MyBundle\DependencyInjection\ACMEMyExtension) as explained here http://symfony.com/doc/current/cookbook/bundles/extension.html. Cookbook entry for bundle configuration is here. Key in config.yml should be named only as acme_my.
Creating the Configuration class alone is not enough. You need to register a dependency injection extension and use the Configuration class in there.
Read more about in the How to Create Friendly Configuration for a Bundle cookbook:
[The Configuration] class can now be used in your load() method to merge configurations and force validation (e.g. if an additional option was passed, an exception will be thrown)
namespace Acme\MyBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class AcmeMyBundleExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
// ...
}
}
Naming your extension class according to the convention will make it's automatically loaded. More on creating DIC extension classes in Creating an Extension Class. You can also enable the extension manually, see Manually registering an extension class.

You have requested a non-existent service "user_service"

Iam trying to implement service for encoding password but it seems it doesn't work cause I get "You have requested a non-existent service user_service " error.
Here is my code :
Vendor/BundleNameBundle/Resources/config/services.yml
services:
user_service:
class: Morescreens\VideomanagerBundle\Service\UserService
arguments: ['#security.encoder_factory']
app/config/config.yml
imports:
- { resource: "#morescreensVideomanagerBundle/Resources/config/services.yml" }
code for my service
class UserService {
/**
* #var EncoderFactoryInterface
*/
private $encoderFactory;
public function __construct(EncoderFactoryInterface $encoderFactory)
{
$this->encoderFactory=$encoderFactory;
}
public function setEncodedPassword(User $user)
{
$encoder=$this->encoderFactory->getEncoder($user);
$password=$encoder->encodePassword($user->getPassword(),$user->getSalt());
$user->setPassword($password);
}
}
Inside mine controller:
$user=new User();
$user->setPassword('password');
$this->get('user_service')->setEncodedPassword($user);
EDIT:
I manually deleted cache folder and my service started to work.
Try looking at your src/{VendorName}/{BundleName}Bundle/DependencyInjection/{VendorName}{BundleName}Extension.php
This file should load your service definitions like this:
<?php
namespace Vendor\{BundleName}Bundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class Vendor{BundleName}Extension extends Extension
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
//Load our YAML resources
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
This will load the service definition from src/{VendorName}/{BundleName}Bundle/Resources/config/services.yml into the container. If that still doesn't work try doing php app/console cache:clear. For speed reasons, symfony will basically aggregate all your service (and other configuration files) into a cached file so it doesn't have to read those files every time. The files that actually cache the service definitions are located:
app/cache/{envName}/ (The cache directory can be configured to be located wherever you want, this is just the default).
The files that have the relevent info for container service definitions are:
app{EnvName}DebugProjectContainer.php
app{EnvName}DebugProjectContainer.php.meta
app{EnvName}DebugProjectContainer.xml

Categories