You can do that with filter() or reject().
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
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 }}
That kind of filtering should not happen in template in my mind.
it is strange that I easily may do andWhere in Laravel Collections in this way where()->where()->where() but I can't do orWhere
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.
@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.
it is not an answer, I can do this in Craft CMS for e.g. https://docs.craftcms.com/v3/dev/element-queries/ or with Doctrine collections https://www.doctrine-project.org/projects/doctrine-collections/en/latest/expressions.html#orwhere
both in TWIG templates can by executable
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);
}
}
is that what your mean ?
$model1 = Model::where('att_a',$c)->orWhere('att_a',$b)->get();
So you are using Twig with Laravel?
I am using Laravel collections in My Project + Twig
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() %}
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.
okey lets forget about TWIG,
how to do this on PHP side ?
With Doctrine Collections I can do this:
https://www.doctrine-project.org/projects/doctrine-collections/en/1.6/expressions.html#orwhere
$criteria->where($expr1);
$criteria->andWhere($expr2);
$criteria->orWhere($expr3);
How to do this with Laravel Collections ?
@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';
});
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();
Please or to participate in this conversation.