I have a problem injecting the EntityManger into a Symfony2 twig-extension. I did the following:
I registered a new twig extension and created a class. All of it is working.
Now I wanted to get access to the database and tried to inject the doctrine EntityManager. My first step was to add the EM as parameter to the constructor:
use XYZ\BlubBundle\Utils\SessionHelper;
class SessionHelperExtension extends \Twig_Extension
{
private $em;
private $conn;
protected $sessionHelper;
public function __construct(\Doctrine\ORM\EntityManager $em, \XYZ\BlubBundle\Utils\SessionHelper $sessionHelper) {
$this->em = $em;
$this->conn = $em->getConnection();
$this->sessionHelper = $sessionHelper;
}
[...]
}
?>
Then I added the following lines to the service.yaml:
twig.extension.sessionHelper:
class: XYZ\BlubBundle\Extensions\SessionHelperExtension
arguments: [#session_helper, #doctrine.orm.entity_manager]
tags:
- { name: twig.extension }
My own Service "sessionHelper" gets injected without a problem, but the EntityManager is always "null". What am I doing wrong here?
EDIT:
I get the following exception:
Catchable Fatal Error: Argument 2 passed to
XYZ\BlubBundle\Extensions\SessionHelperExtension::__construct() must be an instance of
Doctrine\ORM\EntityManager, none given,
called in /.../Symfony/app/cache/dev/appDevDebugProjectContainer.php on line 2918 and
defined in /.../Symfony/src/XYZ/BlubBundle/Extensions/SessionHelperExtension.php line 12
public function __construct(
\Doctrine\ORM\EntityManager $em,
\XYZ\BlubBundle\Utils\SessionHelper $sessionHelper
) {
is wrong — you need to keep the same order like in the yml:
public function __construct(
\XYZ\BlubBundle\Utils\SessionHelper $sessionHelper,
\Doctrine\ORM\EntityManager $em
) {
Update
Try this: http://www.coderelic.com/2012/06/querying-the-database-from-a-twig-extension-in-symfony-2/
Related
How can I get the "http://www.yourwebsite.com" from my repository class in Symfony 4?
The reason why I need to do this is because I'm using the Liip image service which returns the entire url, and I only need the url relative to the root, so I have to strip out the "http://www.yourwebsite.com" from the path returned.
I have used KernelInterface and that only returns the path from within your machine (i.e. the var/www/... in your machine).
I've tried injecting http foundation's Request object so I can call the getPathInfo() method, here is what I have in my repository class:
use Symfony\Component\HttpFoundation\Request;
class PhotoRepository extends ServiceEntityRepository
{
/**
* #var Request
*/
protected $request;
public function __construct(Request $request){
$this->request = $request;
}
But I just get the error Cannot autowire service "App\Repository\PhotoRepository": argument "$request" of method "__construct()" references class "Symfony\Component\HttpFoundation\Request" but no such service exists.
Here is what I have under "services" in my services.yaml:
App\Repository\PhotoRepository:
arguments:
- Symfony\Component\HttpFoundation\Request
Here is the full path to my file generated:
"http://www.mywebsite.com/media/cache/my_thumb/tmp/phpNbEjUt"
I need to parse out the get the http://www.mywebsite.com and just get the /media/cache/my_thumb/tmp/phpNbEjUt from the path.
As Cerad already wrote in the comments, you can inject the Symfony\Component\HttpFoundation\RequestStack:
App\Repository\PhotoRepository:
arguments:
- Symfony\Component\HttpFoundation\RequestStack
- Doctrine\Common\Persistence\ManagerRegistry
Your constructor for the PhotoRepository will then look something like:
class PhotoRepository extends ServiceEntityRepository
{
/**
* #var RequestStack
*/
protected $requestStack;
public function __construct(RequestStack $requestStack, ManagerRegistry $managerRegistry)
{
parent::__construct($managerRegistry, Photo::class);
$this->requestStack = $requestStack;
}
...
}
You can then determine the current URL using something like this:
private function getCurrentUrl(): string
{
$request = $this->requestStack->getCurrentRequest();
return $request->getBaseUrl(); // or possibly getUri()
}
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 had to call controller in service. In that manner I had created connstruct function and add parameter EntityMenager
class UsersController extends Controller
{
private $em;
public function __construct(EntityManager $em) {
$this->em = $em;
}
and defined service for that controller
services:
user_controller:
class: AppBundle\Controller\UsersController
arguments:
['#doctrine.orm.entity_manager']
when I call that service
$usersContainer = $this->get('user_controller');
in other controllers everything is fine.
But when I call self controller I get error
Catchable Fatal Error:
Argument 1 passed to AppBundle\Controller\UsersController::__construct()
must be an instance of Doctrine\ORM\EntityManager, none given,
Where I making mistake?
I just do ugly hack and solve problem at this moment.
I had removed __construc class and add EntityManager as needed parameter to function that needs EntityManager class.
public function getLoggedUserData($loggedUserId, $entityManager)
{
$user = $entityManager->getRepository('...')
$newRequests = $entityManager->getRepository('...')
You can only define a Controller as service, if it is a simple class (not extending Controller).
See : http://symfony.com/doc/current/cookbook/controller/service.html
And particularly :
http://symfony.com/doc/current/cookbook/controller/service.html#alternatives-to-base-controller-methods
I want to implement the security.token_storage as a service to get the user that is logged in; so when the user writes a post or a comment the field "Author" is automatically set.
I cannot get it working:
Attempted to call method "get" on class "Blog\BlogBundle\Services\PostManager".
How can I implement it as a service and use it?
The UserManager (as a service):
namespace Usuarios\UsersBundle\Services;
class UserManager
public function getloggedUser()
{
$loggedUser = $this->get('security.token_storage')->getToken()->getUser();
return $loggedUser;
}
The service.yml for the UserManager config:
services:
user_manager:
class: %user_manager.class%
arguments:
- #doctrine.orm.entity_manager
The PostManager, that uses the getloggedUser function:
namespace Blog\BlogBundle\Services;
class PostManager
private $em;
private $formFactory;
private $um;
/**
* #param EntityManager $em
* #param formFactoryInterface $formFactory
* #param UserManager $um
*/
public function __construct(EntityManager $em, FormFactoryInterface $formFactory, UserManager $um)
{
$this->em = $em;
$this->formFactory = $formFactory;
$this->um = $um;
public function createComment (Post $post, Request $request)
{
$comment = new Comment();
$comment->setPost($post);
//this is the line failing:
$comment->setAuthorName($this->um->getloggedUser());
$form = $this->formFactory->create(new CommentType(), $comment);
$form->handleRequest($request);
if ($form->isValid()) {
$this->em->persist($comment);
$this->em->flush();
return true;
}
return $form;
Note "user_manager" is defined as a service and is fully functional since other functions using it are working. Why cannot I call the UserManager service from the PostManager service? The error I get is:
Catchable Fatal Error: Argument 3 passed to Blog\BlogBundle\Services\PostManager::__construct() must be an instance of Usuarios\UsersBundle\Services\UserManager, none given, called in C:\xampp\htdocs\eScribely2\app\cache\dev\appDevDebugProjectContainer.php on line 2535 and defined
services do not have the get convenience method that controllers do. You need to pass the container in as an argument when you build the service and store it as a member variable and then call you service.
$this->container->get('user_manager');
Optionally you can just pass in your user manger and not have to use the container at all.
I needed to move my model from the controller method, so I got help to change it to a service. The service by itself works, but I need to be able to connect to doctrine and the kernel from inside of this service. At first I tried to enable doctrine, but that created problems. How can I make this work? I've followed docs and got this code. I have no idea why I got the error below. Thank you for your help in advance.
My config is:
CSVImport.php
namespace Tools\TFIBundle\Model;
use Doctrine\ORM\EntityManager;
class CSVImport {
protected $em;
public function __construct( EntityManager $em ) {
$this->em = $em;
}
app/config/config.yml
services:
csvimport:
class: Tools\TFIBundle\Model\CSVImport
arguments: [ #doctrine.orm.entity_manager ]
action in controller
$cvsimport = $this->get('csvimport');
MY ERROR
Catchable Fatal Error: Argument 1 passed to
Tools\TFIBundle\Model\CSVImport::__construct() must be an instance of
Doctrine\ORM\EntityManager, none given, called in
.../Tools/TFIBundle/Controller/DefaultController.php on line 58 and defined in
.../Tools/TFIBundle/Model/CSVImport.php line 12
EDIT, my working code:
service class code with Kernel attached to it
namespace Tools\TFIBundle\Model;
use Doctrine\ORM\EntityManager,
AppKernel;
class CSVImport {
protected $em;
protected $kernel;
protected $cacheDir;
public function __construct( EntityManager $em, AppKernel $k ) {
$this->em = $em;
$this->kernel = $k;
}
Try injecting #doctrine.orm.default_entity_manager.
On web I've found how to connect to Doctrine DBAL to be able to make queries on my own. But when i changed my configuration to this one:
app/config.yml
services:
csvimport:
class: Tools\TFIBundle\Model\CSVImport
arguments: [ #doctrine.dbal.connection, #doctrine.orm.entity_manager, #kernel ]
class definition
namespace Tools\TFIBundle\Model;
use Doctrine\ORM\EntityManager,
Doctrine\DBAL\Connection,
AppKernel;
class CSVImport {
protected $c;
protected $em;
protected $kernel;
public function __construct(Connection $c, EntityManager $em, AppKernel $k ) {
$this->c = $c;
$this->em = $em;
$this->kernel = $k;
}
i got error:
RuntimeException: The definition "csvimport" has a reference to an abstract definition "doctrine.dbal.connection". Abstract definitions cannot be the target of references.
Any ideas?