How can i use Like in cake php - cakephp-2.1

i want the alternative cakephp code for the above query
Select * from book where title like '%java%;

OK, assuming you are using a find() query.
You can specify the conditions array as follows:
"conditions" => array("Book.title like" => "%java%")
or
"conditions" => array("Book.title like '%java%'")
I think both will work

Docu complex find conditions
$this->Post->find('first', array (
"Author.name" => "Bob",
"OR" => array (
"Post.title LIKE" => "%magic%",
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
)
));

Related

Laravel updateOrInsert with 'OR' or 'AND' operator in first arguments?

While it is possible to have multiple arguments for the updateOrInsert in Laravel query builder and what is the operator used by default.
For example in the documentation it is mentioned:
DB::table('users')
->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
Does that mean that email && name are checked or does it mean email || name is checked? How can we control it for one or the other if required?
Please forgive me if this is a silly question or if it is not worded as per the correct vocabulary, as I am new to Laravel. I couldn't find this information in the documentation or API.
updateOrInsert() method is used to update an existing record in the database if matching the condition or create if no matching record exists. Its return type is Boolean.
Syntax :
DB::table('blogs')->updateOrInsert(
[Conditions],
[fields with value]
);
In your query :
DB::table('users')->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
It will check if email == 'john#example.com' & name == 'john', then it will update votes=2.

updateOrCreate with increment in laravel

What I am trying to do is to update or insert the row in table. In my case, update looks something like this:
\DB::table('inventories')->where('product_code',$product_code)->increment('stock_current_quantity',$quantity);
I don't want to use if else statement. What I actually want is to integrate increment into following statement so it update as above statement.
\App\Inventory::updateOrCreate(['product_code' => $product_code], ['stock_current_quantity'=>$quantity]);
Thanks in advance!
Because google brought me here and I think the answers here, especially when you simply want to use updateOrCreate, are not as satisfying as this:
\App\Inventory::updateOrCreate([
'product_code' => $product_code
],
[
'stock_current_quantity' => \DB::raw('stock_current_quantity + 1')
]
);
Credits to this guy
Why not do:
$inventory = \App\Inventory::firstOrNew(['product_code' => $product_code]);
$inventory->stock_current_quantity = ($inventory->stock_current_quantity + $quantity);
$inventory->save();
If the model doesn't exists, $inventory->stock_current_quantity will only be equal to $quantity, else, it will increment it by $quantity.
I am using Laravel 7.8.1 and rolling it all into one statement as per the following works fine:
$user->league_entries()->updateOrCreate([
'month' => $month,
'year' => $year
])->increment('score');
just contributing if someone else has this problem
it doesn't exist, creates, but with zero
self::firstOrNew(['product_code' => $product_code]);
then, increment it... if other process updates it to 1 before me (in this middle time between firstOrNew and increment), this will update to 2, avoiding losing the prior update
self::where('product_code', $product_code)->increment('stock_current_quantity');
Similar to Inigo's answer, but slight change i would go with:
$user->league_entries()->firstOrCreate([
'month' => $month,
'year' => $year
])->increment('score');

Magento both AND and OR conditions in a collection

I want make a query which looks like below to filter some products (using attributes) from product collection.
SELECT <attributes>
FROM <tables & joins>
WHERE (<some AND conditions>) OR (<some AND conditions>)
WHERE condition should filter products that match either first set of AND conditions or second set of AND conditions.
Problem is I can't find a way to add an OR condition in between multiple AND conditions.
Can anyone help me to code above where condition using Magento addAttributeToFilter()? or any other functions?
If i'm understanding you correctly I think you need to do some variation of this:
->addAttributeToFilter(...filter here...)
->addAttributeToFilter(array(
array(
'attribute' => 'special_to_date',
'date' => true,
'from' => $dateTomorrow
),
array(
'attribute' => 'special_to_date',
'null' => 1
)
));
which would be:
...filter here... AND (special_to_date >= '2012-07-03' OR special_to_date IS NULL)...

How to get distinct values for non-key column fields in Laravel?

