Reputation: 2773
This question maybe is more related to architecture and application design more than development itself. Here it goes:
I have an entity defined with date and session (AM or PM), and I need a get/set property to know if isReservedAllDay(), which mean, this entity has a complimentary entity reserved in same day but different session.
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class HallReservation
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \Date
*
* @ORM\Column(name="date", type="date")
*/
private $date;
/**
* @var string: "AM" | "PM"
*
* @ORM\Column(name="session", type="string")
*/
private $session;
This isReservedAllDay() or getReservedAllDay() is actually set by accessing database, which of course, should be out of scope of an entity and done in controller or service.
My first solution is to do so, a query in controller to set de property and then be able to get this property value on twig, forms or wherever, without ever persisting or even mapping this property, this may be a proper solution from the architecture point of view (or maybe not!) but not nice from the point of view of develoment, as it forces me to set the property everytime I get an instance.
function setReservedAllDay($reserved)
{
$this->reservedAllDay = $reserved;
return $this;
}
function getReservedAllDay()
{
return $this->reservedAllDay;
}
Could you criticize this approach or suggest a better one?
Thank you
Upvotes: 1
Views: 257
Reputation: 2436
Setting the value through a doctrine listener for example. Just copied/typed this together so it'll probably not be fully working but you should get the idea. Maybe this approach will cover your needs.
Edit: Like ccKep mentioned the entityManager is already available through the LifecycleEventArgs
in the postLoad
function directly. Adding the custom event would only be needed if you need another service that depends on the entityManager and can't be injected directly because of that.
I'll leave the code here unchanged maybe it could be useful to someone else (who needs more than the entityManager).
The doctrine listener:
class HallReservationLoadListener
{
/** @var EventDispatcherInterface */
protected $eventDispatcher;
public function __construct(EventDispatcherInterface $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}
/**
*
* @param LifecycleEventArgs $args
*/
public function postLoad(LifecycleEventArgs $args)
{
$item = $args->getEntity();
if($item instanceof HallReservation) {
$event = new HallReservationLoadedEvent($item);
$this->eventDispatcher->dispatch(HallReservationLoadedEvent::NAME, $event);
}
}
}
The custom event:
class HallReservationLoadedEvent extends Event
{
const NAME = 'hallreservation.loaded';
protected $hallreservation;
public function __construct(HallReservation $hallreservation)
{
$this->hallreservation = $hallreservation;
}
public function getHallreservation()
{
return $this->hallreservation;
}
}
The listener for your custom event:
class HallReservationReservedListener
{
protected $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function setReservedProperty(HallReservationLoadedEvent $event)
{
$hallreservation = $event->getHallreservation();
//do your stuff
}
}
Services definitions:
app.listener.hallreservationload:
class: AppBundle\Listener\HallReservationLoadListener
arguments: ['@event_dispatcher']
tags:
- { name: doctrine.event_listener, event: postLoad }
app.listener.hallreservationload.reservedproperty:
class: AppBundle\Listener\HallReservationReservedListener
arguments: ['@doctrine.orm.entity_manager']
tags:
- { name: kernel.event_listener, event: 'hallreservation.loaded', method: 'setReservedProperty'}
Upvotes: 1