I want to create HelperController for my project. I generate a controller with doctrine:generate:controller and I need to use entity manager in it.
I enjected to services.yml but it is giving an error like this:
Argument 1 passed to CampingBundle\Controller\HelperController::__construct() must be an instance of Doctrine\ORM\EntityManager, none given ...
My Controller Code :
namespace CampingBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Doctrine\ORM\EntityManager;
class HelperController extends Controller
{
protected $manager;
public function __construct(EntityManager $manager)
{
$this->manager = $manager;
}
My Services.yml :
services:
camping.helper_controller:
class: CampingBundle\Controller\HelperController
arguments: ["#doctrine.orm.entity_manager"]
Why it doesn't work ? Shoudl I clear cache or something else or is there anything wrong in definition ?
Thanks
Try to use EntityManagerInterface and remove extends Controller.
Check this link if you need CAS (Controllers as Services).
Change protected $manager; to private $manager;
namespace CampingBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
class HelperController
{
/**
* #var EntityManagerInterface $entityManager
*/
private $entityManager;
/**
* #param $entityManager
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
}
I'll leave my two cents here as I had same issue and fixed it by adding tags to service.
something.validate.some_service:
class: Path\To\Some\Validator
arguments:
- '#doctrine.orm.entity_manager'
tags:
- { name: validator.constraint_validator, alias: some_validator_alias }
How to Work with Service Tags by Symfony
Related
I have upgraded the symfony 2.8 project to symfony 3.4. After fixing some issue I am getting the above issue when loading the page which has form with filters.
The app_filter attribute is configured in my form.yml file inside the bundle/resources/config directory and it looks like the below,
parameters:
app.abstract_filter.form.type.class: AppBundle\Form\Type\Filter\FilterType
services:
app.abstract_filter.form.type:
class: '%app.abstract_filter.form.type.class%'
arguments:
- '#translator.default'
- '#doctrine.orm.entity_manager'
tags:
- { name: form.type, alias: app_filter}
app.abstract_filter.form:
class: Symfony\Component\Form\Form
factory: ['#form.factory', createNamed]
arguments:
- 'app_filter'
- '%app.abstract_filter.form.type.class%'
app_abstract_fitler_form_type class:
namespace AppBundle\Form\Type\Filter;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\Translator;
class FilterType extends AbstractType
{
/** #var Translator */
protected $translator;
/** #var EntityManager */
protected $entityManager;
public function __construct(Translator $translator, EntityManager $entityManager)
{
$this->translator = $translator;
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
}
public function getName()
{
return 'app_filter';
}
}
In the DI there is Autowiring, annotation definition and PHP definition.
In Symfony 3.3 the autowiring is enabled by default. So if I disable the autowiring, can I use the annotation to define a service?
class Foo
{
/**
* #Inject({"my.specific.service"})
*/
public function __construct(Bar $param1)
{
}
}
Update : Use JMSDiExtraBundle
namespace MediaBundle\Net;
use JMS\DiExtraBundle\Annotation\Inject;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Service;
/**
* #Service("some.service.id", public=false, environments = {"prod", "test", "dev"})
*/
class Foo
{
private $em;
private $session;
/**
* #InjectParams({
* "em" = #Inject("doctrine.orm.entity_manager"),
* "session" = #Inject("session")
* })
*/
public function __construct($em, $session)
{
$this->em = $em;
$this->session = $session;
}
}
Calling the service in the controller:
namespace MediaBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class DefaultController extends Controller
{
/**
* #Route("/media")
*/
public function indexAction()
{
$someService = $this->get('some.service.id');
return $this->render('MediaBundle:Default:index.html.twig');
}
}
Result : You have requested a non-existent service "some.service.id".
Is your service injected somewhere? If not, it will be dropped from the container due to public=false, see http://symfony.com/blog/new-in-symfony-3-2-improved-private-services
I'm trying to override the LastLoginListener to add functionality to it.
I;m trying to do it as described here
It seems
In AppBundle\DependencyInjection\OverrideServiceCompilerPass.php
<?php
namespace AppBundle\DependencyInjection\Compiler;
use AppBundle\EventListener\LastLoginListener;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class OverrideServiceCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('"fos_user.security.interactive_login_listener');
$definition->setClass(LastLoginListener::class);
}
services.yml
services:
app.login_listener:
class: AppBundle\EventListener\LastLoginListener
arguments: []
tags:
- { name: kernel.event_subscriber }
The listener itself is copied from the bundle.
The autoloader expected class "AppBundle\DependencyInjection\OverrideServiceCompilerPass" to be defined in file "/vendor/composer/../../src/AppBundle/DependencyInjection/OverrideServiceCompilerPass.php". The file was found but the class was not in it, the class name or namespace probably has a typo.
in DebugClassLoader.php (line 261)
My goal is to add the ip address of the last login with the listener, but I'll need to create another to add a role and a registration date
I'm trying to do it "the right way" instead of doing something hackish
Its much better to use success_handler and failure_handler services.
# app/config/security.yml
firewalls:
main:
...
form_login:
...
success_handler: authentication_success_handler
failure_handler: authentication_failure_handler
Next you need to register your services and add arguments that fit your needs (probably #router and #doctrine.orm.entity_manager)
# app/config/services.yml
authentication_success_handler:
class: AppBundle\Handler\AuthenticationSuccessHandler
arguments: ['#router', '#doctrine.orm.entity_manager']
authentication_failure_handler:
class: AppBundle\Handler\AuthenticationFailureHandler
arguments: ['#router', '#doctrine.orm.entity_manager']
Then you need to create your services
// src/AppBundle/Handler/AuthenticationSuccessHandler.php
<?php
namespace AppBundle\Handler;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Router;
use Doctrine\Common\Persistence\ObjectManager;
class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface {
protected $router;
private $em;
public function __construct(Router $router, ObjectManager $em) {
$this->router = $router;
$this->em = $om;
}
public function onAuthenticationSuccess(Request $request, AuthenticationException $exception) {
// your code here - creating new object. redirects etc.
}
}
and
// src/AppBundle/Handler/AuthenticationFailureHandler.php
<?php
namespace AppBundle\Handler;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Router;
use Doctrine\Common\Persistence\ObjectManager;
class AuthenticationFailureHandler implements AuthenticationFailureHandlerInterface {
protected $router;
private $em;
public function __construct(Router $router, ObjectManager $em) {
$this->router = $router;
$this->em = $om;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
// your code here - creating new object. redirects etc.
}
}
If you want to hook into another FOSUserBundle Controller use this
I always use doctrine from controllers or from entity repository classes, now I am trying to use it from a static class but I can't find any example on how to do id.
Basically I'd need (I think) a way to create the entity manager in a static method.
thanks
M
You may call a setter function, injecting entity manager, where you call the static method:
MyController
Class MyController extends Controller
{
public function newAction()
{
$entityManager = $this->getDoctrine()->getManager();
SomeClass::setEntityManager($entityManager);
$result = SomeClass::myStaticMethod();
}
}
SomeClass
Class SomeClass
{
private static $entityManager;
public static function setEntityManager($entityManager)
{
self::$entityManager = $entityManager;
}
public static function myStaticMethod()
{
return $entityManager->getRepository(SomeEntity::class)->findAll();
}
}
I'm not sure from your question what you mean by static class/method, some code example might help. But you could declare this class as a service, which it sounds like it might be meant to be anyway, and then inject the entity manager as a dependency.
services.yml
services:
my_service:
class: Acme\AppBundle\Services\MyService
arguments: ["#doctrine.orm.entity_manager"]
Then in your class you will have the entity manager available like this:
<?php
namespace Acme\AppBundle\Services;
use Doctrine\ORM\EntityManager;
class MyService
{
/**
* Entity Manager
*
* #var Doctrine\ORM\EntityManager
*/
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
...
}
And you can then use this service in your controllers like so:
$this->get('my_service')->doSomething();
I am new at symfony and trying to create REST api using FOSRest Bundle. Also i want to use flysystem library as service in my controllers. It is simple as that
class FileController extends FOSRestController
{
public function getFilesAction()
{
$filesystem = $this->container->get('oneup_flysystem.application_filesystem');
...
}
}
This works fine, but my idea is to Inject this service into FileController so i can use $filesystem service in every method in my controller.
I read about it, that I have to make my controller as service, but then something went wrong. What is the proper way to make this injection.
We use something like this:
YourBundle/Resources/config/services.yml
controller.file:
class: YourBundle\Controller\FileController
arguments:
- #yourFileService
- #service_container
YourBundle/Controller/FileController.php
/**
* #Route("/file", service="controller.file")
*/
class FileController extends Controller
{
/**
* #var Filesystem
*/
private $filesystem;
/**
* #param Filesystem $filesystem
* #param $container
*/
public function __construct(
Filesystem $filesystem,
$container
) {
$this->filesystem = $filesystem;
$this->container = $container;
}