Symfony2 how to get entity alias in repository - symfony

i would like to write some DQL query in my entity repository function but instead of haroding entity alias into DQL i would like to get actual entity alias from repository.
my repository:
/**
* TrackingRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class TrackingRepository extends EntityRepository
{
public function test()
{
$dql = 'SELECT * FROM MyBundle:Tracking';
// i would like to call something like this:
// $dql = 'SELECT * FROM ' . $this->getEntityAlias;
$query = $this->getEntityManager()->createQuery($dql);
...
}
}
is this somehow possible?

You can get the entity class with $this->getClassName() in your repository :
class TrackingRepository extends EntityRepository
{
public function test()
{
$dql = 'SELECT t FROM ' . $this->getClassName() . ' t';
$query = $this->getEntityManager()->createQuery($dql);
...
}
}

class TrackingRepository extends EntityRepository
{
public function test()
{
$dql = 'SELECT t.property1,t.property2,t.property3,t.property4 FROM MyBundle:Tracking t';
// i would like to call something like this:
// $dql = 'SELECT * FROM ' . $this->getEntityAlias;
$query = $this->getEntityManager()->createQuery($dql);
...
}
}

What kind of query you want to execute? Are you realy need DQL? There are other ways to achive execute complex query, please consider:
Repository findBy($criteria):
public function test()
{
$this-> findBy($criteria);
}
For more complex queries you can also use:
Criteria and matching:
use Doctrine\Common\Collections\Criteria;
//
public function test()
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq('sth', 'val'))
// more criteria here
$result = $this->matching($criteria);
}
Doctrine's Query Builder
Or even Query Builder with specific criteria expressions:
public function test()
{
$qb = $er->createQueryBuilder('p');
$qb
->where($qb->expr()->andx(
$qb->expr()->in('p', '?1'),
$qb->expr()->isNotNull('p.someField')
))
->setParameter(1, $someValue);
$result = $this->matching($criteria);
}

Related

JOIN DQL SYMFONY

i want to count how many baby for a parent
class abonnementRepository extends \Doctrine\ORM\EntityRepository
{
public function SumEnfantDQL($id)
{
$entityManager = $this->getEntityManager();
$query = $entityManager->createQueryBuilder();
$query->select('sum(o.id) AS somme');
$query->from('AppBundle:enfant', 'o');
$query->join('AppBundle:User','p')->where('p.id = :id');
$rez = $query->getQuery()->getResult();
return $rez;
}
}
the entity enfant had matricul_prt and entity user had enfant_id and $id parameter is the parent id
i don't know how it work with join or innerJoin .So what i want to do is
SELECT SUM(*)
FROM enfant e
WHERE e.matricul_prt = $id;
Thank you so much
First of all, you should create a Repository class for AppBundle:enfant, this repo does not look like created fot 'enfant'.
Next the method should look like below, but only if there is valid association between 'enfant' and 'User'.
public function SumEnfant(int $id): int
{
return $this->createQueryBuilder('e') <- alias for 'enfant'
->select('sum(e.id)')
->join('e.user', 'u') <- join by entity property
->where('u.id = :id') <- condition for associated entity
->setParameter('id' , $id) <- parameter
->getQuery()
->getSingleScalarResult();
}
Try this, read doc once again and modify for your case.

Example Usage of ObjectManagerAware inside entity

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();
}
}

Symfony 2 get Doctrine in Entity

I have two classes
class Topic
{
protected $id;
//....
}
and
class Post
{
protected $topic_id;
//...
}
and I would like add method getPostCount() in Topic class. In other frameworks I used to use something like that:
public function getPostCount()
{
$count = Post::find()
->where(['topic_id' => $this->id])
->count();
return $count;
}
but in symfony2 I don't know how to make it.
You can create a repository class with this method. Add the repository class name to your entity's mapping definition, like this:
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\PostRepository")
*/
class Post
{
protected $topic_id;
//...
}
And in your repository class:
public function getPostCount($id)
{
$query = $this->createQueryBuilder('p')
->select('count(p.topic_id)')
->where('p.topic_id = :id')
->setParameter('id', $id)
->getQuery()->getSingleScalarResult();
return $query;
}
In addition to #DonCallisto answer
//Topic.php
public function getPostsCount()
{
return $this->getPosts()->count();
}
This use doctrine lazyloading: it could be done because you already defined the relation between the entity.
It would not be a good practice to do a query inside the entity, you should use a Repository for that.
//Topic.php
public function getPostsCount()
{
return $this->getPosts()->count();
}
If you have configured annotations or yml properly, you're fine with this
Into Post repository:
public function getPostCount($id) {
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('count(p.topic_id)');
$qb->from('AppBundle:Post', 't')
->where('p.topic_id = :id')
->setParameter('id', $id);
$count = $qb->getQuery()->getSingleScalarResult();
return $count;
}

