i'm trying to understand how to do a QueryBuilder in a service so here is what i've done :
Create my service :
namespace OC\PlatformBundle\PurgerAdvert;
use Doctrine\ORM\EntityManager;
class PurgerAdvert
{
private $em;
public function __construct(EntityManager $em) {
$this->entityManager = $em;
}
public function purge($days)
{
$queryBuilder = $this->createQueryBuilder();
$queryBuilder->select('a')->from('OCPlatformBundle:Advert', 'a');
// get the Query from the QueryBuilder here ...
$query = $qb->getQuery();
return $result = $query->getResult();
}
}
Declare it in services.yml :
oc_platform.purger.advert:
class: OC\PlatformBundle\PurgerAdvert\PurgerAdvert
arguments: ['#doctrine.orm.entity_manager']
I remove the query because i've an error before that : "Attempted to call an undefined method named "createQueryBuilder" of class "OC\PlatformBundle\PurgerAdvert\PurgerAdvert"" I assume that i didn't call properly the entitymanager but i don't see my mistake ...
Thanks for your help :)
You may not want to type entityManager all the time, so a combination of both answers should work:
namespace OC\PlatformBundle\PurgerAdvert;
use Doctrine\ORM\EntityManager;
class PurgerAdvert
{
private $entityManager;
public function __construct(EntityManager $em) {
$this->entityManager = $em;
}
public function purge($days)
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder->select('a')->from('OCPlatformBundle:Advert', 'a');
// get the Query from the QueryBuilder here ...
$query = $qb->getQuery();
return $result = $query->getResult();
}
}
Try that, I think it should work.
Related
I would like to use entity manager inside entity and no idea for usage.
use Doctrine\Common\Persistence\ObjectManagerAware;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use SomeBundle\Entity\Boarding;
use SomeBundle\Entity\User;
class Entity extends ApiUserEntity implements ObjectManagerAware
{
private $em;
public function ___construct(User $user)
{
$this->board = $this->getData(123);
}
public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
{
$this->em = $objectManager;
}
private function getData($leadId)
{
//return gettype($this->em); //return null
$repository =$this->em->getRepository(Boarding::class);
$query = $repository->createQueryBuilder('b')
->where('b.lead = :lead')
->setParameter('lead', $leadId)
->getQuery();
$boards = $query->getResult();
return $boards;
}
}
Using this code get me error
Call to a member function getRepository() on null"
The entity manager is null also
//return gettype($this->em); //return null
Any idea for example usage?
You can try to create a repository like here. Just add
* #ORM\Entity(repositoryClass="App\Repository\EntityRepository")
or to YAML, Xml depends on your configuration and then create the repository file. Like this one:
// src/AppBundle/Repository/ProductRepository.php
namespace AppBundle\Repository;
use Doctrine\ORM\EntityRepository;
class ProductRepository extends EntityRepository
{
public function findAllOrderedByName()
{
return $this->getEntityManager()
->createQuery(
'SELECT p FROM AppBundle:Product p ORDER BY p.name ASC'
)
->getResult();
}
}
From the examples I'm finding in the Symfony docs, it looks like the typical thing to do when needing to save data is something like in the controller class:
public function createAction(){
$product = new Product();
$product->setName('Amy Keyboard');
$product->setPrice(24.99);
$product->setDescription('Ergonomic and stylish!');
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return $this->render('index.html.twig');
}
It would be really great to not have to type those 3 $em lines in every single controller method! And it would be even sweeter to move all of this logic to a class somewhere else and then just call $product->saveProduct($data)! What is the best option here?
I usually create a manager class e.g. ProductManager and register it as service. I inject the EntityManager via setter injection and implement all the methods I need.
In your case this would look similar to this:
AppBundle/Product/ProductManager
namespace AppBundle\Product;
use Doctrine\ORM\EntityManager;
class ProductManager {
/** #var EntityManager */
private $entityManager;
public function setEntityManager (EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function getAll()
{
return $this->entityManager->createQuery('SELECT p FROM '.Product::class.' p')
->getResult();
}
public function add(Product $product, $flush = true)
{
$this->entityManager->persist($product);
if ( $flush ) {
$this->entityManager->flush($product);
}
}
public function byId($id)
{
// Fetch a product by id (note: No need to use DQL or the EntityRepository here either!)
return $this->entityManager->find(Product::class, $id);
}
}
app/config/services.yml
services:
app.product_manager:
class: AppBundle\Product\ProductManager
calls:
- [setEntityManager, ['#doctrine.orm.entity_manager']]
Controller
public function createAction(){
$product = new Product();
$product->setName('Amy Keyboard');
$product->setPrice(24.99);
$product->setDescription('Ergonomic and stylish!');
// add the product
$this->get('app.product_manager')->add($product);
return $this->render('index.html.twig');
}
Take a look at the Propel project if you want something like $product->save() but it is a totally different approach. This is the official bundle https://github.com/propelorm/PropelBundle/blob/3.0/README.markdown
I have an error when I would like to add a custom method with DQL Request.
Error:
Undefined method 'getAll'. The method name must start with either
findBy or findOneBy!
My Controller:(SheetController.php)
<?php
namespace Test\FrontBundle\Controller;
use Doctrine\ORM\EntityNotFoundException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Test\FrontBundle\Entity\Sheet;
class SheetController extends Controller
{
public function sheetListAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('TestFrontBundle:Sheet');
$sheets = $repository->getAll();
var_dump($sheets);
return $this->render('TestFrontBundle:Sheet:sheetList.html.twig');
}
public function sheetAction($id, Request $request)
{
$repository = $this->getDoctrine()->getManager()->getRepository('TestFrontBundle:Sheet');
$sheet = $repository->find($id);
if(!$sheet)
{
throw new EntityNotFoundException();
}
return $this->render('TestFrontBundle:Sheet:sheet.html.twig', array('sheet' => $sheet));
}
}
?>
My Repository:(SheetRepository.php)
<?php
namespace Test\FrontBundle\Entity;
/**
* SheetRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class SheetRepository extends \Doctrine\ORM\EntityRepository
{
public function getAll()
{
$qb = $this->createQueryBuilder('s');
$query = $qb;
$result = $query->getQuery()->execute();
return $result;
}
}
Please, Could you help me? :)
Why don't you use native Doctrine query findAll() for this?
public function sheetListAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('TestFrontBundle:Sheet');
$sheets = $repository->findAll();
/***/
}
EDIT - With class repository:
class SheetRepository extends \Doctrine\ORM\EntityRepository
{
public function getAll()
{
return $this->createQueryBuilder('s')
->select('s')
->getQuery()
->getResult()
;
}
}
And in your controller : replace findAll() by getAll()
I have a method in 'DynamicList' service that should return a select filled with dynamic data, but i'm getting "circular reference":
YML:
parameters:
my.dynamic_list.class: My\DynamicListBundle\Service\DynamicList
services:
my.dynamic_list:
class: %my.dynamic_list.class%
arguments: ['#doctrine.orm.default_entity_manager','#templating']
Class:
<?php
namespace My\DynamicListBundle\Service;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
class DynamicList
{
private $em;
private $templating;
public function __construct(
EntityManager $em,
EngineInterface $templating
) {
$this->em = $em;
$this->templating = $templating;
}
public function getSelect($slug)
{
$dynamic_list = $this->em
->getRepository('MyDynamicListBundle:DynamicList')
->findOneBy(array(
"slug" => $slug
));
return $this->templating->render('MyComponentsCoreBundle::Templates/DynamicList/combo.html.twig', array(
'dl' => $dynamic_list
));
}
}
I guess i don't need to put here the twig content: the problema occurs before.
Last, the error i'm getting:
Circular reference detected for service "my.dynamic_list", path: "my.dynamic_list -> templating -> twig". (500 Internal Server Error - ServiceCircularReferenceException)
What's the proper way to get templating component working in my service?
Well, I found a workaround but I don't if is the best way:
<?php
namespace My\DynamicListBundle\Service;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
class DynamicList
{
private $em;
private $templating;
public function __construct(
EntityManager $em
) {
$this->em = $em;
}
public function init(
EngineInterface $templating
) {
$this->templating = $templating;
}
public function getSelect($slug)
{
$dynamic_list = $this->em
->getRepository('MyDynamicListBundle:DynamicList')
->findOneBy(array(
"slug" => $slug
));
return $this->templating->render('MyComponentsCoreBundle::Templates/DynamicList/combo.html.twig', array(
'dl' => $dynamic_list
));
}
}
So, in controller, I call 'init()' to pass 'templating':
$dl_service = $this->get('my.dynamic_list');
$dl_service->init($this->container->get('templating'));
I am using a symfony controller as a service.But when I call doctrine manager in the controller it gives the error FatalErrorException: Error: Call to a member function has() on a non-object.
Here is my controller:
namespace Acme\StoreBundle\Controller;
use Doctrine\ORM\EntityManager;
class ServiceController extends Controller {
/**
*
* #var EntityManager
*/
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
}
and my services.yml is like:
services:
service_controller:
class: Acme\StoreBundle\Controller\ServiceController
arguments: ["#doctrine.orm.entity_manager"]
I am calling the entity manager in an other controller which DbController:
<?php
public function users()
{
$query = $this->em->createQuery('select u from AcmeStoreBundle:User u');
$user = $query->getResult();
}
You can get the EntityManager in ServiceController likeļ¼
$em = $this->getDoctrine()->getManager();
so the following codes make no sense:
service_controller:
class: Acme\StoreBundle\Controller\ServiceController
arguments: ["#doctrine.orm.entity_manager"]
And i really want to see your DbController codes, can you show that?
My DbController is like:
<?php
namespace Acme\StoreBundle\Controller;
use Acme\StoreBundle\Entity\UserCategoryTag;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DbController extends Controller
{
//Suppose you want get all users you can do some like this..
public function Users() {
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('AcmeStoreBundle:User');
$user = $repository->findAll();
}
}
You can also get using per-execute method like follow:
1] Create new listener class for pre-execute method
namespace Acme\Listener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
/**
* Acme\Listener\ControllerListener
*/
class ControllerListener
{
/**
* On Core Controller this is used to set pre execute
*
* #param GetResponseEvent $event
*/
public function onCoreController(FilterControllerEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
$_controller = $event->getController();
if (isset($_controller[0])) {
$controller = $_controller[0];
if (method_exists($controller, 'preExecute')) {
$controller->preExecute();
}
}
}
}
}
2] configure listener in your config file app/config/config.yml
services:
controller.pre_execute_listener:
class: Acme\Listener\ControllerListener
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
3] controller file
namespace Acme\StoreBundle\Controller;
use Doctrine\ORM\EntityManager;
class ServiceController extends Controller {
public function preExecute()
{
$this->em = $this->getDoctrine()->getEntityManager();
}
}
4] your function
<?php
public function users()
{
$query = $this->em->createQuery('select u from AcmeStoreBundle:User u');
$user = $query->getResult();
}
I solved this by trying a lot of things.
Here is the solution for this :
You have to use your controller as service.I used TagClass Controller as a service.Here is my controller code:
<?php
namespace Acme\StoreBundle\Controller;
class TagClassController extends Controller
{
public $em;
public function __construct(Entity Manager $em)
{
$this->em = $em;
}
public function ParseWebsite($categoryid){
}
}
?>
For using this you have to define the controller as service in your services.yml like this:
parameters:
acme.controller.tagclass.class: Acme\StoreBundle\Controller\TagClassController
services:
acme.controller.tagclass:
class: "%acme.controller.tagclass.class%"
arguments: [ #doctrine.orm.entity_manager ]
And you can call any method with in TagClass like this:
$this->forward('acme.controller.tagclass:ParseWebsite',array($categoryid));