How i can filter a collection with a where like query on Laravel? - php

I have the following array:
$elements = collect([
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
]);
I need to filter by approximation, but just using the collection data, something like:
$elements->where('name', 'LIKE', 'De%')->values()->all();
Actually i can filter the data, but with a normal filter (where), this does not work for me because it find the exact coincidences. So, if i use a normal filter i have to say the exactly value to match:
$elements->where('name', 'Desk');
How i can made a query to the array data using something like a "Where LIKE" clausule?

You can use filter function in collection and in closure use preg_match php function to check if it exist in name parameter like this:
$name='de';
$elements->filter(function ($item) use($name){
return preg_match("/$name/",$item['name']);
});

Related

title does not exist on the Eloquent builder instance

I know there is question about this but there is not solution that helps me. So, i have table 'About' in database and model About.php. I want retrieve only one column from db such as title, and use this codes:
$abouts = About::orderBy('created_at', 'desc');
return view('about')->with('abouts', $abouts);
and in view:
{{$abouts->title}}
and how solve this problem. i don't want to use foreach loop. is it possible? how?
try Pluck()
The pluck method retrieves all of the values for a given key:
$collection = collect([
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$plucked = $collection->pluck('name');
$plucked->all();
// ['Desk', 'Chair']
in controller:
$titles = About::orderBy('created_at', 'desc')->pluck('title')->all();
return view('about')->with('titles');
in blade use:
{{$titles[0]}}
ref: https://laravel.com/docs/9.x/collections#method-pluck

Return only certain data in from a collection - Laravel

I'm learning Laravel and have created a public endpoint where I want to output only certain information of some comments if a user is not authenticated from a GET request.
I have managed to filter out the comments based on whether or not they are approved. I now want to filter out the data that is returned. I have attached a screenshot of what is currently returned.
Ideally, I only want to return the id, name and the body in the json. How can I go about this? I tried the pluck() method which did not give the desired results. Any pointers would be greatly appreciated
public function index(Request $request)
{
if (Auth::guard('api')->check()) {
return Comment::all();
} else {
$comments = Comment::where('approved', 1)->get();
return $comments->pluck('id','name','body');
}
}
To select the particular columns, you can pass columns name to get as
$comments = Comment::where('approved', 1) -> get(['id','name','body']);
You can use a transformer to map the incoming data to a sensible output based on the auth state. The following example comes from the Fractal lib:
<?php
use Acme\Model\Book;
use League\Fractal;
$books = Book::all();
$resource = new Fractal\Resource\Collection($books, function(Book $book) {
return [
'id' => (int) $book->id,
'title' => $book->title,
'year' => $book->yr,
'author' => [
'name' => $book->author_name,
'email' => $book->author_email,
],
'links' => [
[
'rel' => 'self',
'uri' => '/books/'.$book->id,
]
]
];
});
Ideally, you would create 2 classes that extend from Transformer and pass the correct one to the output.
If you want to pass the result as json respose
$comments = Comment::where('approved', 1)->pluck('id','name','body')->toArray();
return Response::json($comments);
If you want to pass the result as to blade
$comments = Comment::where('approved', 1)->pluck('id','name','body')->toArray();
return view('your_blade_name')->with('comments',$comments);

Yii2 Query class does not return additional columns

I've got something like this
$query = Customer::find()
->select(['customer.name', 'surname', 'cityName' => 'cities.name', 'streetName' => 'streets.name'])
->joinWith(['city', 'street'])
->where(['group_id' => $id]);
When i do
return $query->all();
it returns only columns from customer table, but when i do something like this
$raw = $query->createCommand()->getRawSql();
return \Yii::$app->user_db->createCommand($raw)->queryAll();
it returns me all 4 columns. Why orm fails?
I'm using custom db connection (user), dynamicly connected after authorization. Anyway ActiveRecord->getDb() has been customized too and it works well till now.
it returns only columns from customer table, but when i do something like this.
Yes, that's right. Because Yii2 AR(Active Record) is ORM pattern. And it's try to return all result off query like object.
So, I will not tell the theory, I'd better suggest a solution variant:
$query = Customer::find()
->joinWith(['city', 'street'])
->where(['group_id' => $id])
->asArray()
->all();
return $query;
It's from Yii2 docs(performance tuning).
The result will be like:
[
all data selected from "customer",
['city' => all data selected from city joinWith],
['street' => all data selected from street joinWith]
]
I think, this is exactly what you need.
But, if you need objects. You can try marge objects to only one array.
$customer = Customer::find()
->joinWith(['city', 'street'])
->where(['group_id' => $id])
->all();
return [
'customer' => $customer,
'city' => $customer->city,
'street' => $customer->street,
];
you are using
->select(['customer.name', 'surname', 'cityName' => 'cities.name', 'streetName' => 'streets.name'])
so you will get selected columns only.
use,
$query = Customer::find()
->joinWith(['city', 'street'])
->where(['group_id' => $id])
->all();
this will give you all the columns

Convert a collection into an Eloquent object

Currently I'm using the Xero API inside Laravel 5.2. I would like to use the power of Eloquent with this data.
Actually I can recover invoices and even filter them using chaining methods as shown:
$invoices = XeroPrivate::load('Accounting\\Invoice')
->where('Status', 'DRAFT')
->execute();
If I do a var_dump, I get this kind of data:
object(XeroPHP\Remote\Collection)[173]
public 0 =>
object(XeroPHP\Models\Accounting\Invoice)[171]
protected '_data' =>
array (size=31)
'Type' => string 'ACCPAY' (length=6)
'Contact' =>
Eloquent chaining methods would let me to execute things like this. Currently it fails:
$invoices = XeroPrivate::load('Accounting\\Invoice')
->where('Date','>','2016-03-20')
->execute();
Checking Laravel's docs, it is supposed I could convert into a collection with collect:
$collection = collect($invoices);
$collection does not solve the problem. Now data structure is different but still can't use Eloquent. Now data is:
object(Illuminate\Support\Collection)[163]
protected 'items' =>
array (size=24)
0 =>
object(XeroPHP\Models\Accounting\Invoice)[171]
protected '_data' =>
array (size=31)
But it is shown data is Illuminate\Support\Collection and seems to be right.
Thanks!
You can take a single item of the collection by using first() method.
$entity = $collection->first();
You can find more information here about what methods you have available of Illuminate\Support\Collection.

Yii CGridView filter, modify data before filtering

One field in CGridView is a 'quota' field with a value in bytes. To make it human-readable, I'm using CFormatter:
'columns' => array(
...
array(
'name' => 'quota',
'value' => function($data) {
return Yii::app()->format->formatSize($data->quota);
},
),
),
Now I'd like to filter data in this column by megabytes. I've modified the search() method in model like this:
$criteria->compare('(quota / 1024 / 1024)',$this->quota,true);
but I don't like how it looks like. Is there a normal workaround?
Thank you.
Instead of
array(
'name' => 'quota',
'value' => function($data) {
return Yii::app()->format->formatSize($data->quota);
},
),
You could simply do:
'quota:size',
Now, to answer your question, using the compare function is wrong, as it adds a "WHERE" clause to the SQL query. You are looking to do a sort instead using the order property:
$criteria = new CDbCriteria;
$criteria->order = "quota DESC";
EDIT (after your comment):
$criteria = new CDbCriteria;
$criteria->addCondition('quota > '.intval($this->quota)*1024*1024);

Categories