Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MrMoto9000's avatar

Advanced query scope

I was hoping to write an advanced query scope that would return items based on a flexible number of parameters. For example, accepting a JSON string that could have any number of days of the week inside it to be excluded from a query:

public function scopeRestrictDays($query, String $restrictedDays = null)
{
    $restrictedDays = json_decode($restrictedDays)->day ?? [];

    return $query->filter(function($event) use ($restrictedDays) {
        $allowed = true;

        foreach($restrictedDays as $day) {
            if(date("D", strtotime($event->date)) === $day) {
                $allowed = false;
            }
        }
        return $allowed;
    })->all();
}

This of course immediately fails because $query isn't a Collection and so I cannot use filter() on it.

Is there any way to restructure this to make it work as a query scope? I'm thinking not, but I thought I'd see if there was a Laravel genius out there that can find a way.

0 likes
2 replies
SilenceBringer's avatar

@johnnyw2001

public function scopeRestrictDays($query, String $restrictedDays = null)
{
    $restrictedDays = json_decode($restrictedDays)->day ?? [];

    return $query->when($restrictedDays, function ($query) {
		return $query->whereNotIn(DB::raw('date_format($event->date, "%a")', restrictedDays);
	});
}
martinbean's avatar

@johnnyw2001 Why do you want to pass the days as JSON? That enforces nothing. What are “days”? Integers 0 to 6? Names in English? Names in Spanish?

Just pass days you want to exclude as an array. How you represent days, I don’t know because you don’t say and I can’t really make sense of your code at 03:30.

public function scopeExcludeDays($query, array $days)
{
    return $query->whereNotIn('day', $days);
}

Please or to participate in this conversation.