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

Awilum's avatar

orWhere expression in Laravel Collections like it is in Doctrine

Hello!

Is there is analog of orWhere expression in Laravel Collections ? like it is in Doctrine ? https://www.doctrine-project.org/projects/doctrine-collections/en/latest/expressions.html#orwhere

0 likes
16 replies
Awilum's avatar

I don't think that I will able to use such constructions with anonymous functions inside twig templates

$filtered = $collection->reject(function ($value, $key) {
    return $value > 2;
});

as I do this with for e.g. where

{{ collect(entries.fetchCollection('movies/drama')).where('title', '=', 'Platforma').title }}
bugsysha's avatar

That kind of filtering should not happen in template in my mind.

Awilum's avatar

it is strange that I easily may do andWhere in Laravel Collections in this way where()->where()->where() but I can't do orWhere

bugsysha's avatar

To me, that does not make sense to have in a collection, but I might be wrong. Point is that I never had to reach for that kind of logic.

martinbean's avatar

@awilum Get the data you want and pass that to your template. Stop trying to do filtering in the template. That’s not the appropriate place to do so.

Awilum's avatar

so if there is no built in orWhere() method, how can I execute Laras filter() or reject() inside twig template to make it possible to use in one chain with others ?

btw: I am already pathing there a collect() function by my extension

<?php

declare(strict_types=1);

use Twig_Extension;
use Twig_SimpleFunction;
use Twig_Extension_GlobalsInterface;

class CollectionTwigExtension extends Twig_Extension
{
    /**
     * Flextype Dependency Container
     */
    private $flextype;

    /**
     * Constructor
     */
    public function __construct($flextype)
    {
        $this->flextype = $flextype;
    }

    /**
     * Callback for twig.
     *
     * @return array
     */
    public function getFunctions() : array
    {
        return [
            new Twig_SimpleFunction('collect', [$this, 'collect']),
        ];
    }

    public function collect($items)
    {
        return collect($items);
    }
}
sevenTopo's avatar

is that what your mean ?


$model1 = Model::where('att_a',$c)->orWhere('att_a',$b)->get();

Awilum's avatar

I am using Laravel collections in My Project + Twig

Awilum's avatar

with Doctrine COLLECTIONS I can do this:

{% set data = collect(entries.fetchCollection('movies/drama')).where('title', '=', 'Platforma').orWhere('country', '=', 'USA').all() %}

with Lara as I see I can't do this, because orWhere method does not exist in Laravel Collections

@bugsysha says that I should look into filter() or reject(). ok, how to use them inside twit templates ?

here:

{% set data = collect(entries.fetchCollection('movies/drama')).where('title', '=', 'Platforma').FILTER OR REJECT('country', '=', 'USA').all() %}
bugsysha's avatar

I haven't used Twig for years now so I can not help you. And that piece of logic is something I would never have in my template file. Move it at least to a controller.

martinbean's avatar

@awilum We get it. You’ve used Doctrine Collections. Laravel Collections have different methods, though.

Again, filter your data in a controller and then pass the results to your Blade/Twig/whatever view. This is basic MVC. You shouldn’t be doing filtering in a view. A view is meant to just display data. That’s why it’s called a view: because it’s a view of your application’s state at a particular moment in time.

So, to filter in a Laravel collection, if you want to find something that matches one of many conditions, you need to define that in a filter callback:

$results = $collection->filter(function ($item) {
    // Return true if you want this item included in the resultant collection
    return $item->title === 'Platforma' || $item->country === 'USA';
});
1 like
bugsysha's avatar

And that can be even shorter if you use short syntax introduced by PHP7.4

$results = $collection->filter(fn ($item) => $item->title === 'Platforma' || $item->country === 'USA');

Or you can provide invokable class

$results = $collection->filter(new FilterTitleAndCountry);

class FilterTitleAndCountry // ofc come up with better name
{
  public function __invoke(TypeHintHereForBetterAutoCompetion $item): bool
  {
    return $item->title === 'Platforma' || $item->country === 'USA';
  }
}

You can also improve encapsulation by adding methods

public function isPlatforma(): bool
{
  return $this->title === 'Platforma';
}

public function isUSA(): bool
{
  return $this->country === 'USA';
}

Then just use

return $item->isPlatforma() || $item->isUSA();
1 like

Please or to participate in this conversation.