Extend Doctrine EntityRepository

I have written a class BasicRepository in order to use it instead of the EntityRepository to add some basic modification like remove all deleted-flaged items.
<?php
namespace AppBundle\Repository;
use AppBundle\DataFixtures\ORM\LoadEventPrioData;
use AppBundle\Entity\Location;
use Doctrine\ORM\EntityRepository;
class BasicRepository extends EntityRepository
{
public function createQueryBuilder($alias, $indexBy = null)
{
$query = parent::createQueryBuilder($alias);
dump(parent::getClassName());
dump($this->getClassName());
if (property_exists($this->getClassName(), 'isDeleted')) {
dump("Ping");
$query->andWhere($alias.'.isDeleted = :false')->setParameter('false', false);
}
else {
dump("Pong");
}
return $query;
}
}
Controller:
...
public function searchAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$meta = new ClassMetadata('AppBundle:Location');
$er = new BasicRepository($em, $meta);
$query = $er->createQueryBuilder('u');
...
My aim is that - if the property "isDeleted" (boolean) exists in the Entity - the Query should contain an additional Where-Statement.
For some strange reason property_exists always return false - even when the property exits in the class.
I get your idea. The correct place you're looking for is Doctrine Filters. Check this package: https://github.com/DeprecatedPackages/DoctrineFilters#usage
There you can find example exactly with your use case:
<?php
use Doctrine\ORM\Mapping\ClassMetadata;
use Symplify\DoctrineFilters\Contract\Filter\FilterInterface;
final class SoftdeletableFilter implements FilterInterface
{
/**
* {#inheritdoc}
*/
public function addFilterConstraint(ClassMetadata $entity, $alias)
{
if ($entity->getReflectionClass()->hasProperty('isDeleted')) {
return "$alias.isDeleted = 0";
}
return '';
}
}

Error to call a method in Doctrine, Symfony2

I don't understand why I get the following error in my Symfony2 project:
Error: Call to a member function getQueryId() on a non-object
Here are my codes:
Bibliorepository:
<?php
namespace Xxxx\XxxxxBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* BiblioRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class BiblioRepository extends EntityRepository
{
public function wantAuthor($author)
{
$query = $this->_em->createQuery('SELECT b FROM XxxxBundle:Biblio b WHERE b.author = :author');
$query->setParameter('author', $author);
$result_author = $query->getResult();
return $result_author;
}
}
The getter:
/**
* Get queryId
*
* #return integer
*/
public function getQueryId()
{
return $this->queryId;
}
}
And the controller:
$author = $this->getUser()->getId();
$repository = $this
->getDoctrine()
->getManager()
->getRepository('XxxxBundle:Biblio');
$resultBiblio = $repository->wantAuthor($author);
$resultBiblio->getQueryId();
foreach ($resultBiblio as $id_query) {
$repository = $this
->getDoctrine()
->getManager()
->getRepository('XxXxBundle:Query');
$resultQuery = $repository->wantQuery($id_query);
$titles = $resultQuery->getQuery();
}
return $this->redirect($this->generateUrl("fos_user_profile_show"));
Thank you very much for your help ;)
$resultBiblio is an array with object. You invoke a method on array and this causes error.
You can invoke this method in foreach like
foreach ($resultBilbo as $singleResult){
$singleResult->getQueryId();
}
Var dump results wantAuthor($author) method and make sure you're getting the Author object in return. I bet you're not getting one.

Resources