I´m using Symfony 2.1, I have this controller:
<?php
namespace app\UsuariosBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use app\UsuariosBundle\Entity\Usuarios;
use app\ClientesBundle\Entity\Clientes;
use app\UsuariosBundle\Util\Util;
class DefaultController extends Controller
{
//Some functions
public function conexionAction(Request $request){
$util=new Util();
$sesion=$util->compruebaSesion(1,1,1);
}
}
?>
And this is my helper class, his folder is in UsuariosBundle\Util\Util.php
<?php
namespace app\UsuariosBundle\Util;
class Util
{
public function compruebaSesion($tipo,$idUsuario,$login){
//Here I need the entity manager
}
}
?>
I need the entity manager to do some updates in the database with the util class from everywhere in the app, but I don´t know how to get the entity manager here,out of the controller.
|-| UPDATE |-|
I have updated my code with the instructions of Vincent T and I´m gettin this error:
"Argument 1 passed to app\UsuariosBundle\Service\Util::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, "
app/config/services.yml
services:
util:
class: app\UsuariosBundle\Service\Util
arguments: ["#doctrine.orm.entity_manager"]
src/UsuariosBundle/Service/Util.php
<?php
namespace app\UsuariosBundle\Util;
use Doctrine\ORM\EntityManager;
class Util
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function compruebaSesion($tipo,$idUsuario,$login){
$query= $this->em->createQuery('some query');
}
}
?>
Create a service as described in the docs sf docs services
and then you can just either inject that as a base service or get it using $this->get('name_of_helper_service') in a controller.
# app/config/services.yml
services:
app.service.util:
class: app\UsuariosBundle\Service\UtilService
arguments: ["#doctrine.orm.entity_manager"]
helper class
<?php
namespace app\UsuariosBundle\Util;
use Doctrine\ORM\EntityManager;
class Util
{
/**
* #Var EntityManager
*/
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function compruebaSesion($tipo,$idUsuario,$login){
$query= $this->em->createQuery('some query');
}
}
?>
Controller class
<?php
namespace app\UsuariosBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use app\UsuariosBundle\Entity\Usuarios;
use app\ClientesBundle\Entity\Clientes;
use app\UsuariosBundle\Util\Util;
class DefaultController extends Controller
{
//Some functions
public function conexionAction(Request $request){
$util= $this->get('app.service.util');
$sesion=$util->compruebaSesion(1,1,1);
}
}
?>
Related
I tried to call a function in a controller using service:
#BookManager.php
<?php
namespace App\Service;
use App\Entity\BookContent;
use Doctrine\ORM\EntityManagerInterface;
class BookManager
{
protected $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function getBookTitle(string $page){
return $this->entityManager->getRepository(BookContent::class)
>findOneBy(["page"=>$page])->getTitle();
}
In service.yml
....
services:
book.manager:
class: App\Service\BookManager
arguments: ['#doctrine.orm.entity_manager']
public: true
Finally I call it in Controller ;
$pageName = $this->container->get('request_stack')->getMasterRequest()->get('_route');
$bookTitle = $this->container->get('book.manager')->getBookTitle($pageName);
But I get this error
Service "book.manager" not found: even though it exists in the app's container, the container inside "App\Controller\HomeController" is a smaller service locator that only knows about the "doctrine", "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer", "session" and "twig" services. Try using dependency injection instead.
Any idea?
EDIT
it's work when I use dependency injection but only when I do query with $id
$this->entityManager->getRepository(BookContent::class)-
>findOneById(["id"=>$id])->getTitle();
when I do it with findOneBy(["page"=>$page]) I get this error:
Impossible to access an attribute ("title") on a null variable.
By default Symfony 5 will autowire/auto configure your services. You can remove the book.manager from your service.yaml.
You can then use dependency injection in your controllers to access your services, like this for example:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Service\BookManager; //<-- Add use
class YourController extends AbstractController
{
/**
* #Route("/", name="home")
*/
public function index(Request $request, BookManager $bookManager): Response
{
$pageName = $request->attributes->get('_route');
$bookTitle = $bookManager->getBookTitle($pageName);
return ...
}
}
I am new in symfony 4 and I've done the CRUD. I want to enhance my code by creating a function that will lessen it.
Example:
If you have 2 modules like manage event and announcement(ofcourse you will have here add,get all,delete, and update). Instead of having a long code like this.
$fetch_item = $this->getDoctrine()
->getRepository(Event::class)
->findAll();
I want to short it like $fetch = $this->fetch(Event::class); I created a new file in my Service directory.
Service\Crud.php
<?php
namespace App\Service;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
*
*/
class Crud extends AbstractController
{
public function __construct(){
parent::__construct();
}
public function fetch($table)
{
$fetch_item = $this->getDoctrine()
->getRepository($table)
->findAll();
return $fetch_item;
}
}
?>
Controller
//
...
use App\Service\Crud;
...
class EventController extends AbstractController
public function index()
{
// $fetch_item = $this->getDoctrine()
// ->getRepository(Item::class)
// ->findAll();
$fetch = $this->fetch(Item::class);
return $this->render('base.html.twig',array(
'items' => $fetch_item
));
}
Above is my code but it gives me an error "Attempted to call an undefined method named "fetch" of class "App\Controller\ItemController""
Question: How can I create a function that will lessen my code?
There is no reason for the fetch function to be part of a controller (on the contrary there are lots of reasons not to be). What you need is a simple service:
<?php
namespace App\Service;
use Doctrine\ORM\EntityManagerInterface;
class CrudService {
protected $em;
public function __construct(EntityManagerInterface $em){
$this->em = $em;
}
public function fetch($entityClass) {
return $this->em->getRepository($entityClass)->findAll();
}
}
Then in your controller you just have to inject it through autowiring and use it:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Service\CrudService;
use App\Entity\Item;
...
class EventController extends AbstractController {
public function index(CrudService $crudService) {
$items = $crudService->fetch(Item::class);
return $this->render('base.html.twig',array(
'items' => $items
));
}
}
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
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
create class Tools\MainBundle\Controller\Sm_Image_HandlerController
<?php
namespace Tools\MainBundle\Controller;
class Sm_Image_HandlerController{
public function test($param) {
return $param;
}
}
other class :
<?php
namespace FoodBundle\Controller;
use FoodBundle\Entity\FoodMaterialMapping;
use Symfony\Component\BrowserKit\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FoodBundle\Entity\Food;
use Symfony\Component\Validator\Constraints\NotBlank;
use Tools\MainBundle\Controller\Sm_Image_HandlerController;
/**
* Food controller.
*
*/
class FoodController extends Controller {
public function indexAction() {
$param="sample";
$sm=new Sm_Image_HandlerController();
$sample=$sm->test($param);
return new \Symfony\Component\HttpFoundation\Response(sample);
}
if run function indexAction in class foodController
return error
Attempted to load class "Sm_Image_HandlerController" from namespace "Tools\MainBundle\Controller".
Did you forget a "use" statement for another namespace?
src/FoodBundle/Controller/FoodController.php at line 23
<?php
public function createAction(Request $request) {
$param = "sample";
$sm = new Sm_Image_HandlerController();
$sample = $sm->test($param);
return new \Symfony\Component\HttpFoundation\Response(sample);
}
you must use CamelCase naming for class and file name in symfony
rename your controller and its file like this
class SmImageHandlerController{
public function test($param) {
return $param;
}
}