The greatest difficulty in implementing this approach (i.e beforeExecuteQuery) is that although often the queries are executed in a single model there are often JOINS that use several models so place this event in every model would not be appropriate, for example:
$this->modelsManager->executeQuery("SELECT r.*, p.* FROM Robots r JOIN Parts p ORDER BY r.name");
Pretending that there is a many to many relationship between Robots and Parts then the above query requires 3 models:
<?php
class Robots extends Phalcon\Mvc\Model
{
public function beforeExecuteQuery()
{
}
}
class RobotsParts extends Phalcon\Mvc\Model
{
public function beforeExecuteQuery()
{
}
}
class Parts extends Phalcon\Mvc\Model
{
public function beforeExecuteQuery()
{
}
}
We can check every model for that method and execute it, but what parameters pass to them? Not all queries have a query builder, if we pass the PHQL it could be really hard change things on it, also changing the original PHQL we must re-parse it to take into account the new changes, re-parse and execute beforeExecuteQuery again?
class Robots extends Phalcon\Mvc\Model
{
public function beforeExecuteQuery($phql)
{
if (preg_match('/ WHERE /i', $phql)) {
$parts = explode(' WHERE ', $phql);
$phql = $parts[0] . ' WHERE robots.shard_id = 1 AND '.$parts[1];
}
return $phql;
}
}
Like this, there are more complex scenarios where the event, instead of make things easier it will make applications more complex and will lead to all kind of misunderstanding and wrong expectations, so implement an event that sometimes work as expected and sometimes does not is not the ideal.