Reputation: 83
Ok Im using Illuminate on my php project and recently upgrade from PHP 5 to PHP 7.2.
I have this scope in my Model
Model.php
public function scopeWhereInOrAny(Builder $query, $field, $value)
{
if ($value === null || $value === '' || count($value) === 0) {
return $query;
}
return $query->whereIn($field, $value);
}
a pretty simple scope to accept null when using whereIn. Now I use it in a function
public function getList($params = []) {
$cancelReasons = CancellationReasons
::orderBy('id', 'asc')
->whereInOrAny('type_booking', $params['type_booking']) // HERE
->where('status', '=', 1)
->get(['id','name','type_client']);
return $cancelReasons;
And when I call that method, it kinda works, it returns what it should return but also adds a warning at the end like this
[{"id":1,"name":"He cancelado mi viaje","type_client":1},{"id":2,"name":"Quiero hacer otra actividad","type_client":1},{"id":3,"name":"Quiero modificar la reserva","type_client":1},{"id":4,"name":"He encontrado un precio m\u00e1s barato en otra web","type_client":1},{"id":5,"name":"El proveedor me ha pedido que cancele","type_client":1},{"id":6,"name":"Otros motivos","type_client":1},{"id":7,"name":"Condiciones climatol\u00f3gicas","type_client":2},{"id":8,"name":"Problemas en el destino","type_client":2},{"id":9,"name":"No hay un n\u00famero m\u00ednimo de personas","type_client":2},{"id":10,"name":"Falta de disponibilidad","type_client":2},{"id":11,"name":"Restricciones Covid","type_client":2},{"id":12,"name":"Cancelaci\u00f3n solicitada por el cliente","type_client":2},{"id":13,"name":"Otros motivos","type_client":2},{"id":14,"name":"Cese de la colaboraci\u00f3n con el proveedor","type_client":3},{"id":15,"name":"El proveedor no realiz\u00f3 la actividad","type_client":3},{"id":16,"name":"Otros motivos","type_client":3}]<br />
<b>Warning</b>: count(): Parameter must be an array or an object that implements Countable in <b>/var/www/html/newadmin/vendor7/illuminate/database/Eloquent/Builder.php</b> on line <b>1015</b><br />
Now debugging I found the issue is here in Builder.php
/**
* Apply the given scope on the current builder instance.
*
* @param callable $scope
* @param array $parameters
* @return mixed
*/
protected function callScope(callable $scope, $parameters = [])
{
array_unshift($parameters, $this);
$query = $this->getQuery();
// We will keep track of how many wheres are on the query before running the
// scope so that we can properly group the added scope constraints in the
// query as their own isolated nested where statement and avoid issues.
$originalWhereCount = count($query->wheres); // HERE IS THE PROBLEM
$result = $scope(...array_values($parameters)) ?: $this;
if (count($query->wheres) > $originalWhereCount) {
$this->addNewWheresWithinGroup($query, $originalWhereCount);
}
return $result;
}
Aparently $query->wheres is equals null on this case and in php 7.2 when using count on null it throws a warning, now why $query->wheres is equals to null? because there are no other wheres before the custom scope so if I change the order of my wheres to
public function getList($params = []) {
$cancelReasons = CancellationReasons
::orderBy('id', 'asc')
->where('status', '=', 1) //This where before the scope
->whereInOrAny('type_booking', $params['type_booking'])
->get(['id','name','type_client']);
return $cancelReasons;
}
It works perfectly!, but I don't think this really solves the issue long term, sure it solves this particular case but now every time I want to use a scope I need to add a random where first? even if I don't need it? that doesn't seems to be right. So Im looking for a cleaner solution to this issue that will work with other parts where Im using a scope on the querybuilder.
I hope anybody can help me
Upvotes: 0
Views: 42