Applying conditional query to Doctrine's `getRepository()` - symfony

I am trying to find my feet with Symfony and Doctrine and although I'm guessing it's far from elegant, I have managed to get the below working IF I use findall(). My main issue is that I'm trying to only return events which are yet to occur. Below is my attempt using expr()->gr():
My controller:
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Form\Type\RegistrationType;
use AppBundle\Form\Model\Registration;
use AppBundle\Entity\Events;
use Doctrine\ORM\EntityRepository;
class DefaultController extends Controller
{
/**
* #Route("/events", name="events")
*/
public function eventsAction(Request $request)
{
$calendar = $this->getDoctrine()
->getRepository('AppBundle:Events');
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->gt('EventDate',date('Y-m-d H:i:s') ));
$list=$calendar->matching($criteria);
return $this->render('default/events.html.twig', array(
'title' => 'Events',
'list' => $list,
));
}
}
My Events.php entity is:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Events
*
* #ORM\Table(name="Events")
* #ORM\Entity
*/
class Events
{
/**
* #var \DateTime
*
* #ORM\Column(name="EventDate", type="date", nullable=false)
*/
private $eventdate;
When I try to load the page I get:
Unrecognized field: EventDate
I'm assuming it's a case-sensitive issue somewhere? I have it in my database (EventDate) and my Events entity annotation specifies name="EventDate". I've tried changing private $eventdate to private $EventDate but this gives me an even more serious looking error so I quickly retreated:
FatalErrorException in DateType.php line 53: Error: Call to a member function format() on a non-object

I have no experience using criteria, but this is very easy to accomplish using the Doctrine Query Language (DQL).
$em = $this->getDoctrine()->getManager();
$result = $em->createQuery(
'SELECT e FROM AppBundle:Events e
WHERE e.eventdate > :date'
)
->setParameter(':date', $date)
->getResult();
$date has to be an instance of \DateTime.

Related

How could I sort the array of entity objects returned by this doctrine query?

For the below route I want to return a list of Events that are on or after the current date - however I'm having problems as I'm only aware of how to do either:
Return all objects sorted by date
Return all objects after 'today'
...but I can't work out how to do both together.
Below is my current code:
Controller
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Events;
class DefaultController extends Controller
{
/**
* #Route("/events", name="events")
*/
public function eventsAction(Request $request)
{
$calendar = $this->getDoctrine()->getRepository('AppBundle:Events')->findAll();
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->gt('eventdate',new \DateTime('now') ));
$list=$calendar->matching($criteria);
if (!$calendar) {
throw $this->createNotFoundException('No event found for ID ',$list);
}
return $this->render('default/events.html.twig', array(
'title' => 'Events',
'list' => $list,
'message' => '',
));
}
}
Entity repository
namespace AppBundle\Entity\Repository;
use Doctrine\ORM\EntityRepository;
class EventRepository extends EntityRepository
{
public function findAll()
{
return $this->findBy(array(), array('eventdate' => 'ASC'));
}
}
Events entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Events
*
* #ORM\Table(name="Events")
* #ORM\Entity
* #ORM\Entity(repositoryClass="AppBundle\Entity\Repository\EventRepository")
*/
class Events
{
/**
* #var \DateTime
*
* #ORM\Column(name="EventDate", type="date", nullable=false)
*/
private $eventdate;
/* .... */
}
// inside your repository
public function getAllFutureEvents()
{
return $this->getEntityManager()->createQuery(
'SELECT b FROM AppBundle:Event e
WHERE e.eventdate > CURRENT_DATE()
ORDER BY e.eventdate DESC'
)->getResult();
}
// inside your controller:
$events = $this->getDoctrine()->getRepository('AppBundle:Events')->getAllFutureEvents();

Repository with symfony2 and Doctrine not working

