Let's say I have model "Question".
Every question is created by user (current user).
How to "auto" update createdBy
to current.user
In Doctrine2 I should have event listener with dependency on security.context
.
And event will subscribe for preSave()
, setting $question->setCreatedBy( $context->getToken()->getUser());
How to achieve this with Propel2 ? I could set createdBy
in controller, but this is ugly :(
I could write custom behavior, but how to access security.context
from the behavior ?
After ~ half year I found working solution :)
Idea: Model will have setter injection for Event Dispatcher
. On pre-save
model will fire event (validation/user injection etc..). This way I require ED for save. I can select objects from the DB without injected ED.
Dependency manager will manage "repository". Repo will be able to inject all required dependencies on the model and then call save.
$depepndanciesManager->getModelRepo->save($model)
.
Witch will do:
$model->setEventDispacher($this->getEventDispacher);
$model->save();
Example of Model:
class Lyric extends BaseLyric
{
private $eventDispacher;
public function preSave(ConnectionInterface $con = null)
{
if (!$this->validate()) {
// throw exception
}
$this->notifyPreSave($this);
return parent::preSave($con);
}
private function getEventDispacher()
{
if ($this->eventDispacher === null) {
throw new \Exception('eventDispacher not set');
}
return $this->eventDispacher;
}
public function setEventDispacher(EventDispacher $eventDispacher)
{
$this->eventDispacher = $eventDispacher;
}
private function notifyPreSave(Lyric $lyric)
{
$event = new LyricEvent($lyric);
$this->getEventDispacher()->dispatch('tekstove.lyric.save', $event);
}
}
Example of Repository:
class LyricRepository
{
private $eventDispacher;
public function __construct(EventDispacher $eventDispacher)
{
$this->eventDispacher = $eventDispacher;
}
public function save(Lyric $lyric)
{
$lyric->setEventDispacher($this->eventDispacher);
$lyric->save();
}
}
Example usage from controller:
public function postAction(Request $request)
{
$repo = $this->get('tekstove.lyric.repository');
$lyric = new \Tekstove\ApiBundle\Model\Lyric();
try {
$repo->save($lyric);
// return ....
} catch (Exception $e) {
// ...
}
}
Example config:
tekstove.lyric.repository:
class: Tekstove\ApiBundle\Model\Lyric\LyricRepository
arguments: ["@tekstove.event_dispacher"]
Config is based on symfony framework. Real implementation:
Links may not work, project is in active development!