This might be quite easy but have no idea how to.
I have a table that can have repeated values for a particular non-key column field. How do I write a SQL query using Query Builder or Eloquent that will fetch rows with distinct values for that column?
Note that I am not fetching that column only, it is in conjunction with other column values, so distinct() might not really work. So that question basically can be how to specify the column that I want to be distinct in a query now that distinct() accepts no parameters?
You should use groupby. In Query Builder you can do it this way:
$users = DB::table('users')
->select('id','name', 'email')
->groupBy('name')
->get();
In Eloquent you can also query like this:
$users = User::select('name')->distinct()->get();
in eloquent you can use this
$users = User::select('name')->groupBy('name')->get()->toArray() ;
groupBy is actually fetching the distinct values, in fact the groupBy will categorize the same values, so that we can use aggregate functions on them. but in this scenario we have no aggregate functions, we are just selecting the value which will cause the result to have distinct values
Though I am late to answer this, a better approach to get distinct records using Eloquent would be
$user_names = User::distinct()->get(['name']);
**
Tested for Laravel 5.8
**
Since you wanna get all columns from the table, you can collect all of the data and then filter it using Collections function called Unique
// Get all users with unique name
User::all()->unique('name')
or
// Get all & latest users with unique name
User::latest()->get()->unique('name')
For more information you can check Laravel Collection Documentations
EDIT: You might have issue with perfomance, by using Unique() you'll get all data first from User table, and then Laravel will filter it.
This way isn't good if you have lots of Users data. You can use query builder and call each fields that you wanna use, example:
User::select('username','email','name')->distinct('name')->get();
Grouping by will not work if the database rules don't allow any of the select fields to be outside of an aggregate function. Instead use the laravel collections.
$users = DB::table('users')
->select('id','name', 'email')
->get();
foreach($users->unique('name') as $user){
//....
}
Someone pointed out that this may not be great on performance for large collections. I would recommend adding a key to the collection. The method to use is called keyBy. This is the simple method.
$users = DB::table('users')
->select('id','name', 'email')
->get()
->keyBy('name');
The keyBy also allows you to add a call back function for more complex things...
$users = DB::table('users')
->select('id','name', 'email')
->get()
->keyBy(function($user){
return $user->name . '-' . $user->id;
});
If you have to iterate over large collections, adding a key to it solve the performance issue.
Note that groupBy as used above won't work for postgres.
Using distinct is probably a better option - e.g.
$users = User::query()->distinct()->get();
If you use query you can select all the columns as requested.
$users = User::select('column1', 'column2', 'column3')->distinct()->get(); retrieves all three coulmns for distinct rows in the table. You can add as many columns as you wish.
I found this method working quite well (for me) to produce a flat array of unique values:
$uniqueNames = User::select('name')->distinct()->pluck('name')->toArray();
If you ran ->toSql() on this query builder, you will see it generates a query like this:
select distinct `name` from `users`
The ->pluck() is handled by illuminate\collection lib (not via sql query).
// Get unique value for table 'add_new_videos' column name 'project_id'
$project_id = DB::table('add_new_videos')->distinct()->get(['project_id']);
I had the same issues when trying to populate a list of all the unique threads a user had with other users. This did the trick for me
Message::where('from_user', $user->id)
->select(['from_user', 'to_user'])
->selectRaw('MAX(created_at) AS last_date')
->groupBy(['from_user', 'to_user'])
->orderBy('last_date', 'DESC')
->get()
Here are 3 ways I have tested that will give same result:
User::distinct()->get(['name'])->pluck('name');
User::select('name')->distinct()->pluck('name')->all();
DB::table('users')->select('name')->groupBy('name')->get()->pluck('name')->all();
For those who like me doing same mistake. Here is the elaborated answer
Tested in Laravel 5.7
A. Records in DB
UserFile::orderBy('created_at','desc')->get()->toArray();
Array
(
[0] => Array
(
[id] => 2073
[type] => 'DL'
[url] => 'https://i.picsum.photos/12/884/200/300.jpg'
[created_at] => 2020-08-05 17:16:48
[updated_at] => 2020-08-06 18:08:38
)
[1] => Array
(
[id] => 2074
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[created_at] => 2020-08-05 17:20:06
[updated_at] => 2020-08-06 18:08:38
)
[2] => Array
(
[id] => 2076
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[created_at] => 2020-08-05 17:22:01
[updated_at] => 2020-08-06 18:08:38
)
[3] => Array
(
[id] => 2086
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[created_at] => 2020-08-05 19:22:41
[updated_at] => 2020-08-06 18:08:38
)
)
B. Desired Grouped result
UserFile::select('type','url','updated_at)->distinct('type')->get()->toArray();
Array
(
[0] => Array
(
[type] => 'DL'
[url] => 'https://i.picsum.photos/12/884/200/300.jpg'
[updated_at] => 2020-08-06 18:08:38
)
[1] => Array
(
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[updated_at] => 2020-08-06 18:08:38
)
)
So Pass only those columns in "select()", values of which are same.
For example: 'type','url'. You can add more columns provided they have same value like 'updated_at'.
If you try to pass "created_at" or "id" in "select()", then you will get the records same as A.
Because they are different for each row in DB.
In my case (with Laravel 9), I need:-
to use where clause.
to get complete row.
to get unique entries for specific column.
As more complex query, but still, I have an easy approach. May be that help you also.
User::where('id',auth()->user()->id)->distinct('name')->get();

getting the value of array key in codeigniter

I have the following line in my controller:
$data['faq'] = $this->faqModel->get();
This data print the following using the print_r
Array
(
[faq] => Array
(
[0] => Array
(
[faqid] => 12
[catid] => 122
[question] => How this CMS works
[question_en] => How this CMS works
[answer] => How this CMS works?
[answer_en] => How this CMS works?
[sorder] => 2
[visible] => 1
)
[1] => Array
(
[faqid] => 8
[catid] => 121
[question] => How does the design cost?
[question_en] => How does the design cost?
[answer] => How does the design cost?
[answer_en] => How does the design cost?
[sorder] => 1
[visible] => 1
)
)
)
I want to use the value stored in the [catid] key, and I am trying to do something like:
$data['faq']['catid'] to get that value in the controller (I want to make another select with that value) But I am getting with this error message: Undefined index: catid
Anyone can help me to get the value of ['catid']???
Regards, Zoran
Its 3 dimensional array u look closely there is two elements in faq array. You must wrote something like this: $data['faq'][0]['catid'] or $data['faq'][1]['catid']
The way you are accessing the array is incorrect, you are missing the item index on the second level. The correct way to use it as you are doing would be to do
echo $data['faq'][0]['faqid']; //faqid of the first item
However, this will only show one faqid at a time, and it not so useful when you are iterating. So, a good way would be this way.
foreach($data['faq'] as $value) {
echo $value['faqid'];
}

Resources