I'm trying to work with Entity Repository to write my custom functions.
I have an Entity and his Repository generated from yaml file
Yaml file
Bluesys\WeekupBundle\Entity\Event:
type: entity
repositoryClass: Bluesys\WeekupBundle\Repository\Event
fields:
id:
id: true
type: integer
generator:
strategy: AUTO
...
Entity code automatically generated
namespace Bluesys\WeekupBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Event
*/
class Event
{
/**
* #var integer
*/
private $id;
...
}
Repository code automatically generated
I juste wrote the function isHidden
namespace Bluesys\WeekupBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* Event
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class Event extends EntityRepository
{
/**
* isHidden
*
* #return bool
*/
public function isHidden()
{
return true;
}
}
The Controller code
namespace Bluesys\WeekupBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Bluesys\WeekupBundle\Event\Event;
...
class TimelineController extends Controller
{
public function testAction(){
$repository = $this->getDoctrine()->getManager()->getRepository('BluesysWeekupBundle:Event');
$event = $repository->findOneById( 73 );
return $this->render('BluesysWeekupBundle::test.html.twig', array( 'event' => $event ));
}
...
And the view code
{{ event.isHidden }}
I get this error :
Method "isHidden" for object "Bluesys\WeekupBundle\Entity\Event" does not exist in BluesysWeekupBundle::test.html.twig at line 1
Can somebody help me by telling me what is missing ?
Repository classes are used only for selecting/fetching data. They are not the part of entity/object.
If you really want to call isHidden method by repository you can acheive this by passing the whole repository to template (return $this->render('BluesysWeekupBundle::test.html.twig', array( 'event' => $repository ));), but this is very bad idea.
Instead you can put isHidden() method into your entity class and call it as event.isHidden..

Custom query in custom repo cannot be found

I just want to get the last record so I cannot call my custom query in custom build repo. Error is below. Do you know what it could be?
Note: Normal find(), findBy() like queries work fine. If there is a easier way of doing it then please tell me how to do it.
Thanks
ERROR:
Undefined method 'getLastRecord'. The method name must start with either findBy or findOneBy!
MAIN CLASS:
namespace Booking\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="CashQuery")
* #ORM\Entity(repositoryClass="Booking\AdminBundle\Entity\CashQueryRepository")
* #ORM\Entity
*/
class CashQuery
{
}
REPO:
namespace Booking\AdminBundle\Entity;
use Doctrine\ORM\EntityRepository;
class CashQueryRepository extends EntityRepository
{
public function getLastRecord()
{
return $this->getEntityManager()
->createQuery(
'SELECT d FROM AdminBundle:CashQuery d ORDER BY d.id DESC LIMIT 1'
)
->getResult();
}
}
TRYING TO USE WITH THIS:
$dcq = $em->getRepository('BookingAdminBundle:CashQuery')->getLastRecord();
if (! $dcq) {
echo 'CashQuery could not found';
return false;
}
echo $dcq->getCreatedAt();
It seems like you're overwriting the Entity annotation. Try removing the second one:
namespace Booking\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="CashQuery")
* #ORM\Entity(repositoryClass="Booking\AdminBundle\Entity\CashQueryRepository")
*/
class CashQuery
{
}

Symfony2 Entity Annotation Assert/Callback method not invoked

I've got a problem with Assert/Callback validation. I used this as a sample for my code, but Symfony just ignores the validation function. This is the relevant part of my entity code
namespace Vendor\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo; // gedmo annotations
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ExecutionContext;
/**
* #Assert\Callback(methods={"isValidFirma"})
* #ORM\Entity(repositoryClass="Vendor\Bundle\Entity\UserProfileRepository")
* #ORM\Table(name="user_profile")
*/
class UserProfile
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//...
public function isValidFirma(ExecutionContext $context){
$context->addViolationAtSubPath('Firma', 'Company name must be present', array(), null);
// as of sf 2.3 use addViolationAt() instead [reference: https://github.com/propelorm/PropelBundle/issues/234 ]
}
//...
}
isValidFirma is never invoked. I tried validation.yml file instead of annotation as well, no success. I cleared the cache about fifty times, after every change, didn't help either. What could be the problem?
The solution. The problem was in used validator groups. The assert validator has to be a part of that group, or else it wont trigger.
This piece of code in form class file was the culprit:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$vg = array('my-profile');
$resolver->setDefaults(array(
'validation_groups' => $vg
));
}
changing the line with assert to
* #Assert\Callback(methods={"isValidFirma"}, groups={"my-profile"})
did the trick.

Doctrine2.1: Finding by DiscriminatorColumn results in "Unknown field" exception

I've tried to search for this error but the fact that I haven't found anything leads me to believe that I'm doing something silly. I'll include the relevant code below, but basically I'm using multiple table inheritance (or Class Table Inheritance) and trying to use the Doctrine ORM findBy() method to query based on the discriminator column, which results in the following ORMException being thrown: "Unrecognized field: type".
Here is the code that triggers the exception:
// $this->em is an instance of \Doctrine\ORM\EntityManager
$repository = $this->em->getRepository('JoeCommentBundle:Thread');
return $repository->findOneBy(array(
'type' => $this->type,
'related_id' => $id
));
Here is the relevant code for the 'base' abstract entity:
<?php
namespace Joe\Bundle\CommentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="comment_threads")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap( {"story" = "Joe\Bundle\StoryBundle\Entity\StoryThread"} )
*/
abstract class Thread
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="related_id", type="integer")
*/
protected $relatedId;
/** MORE FIELDS BELOW.... **/
And finally, here is the code for the concrete thread entity:
<?php
namespace Joe\Bundle\StoryBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Joe\Bundle\CommentBundle\Entity\Thread as AbstractThread;
/**
* #ORM\Entity
* #ORM\Table(name="story_comment_threads")
*/
class StoryThread extends AbstractThread
{
/**
* #ORM\OneToOne(targetEntity="Story")
* #ORM\JoinColumn(name="story_id", referencedColumnName="id")
*/
protected $story;
}
I've double checked my schema, and the type column definitely exists, so I'm not sure what could be causing this. Any ideas? Thanks.
Rob, when querying your actually using the parent entity and trying to filter on the discriminator value. Instead, work on the repository relative to the child entity you want to fetch. Doctrine will do the rest for you. So in your case you want to get the repository for StoryThread.
$repository = $this->em->getRepository('JoeCommentBundle:StoryThread');
return repository->find($id);
You cannot use the discriminator column as a standard entity property.
Instead you may do the following:
$dql = 'SELECT e FROM JoeCommentBundle:Thread e
WHERE e.related_id = :related_id AND e INSTANCE OF :type';
$query = $em->createQuery($dql);
$query->setParameters(array(
'type' => $this->type,
'related_id' => $id
));
$record = $query->getSingleResult();

Resources