I am calling a method to apply a filter to a query through pass by reference, I can see that the query is modified correctly but then it is seemingly reverts back to the original unfiltered query result. It seems that that section after query modification block is run twice after testing with some dump() statements
This is the result of my testing:
Method where the pass by reference is being done:
public function processFilter(Builder &$query, array $resourceOptions)
{
if ($resourceOptions['query'] === null) {
return $query;
}
$conditionQueryApplier = new ConditionQueryApplier($this);
$conditionQueryApplier->apply($query, $resourceOptions['query']);
dump($query->get()->toArray());
}
Method called to modify query:
public function apply(&$baseQuery, $filter, array $options = [], $or = false)
{
dump('foo');
if (is_string($filter)) {
$filter = ConditionParser::parseQuery($filter);
}
$method = $or ? 'orwhere' : 'where';
$baseQuery->{$method}(function ($query) use ($filter, $options, $baseQuery) {
$or = false;
foreach ($filter as $filterBlock) {
if (isset($filterBlock['type'])) {
switch ($filterBlock['type']) {
case 'pair':
$or = $filterBlock['value'] === 'OR';
break;
case 'operation':
$config = $this->getMatchingConfig($filterBlock);
$this->validateFilter($filterBlock, $config);
if ($config['query_callback']) {
$functionPath = '\\' . $config['query_callback'];
$functionPath($baseQuery, $filterBlock, $config, $or);
}
break;
}
} else {
$this->apply($query, $filterBlock, $options, $or);
}
}
});
dump($baseQuery->get()->toArray());
}
Query callback filter called:
public static function latestScoreQuery($query, $filter, $config, $or){
$value = $filter['value'];
$operator = $filter['operator'];
$query->select(DB::raw('"location_id", ROUND(AVG("score"), 2) AS "average_score", COUNT("score") AS "total_scores", MAX("created") AS "latest"'))
->groupBy('location_id')
->having('location_id', '=', 'some_id');
}
And the results of the dump() statements are:
foo
foo
array:1 [
0 => array:4 [
"location_id" => "some_id"
"average_score" => "3.71"
"total_scores" => 7
"latest" => "2021-09-06 14:08:03"
]
]
array:2 [
0 => array:4 [
"location_id" => "some_id"
"average_score" => "3.71"
"total_scores" => 7
"latest" => "2021-09-06 14:08:03"
]
1 => array:4 [
"location_id" => "some_id2"
"average_score" => "2.00"
"total_scores" => 1
"latest" => "2021-09-03 11:22:41"
]
]
array:2 [
0 => array:4 [
"location_id" => "some_id"
"average_score" => "3.71"
"total_scores" => 7
"latest" => "2021-09-06 14:08:03"
]
1 => array:4 [
"location_id" => "some_id2"
"average_score" => "2.00"
"total_scores" => 1
"latest" => "2021-09-03 11:22:41"
]
]
So as can be seen by the results, there is no foo between the 2 arrays dumped which would indicate that the method was run twice. The filtered result is the array of length one but then the value is reverted for some reason to the unfiltered array of 2 and when checking the value after the pass by reference call, we can see that the query has indeed not been filtered.
I've tried logging as well to ensure that the dump() function itself is not the issue