i have a problem with my Testproject, i tray to make Event, the function of this event is following, when the controller call the row with id 18 from the datebase, it will to call/dispach event, this event have to send email to a Email Adress.
the problem, i cannot call this event from my eventlistener, because i get the wrong:
Too few arguments to function App\customEvents\EmailEvent::SendEMail(), 0 passed in C:\xampp\htdocs\Authentication\src\EventListener\EmailListener.php on line 15 and exactly 1 expected
Controller:
namespace App\Controller;
use App\Entity\Posts;
use App\Repository\PostsRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class EventoController extends AbstractController
{
#[Route('/evento', name: 'app_evento')]
public function index(PostsRepository $Posts, EventDispatcherInterface $eventDispatcher): Response
{
$todo=$Posts->find(18);
$sendEmail=new \App\customEvents\EmailEvent;
$eventDispatcher->dispatch($sendEmail, \App\customEvents\EmailEvent::NAME);
return $this->render('evento/index.html.twig', [
'getdaten' => $todo,
]);
}
}
EmailListener
<?php
namespace App\EventListener;
use App\customEvents\EmailEvent;
use Symfony\Component\Mailer\MailerInterface;
class EmailListener
{
public function sendemailaktive( EmailEvent $MeinEmailEvent)
{
$MeinEmailEvent->SendEMail();
}
}
EmailEvent
<?php
namespace App\customEvents;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
class EmailEvent extends EventDispatcher
{
public const NAME = 'send.email';
public function SendEMail(MailerInterface $mailer)
{
$email = (new Email())
->from('hello#asdasd.com')
->to('spam#muhkas.com')
->subject('Email From Send!')
->text('Sending emails is fun again!')
->html('<p>See Twig integration for better HTML integration!</p>');
$mailer->send($email);
}
}
Related
As my IDE points out, the AbstractController::getDoctrine() method is now deprecated.
I haven't found any reference for this deprecation neither in the official documentation nor in the Github changelog.
What is the new alternative or workaround for this shortcut?
As mentioned here:
Instead of using those shortcuts, inject the related services in the constructor or the controller methods.
You need to use dependency injection.
For a given controller, simply inject ManagerRegistry on the controller's constructor.
use Doctrine\Persistence\ManagerRegistry;
class SomeController {
public function __construct(private ManagerRegistry $doctrine) {}
public function someAction(Request $request) {
// access Doctrine
$this->doctrine;
}
}
You can use EntityManagerInterface $entityManager:
public function delete(Request $request, Test $test, EntityManagerInterface $entityManager): Response
{
if ($this->isCsrfTokenValid('delete'.$test->getId(), $request->request->get('_token'))) {
$entityManager->remove($test);
$entityManager->flush();
}
return $this->redirectToRoute('test_index', [], Response::HTTP_SEE_OTHER);
}
As per the answer of #yivi and as mentionned in the documentation, you can also follow the example below by injecting Doctrine\Persistence\ManagerRegistry directly in the method you want:
// src/Controller/ProductController.php
namespace App\Controller;
// ...
use App\Entity\Product;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Response;
class ProductController extends AbstractController
{
/**
* #Route("/product", name="create_product")
*/
public function createProduct(ManagerRegistry $doctrine): Response
{
$entityManager = $doctrine->getManager();
$product = new Product();
$product->setName('Keyboard');
$product->setPrice(1999);
$product->setDescription('Ergonomic and stylish!');
// tell Doctrine you want to (eventually) save the Product (no queries yet)
$entityManager->persist($product);
// actually executes the queries (i.e. the INSERT query)
$entityManager->flush();
return new Response('Saved new product with id '.$product->getId());
}
}
Add code in controller, and not change logic the controller
<?php
//...
use Doctrine\Persistence\ManagerRegistry;
//...
class AlsoController extends AbstractController
{
public static function getSubscribedServices(): array
{
return array_merge(parent::getSubscribedServices(), [
'doctrine' => '?'.ManagerRegistry::class,
]);
}
protected function getDoctrine(): ManagerRegistry
{
if (!$this->container->has('doctrine')) {
throw new \LogicException('The DoctrineBundle is not registered in your application. Try running "composer require symfony/orm-pack".');
}
return $this->container->get('doctrine');
}
...
}
read more https://symfony.com/doc/current/service_container/service_subscribers_locators.html#including-services
In my case, relying on constructor- or method-based autowiring is not flexible enough.
I have a trait used by a number of Controllers that define their own autowiring. The trait provides a method that fetches some numbers from the database. I didn't want to tightly couple the trait's functionality with the controller's autowiring setup.
I created yet another trait that I can include anywhere I need to get access to Doctrine. The bonus part? It's still a legit autowiring approach:
<?php
namespace App\Controller;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectManager;
use Symfony\Contracts\Service\Attribute\Required;
trait EntityManagerTrait
{
protected readonly ManagerRegistry $managerRegistry;
#[Required]
public function setManagerRegistry(ManagerRegistry $managerRegistry): void
{
// #phpstan-ignore-next-line PHPStan complains that the readonly property is assigned outside of the constructor.
$this->managerRegistry = $managerRegistry;
}
protected function getDoctrine(?string $name = null, ?string $forClass = null): ObjectManager
{
if ($forClass) {
return $this->managerRegistry->getManagerForClass($forClass);
}
return $this->managerRegistry->getManager($name);
}
}
and then
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Entity\Foobar;
class SomeController extends AbstractController
{
use EntityManagerTrait
public function someAction()
{
$result = $this->getDoctrine()->getRepository(Foobar::class)->doSomething();
// ...
}
}
If you have multiple managers like I do, you can use the getDoctrine() arguments to fetch the right one too.
How do I obtain the name of the current route in the controller in Symfony 5?
When I try this I get NULL:
$this->Request = Request::createFromGlobals();
$route = $this->Request->attributes->get('_route');
var_dump($route);
It's not recommended to create request inside your controller.
Preferred way of obtaining already created Request is DI and autowiring:
// src/Controller/BlogController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class BlogController extends AbstractController
{
/**
* #Route("/blog", name="blog_list")
*/
public function list(Request $request)
{
$routeName = $request->attributes->get('_route');
$routeParameters = $request->attributes->get('_route_params');
var_dump($routeName);
}
}
This request is processed by Symfony HttpKernel and filled with additional information.
More info: https://symfony.com/doc/current/routing.html#getting-the-route-name-and-parameters
How did it get there: https://github.com/symfony/symfony/blob/b2609c4bae69ca383b97cb520da2ed9be1c48449/src/Symfony/Component/Routing/Matcher/UrlMatcher.php#L217
Found an answer here:
Just add RequestStack as a function parameter and call RequestStack->getCurrentRequest()->get('_route');
use Symfony\Component\HttpFoundation\RequestStack;
public function yourCalledFunction(Utilities $u, RequestStack $requestStack) {
$route = $requestStack->getCurrentRequest()->get('_route');
}
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´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);
}
}
?>
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;
}
}