laravel add multiple where and or where - mysql

[
[
[
'condition1',
'value1',
],
[
'condition2',
'value2',
],
[
'condition3',
'value3',
],
],
[
'condition4',
'value4',
],
[
]
]
Im trying to build query builder with values 1 ,values 2, value 3 are in 'or' condition and value 4 in 'and' condition
for first two array i can get the result like what i need
$result = DB::table('table')
->where(function($query) use($value1) {
$query->where('condition1', $value1) // and condition
->orWhere('condition2', $value2) // rest or in or condition
->orWhere('condition3', $value3)
})
->where('condition4', $value4)
->get();
But the array will be keep going. inside the array index 0 is in 'and' condition and a;; other index in or condition
I have tried like
foreach($values as $value){ //
$result->where(function ($qry) use ($value) {
foreach($value as $index=>$val){
$qry->when($index==0),function($qyr){
$qry->where();
}
},function($qry){
$qry->orwhere();
}
});
}
Is there any better solution or improvement i can add?

You should not have condition3 in the grouping query. Normaly it should look like this:
$result = DB::table('table')->where(function($query) use($value1, $value2) {
$query->where('condition1', $value1) // where condition1
->orWhere('condition2', $value2); // or where condition2
})->Where('condition3', $value3) // And where condition3
->get();

Related

Loop on a variable delimited with gamma using Laravel 8

I have in my database values with this form :
["email1#gmail.com","email2#gmail.com"]
I'm using laravel and I want to loop on this variable to get each element for example get the element : email1#gmail.com.
I tried the following code :
I have the following array :
$emails :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["email3#gmail.com","email4#gmail.com"]"
]
So I'm using the following code to get each element :
$var = array();
foreach ($emails as $key => $value) {
$var[] = $value;
}
I get the following result :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["email3#gmail.com","email4#gmail.com"]"
]
If you have any idea , please help
UPDATE
I have the following array :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["hajar.boualamia33#gmail.com","guernine.khadija#gmail.com"]"
]
And I did the following method :
$emailss = collect($emails)->flatten()->all();
dd($emailss);
I get the following result :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["hajar.boualamia33#gmail.com","guernine.khadija#gmail.com"]"
]
Update
Ha, tricky one. It seems that you have a PHP expression (an array) stored. So in order to extract the arrays, we need to evaluate them first.
Try this instead:
$elements = [
"['email1#gmail.com','email2#gmail.com']",
"['email3#gmail.com','email4#gmail.com']",
];
$emails = collect($elements)
->map(function ($element) {
return (eval("return \$element = " . $element . ';'));
})
->flatten()
->all();
Try this:
$elements = [
['email1#gmail.com','email2#gmail.com'],
['email3#gmail.com','email4#gmail.com'],
];
$emails = collect($elements)->flatten()->all();
This will get you:
=> [
"email1#gmail.com",
"email2#gmail.com",
"email3#gmail.com",
"email4#gmail.com",
]
Check this method on the docs.

Laravel: Update a nested json object

I have a column in my db for saving a users' settings. This is what the data structure looks like:
{"email":{"subscriptions":"{\"Foo\":true,\"Bar\":false}"}}
I am using a vue toggle to change the status of each property (true/false). Everything seems to be working, however when I save, I am wiping out the structure and saving the updated values like this:
{\"Foo\":true,\"Bar\":false}"}
php
$user = auth()->user();
$array = json_decode($user->preferences['email']['subscriptions'], true);
dd($array);
The above gets me:
array:2 [
"Foo" => true
"Bar" => false
]
So far so good...
$preferences = array_merge($array, $request->all());
dd($preferences);
Gets me:
array:2 [
"Foo" => true
"Bar" => true
]
Great - the values are now picking up the values passed in from the axios request. Next up; update the user's data:
$user->update(compact('preferences'));
Now my data looks like this:
{"Foo":true,"Bar":true}
The values are no-longer nested; I've wiped out email and subscriptions.
I've tried this:
$user->update([$user->preferences['email']['subscriptions'] => json_encode($preferences)]);
But it doesn't seem to save the data. How can I use the $preferences variable to update the data - and keep the data nested correctly?
You can create an array with the structure you want the resulting json to have. So, for this json:
{
"email":{
"subscriptions":{
"Foo":true,
"Bar":false
}
}
}
you can create an array like this:
[
'email' => [
'subscriptions' => [
'Foo' => true,
'Bar' => false
]
]
]
an then, encode the entire structure:
json_encode([
'email' => [
'subscriptions' => [
'Foo' => true,
'Bar' => false
]
]
]);
So, in your code, as you already have the nested array in the $preferences variable, I think this should work:
$json_preferences = json_encode([
'email' => [
'subscriptions' => $preferences
]
]);
Then you can update the user 'preferences' attribute (just for example):
User::where('id', auth()->user()->id)->update(['preferences' => $json_preferences]);
or
$user = auth()->user();
$user->preferences = $json_preferences;
$user->save();

json search using laravel query builder issues

["php", "css", "Mysql"]
["html", "css", "js"]
["js","css"]
This is value for 'keywords' field in 3 records
I need search result for this
["php","css"]
ie, result should contain the above 3 record as there is 'php' in 1st record and 'css' in other 2 records
SELECT * FROMjob_postsWHERE JSON_CONTAINS(keywords, '["php","css"]')
only giving the 1st record
array:2 [
0 => "php"
1 => "css"
]
Made use of array instead of json_encoded format($request['keywords] itself)
DB::table('job_posts')
->when($keywords, function ($query) use ( $keywords) {
foreach ($keywords as $key => $value) {
$query->orWhere('keywords', 'LIKE', '%' . $value . '%');
}
}
->get();

Getting key value pair array in Yii2

$data = User::find()
->select('id, name')
->where(['status' => 'active'])
->orderBy('id DESC')
->asArray()
->all();
[
[0]=>[
id=>1
name="test"
]
[1]=>[
id=>2
name="test1"
]
]
What I want is array which looks similar to this. Mapping the id with name so it can be accessed and checked.
[
[1]=>'test'
[2]=>'test1'
]
Instead of using the ArrayHelper you can directly achieve the desired output by using indexBy() and column() within your query:
$data = User::find()
->select(['name', 'id'])
->where(['status' => 'active'])
->orderBy(['id' => SORT_DESC])
->indexBy('id')
->column();
indexBy() defines the array key, while column() will take the first column in the select condition as value.
Try this
Add the below namespace and use the arrayhelper of Yii2 to map
use yii\helpers\ArrayHelper
$userdata = ArrayHelper::map($data, 'id', 'name');

search for multiple keywords in the same field in Yii2

I need to search several key words that appear in the same database field. For example if field contains "The quick brown fox jumps over the lazy dog" and someone searches for "quick" and "dog" this should be returned as a match.
so I take the search field and explode it into an array based on spaces:
$terms = explode( " ", $this->search_term );
Then I thought I'd throw this into a loop:
foreach ($terms as $key) {
$query->andFilterWhere( [
'or',
[ 'like', 'item.name', $key ],
] );
}
However this isn't working, plus it's not very elegant.
You should simply build properly the condition parameter, e.g. :
$condition = ['or'];
foreach ($terms as $key) {
$condition[] = ['like', 'item.name', $key];
}
$query->andWhere($condition);
I think you have to join the conditions by using or conditions.
foreach ($terms as $key) {
$query->orFilterWhere( [
'or',
[ 'like', 'item.name', $key ],
] );
}
This is how you have to add another or conditions. See here for further details.
I guess there is no other ways to do this without doing for loop.