query laravel not working if pass variable in Where NOT IN - php

I'm trying to filter items from a database table
what I do is get the ids that I want to exclude and then through -> whereNotIn in laravel, I pass the ids
$idcontracts=array();
$idbike=array();
$biciCorretta = array();
$findcontract=Contract::whereRaw('? between data_inizio and data_fine', [$datainizio])->whereRaw('? between data_inizio and data_fine', [$datafine])->get();
foreach ($findcontract as $key) {
if (!in_array($key->id,$idcontracts)) {
array_push($idcontracts,$key->id);
}
}
foreach ($idcontracts as $idcontract) {
$bike_contracts=DB::table('bike_contract')->where('contract_id',$idcontract)->get();
foreach ($bike_contracts as $bike_contract) {
if (!in_array($bike_contract->bike_id,$idbike)) {
array_push($idbike,$bike_contract->bike_id);
}
}
}
$notid=implode("', '",$idbike);
up to this point I have no problem.
the result of "implode" gives me the ids I want to remove
this is the result of $idbike and $notid:
this is the query I write to exclude the ids found:
$bikes = Bike::with('category')->whereNotIn('id', [$notid])->orderBy('category_id')->get();
the problem is that it doesn't exclude me the ids passed with $notid
but if I manually pass the ids, it removes them instead:
$bikes = Bike::with('category')->whereNotIn('id', [40,41,34,36,39])->orderBy('category_id')->get();
am I doing something wrong?

You shouldn't implode $notid, that makes it a string and Laravels whereNotIn() already does that for you.
->whereNotIn('id', $idbike)
And remove the $notid parameter, as it is not needed.

implode will return in string, and because of that it will not work correctly, you should pass it as array instead.

If you print data
$idbike =[40,41,34,36,39];
print_r($idbike);
Output will be Array
Array
(
[0] => 40
[1] => 41
[2] => 34
[3] => 36
[4] => 39
)
and if you print below code
$notid=[implode(",",$idbike)];
print_r($notid);
The output will be
Array
(
[0] => 40,41,34,36,39
)
So your query become
->whereNotIn('id', ["40,41,34,36,39"])
so laravel searching for id of "40,41,34,36,39". so its not returning result
So you can pass array directly to wherenotin
->whereNotIn('id', $idbike)

Laravel, whereNotIn method removes elements from the collection that have a specified item value that is contained within the given array. That means you have to pass an array
So, idbike is the array you mentioned
$bikes = Bike::with('category')->whereNotIn('id', idbike)->orderBy('category_id')->get();

Related

Laravel - how to group data by key and save to array?

I have table attribute_values(id, value, attr_group_id).
I need to return the collection grouped by key attr_group_id.
in clear php using ORM RedBean i made:
$data = \DB::table('attribute_values')->get();
$attrs = [];
foreach ($data as $k => $v){
$attrs [$v['attr_group_id']][$k] = $v['value'];
}
return $attrs;
I need same using Laravel, after this one:
$data = \DB::table('attribute_values')->get();
My table
id value attr_group_id
1 one 1
2 two 1
3 three 2
4 four 2
5 five 3
6 six 3
And i need result
Array(
[1] => Array
(
[1] => one
[2] => two
)
[2] => Array
(
[3] => three
[4] => four
)
[3] => Array
(
[5] => five
[6] => six
)
)
Fetch all data, and map it with attribute id of every row will work,
$data = \DB::table('attribute_values')->get();
$attrs = [];
foreach ($data as $key => $value) {
// -> as it return std object
$attrs[$value->attr_group_id][] = $value->value;
}
dd($attrs);
You can use the groupBy() function of collection as:
$data = \DB::table('attribute_values')->get()->groupBy('attr_group_id');
It merges records with same attr_group_id under this field's value as making key of the collection.
Doing all this in raw SQL will be more efficient, SQL database are quite good at these operations. SQL has a group by function, since you are overwriting value, i just get it out with max() (this seems weird, that you overwrite the value, do you actually just want unique results?).
DB::table('attribute_values')
->select('attr_group_id', DB::raw('max(value)'))
->groupBy('attr_group_id')
->get();
EDIT
Since the scope has changed, you can utilize Laravels Collection methods, that is opreations on a Collection.
DB::table('attribute_values')
->get()
->groupBy('attr_group_id')
->toArray();
Friends, this is a ready task that I needed !
I did it myself and you helped me. If anyone interested can read.
I'll explain to you why I needed this particular method. I am doing an online store with a clock and now there was a task to make filters and attributes for filters.
So there are three tables
attribute_groups table
attribute_products table
attribute_values
I need to display the Laravel widget on my .blade.php like as
{{ Widget::run('filter', 'tpl' => 'widgets.filter', 'filter' => null,]) }}
When i creating a new product in the admin panel.
I must to save the product id and attribute_id in attribute_products, but there can be as many attributes as possible for one product. so, if I'll use this option
$data = \DB::table('attribute_values')
->get()
->groupBy('attr_group_id')
->toArray();
I got result:
But! each new array starts with index 0. But I need an index that means its id. attr_group_id from table attribute_value for saving into attribute_products.
And after I see only one method for me.
$data = \DB::table('attribute_values')->get();
$attrs = [];
foreach ($data as $key => $value) {
$attrs[$value->attr_group_id][$value->id] = $value->value;
}
return $attrs;
and the result I was looking for
now you can see what's the difference and what was needed. Array index starts 1,2,3,4,5 and this index = attr_group_id. Unfortunately I could not initially ask the right question. thanks to all.
Laravel Version 5.8
So You need to Group the id
if You need in the Model Way I have created the Model as AttributeValue
$modelWay = \App\AttributeValue::get()
->groupBy('attr_group_id');
if You need in the DBWay I have created the table as attribute_values
$dbWay = \DB::table('attribute_values')
->get()
->groupBy('attr_group_id');
Both Will give the Same Result

Get the single element from the array

I got the following array (the array is retrieved through a db query). Now, my question is, how do I get a single element like e_domains from the array mentioned below:
stdClass Object
(
[id] => 1
[uni_origin] => Aachen
[e_domains] => rwth-aachen.de
)
I got the output shown above by running the following line of codes:
if ($results ) {
foreach ( $results as $result ){
echo'<pre>'; print_r($result) ;
}
}
First off, that's not an array, that's an object. Like it says: "stdClass Object".
Access object properties like this:
$object->property_name
In your case, it would be:
$result->e_domains
There are much more to learn on the subject, like static properties, visibility etc. In your case, the above example will work.
Read more about classes and objects in the manual: http://php.net/manual/en/language.oop5.basic.php
Try this:
$e_domains = mysql_result(mysql_query("SELECT id FROM games LIMIT 1"),0);
Hope it helpt.

Associative array from a database with codeigniter

On my models I try to write a php model that will get me a associative array from a database. But I don't quite know how to approach this.
So after I execute this SQL query:
SELECT balance_events.weight,balance_events.added_date,
balance_entries.mid FROM balance_events, balance_entries
WHERE balance_entries.added_date BETWEEN '2016-08-02' AND '2016-08-03'
AND balance_entries.ptid =12
AND balance_entries.beid = balance_events.id
I will get this table:
And from that table I want to extract a asociative array that it will look like this:
count = ['13'=>1, '6'=>4, '16'=>3, '4'=>3]
where 'mid'=>number of how many times that mid can be found in the table.
ex. mid '13'=>1 cause you can found it only once.
I think that I will have to use SQL COUNT function, but how I can aggregate all of this in a PHP model in codeigniter? I know how to configure controller and view, but I don't know how to actually do the actual php model that will get me the desired array.
Try this query may help you ,
$result = $this->db->select('balance_events.weight,balance_events.added_date,COUNT(balance_entries.mid) as mid_count')
->from('balance_events, balance_entries')
->where('balance_entries.added_date BETWEEN "2016-08-02" AND "2016-08-03" ')
->where('balance_entries.ptid','12')
->where('balance_entries.beid','balance_events.id')
->group_by('balance_entries.mid')
->get();
return $result->result_array();
I'm not sure how you would create this in SQL but since you tagged php, I wrote a function that would do just this.
<?php
$query = array(array("mid"=>13), array("mid"=>2), array("mid"=>13), array("mid" =>6), array("mid" => 13), array("mid" => 6));
function createMidArray($queryResult){
$returnArray = array();
foreach ($queryResult as $qr){
$returnArray[$qr['mid']]++;
}
return $returnArray;
}
print_r(createMidArray($query));
?>
The output of this was Array ( [13] => 3 [2] => 1 [6] => 2 ) which matches up to my inputted $query (which is a 2D array). I'm expecting the output of your query is stored in a similar array, but with more data and keys

Yii2 array of objects, find the one

I have an array in yii2, and ocassionally it's only 1 single object that is not empty (all other element of array is empty) and I don't know which one is it. How can I either find the one that is not empty, or (my idea what I was trying), to create a new array, with array_filter (but I'm not sure if it works also with array of objects), to have only the one object in it.
if (count($ttepk) == 1) {
$ttep_filtered[] = array_filter($ttepk);
$id = $ttep_filtered[0]->id;
}
But it was also not working. I get the error message: PHP Notice – yii\base\ErrorException Trying to get property of non-object.
Before array_filter it looks like this:
Array
(
[3] => app\models\Model Object
(
after array_filter:
Array
(
[0] => Array
(
[3] => app\models\Model Object
(
So it seems, array_filter is not the one I need, or I use it the wrong way.
Can you please help me? Thank you!
You can try something like this
$filtered = array_filter($ttepk, function($item) {
return $item instanceof app\models\Model;
});
if (count($filtered) == 1) {
$id = reset($filtered)->id;
}

Apply function to every array key

I am using Cassandra and I have saved some byte representations as ID. Everything is working fine, however that data (id) is no good for output.
$users = $db->get('1');
echo '<pre>';
print_r($users);
die();
Outputs
Array
(
[��� X��W��c_ ] => Array
(
[id] => ��� X��W��c_
[name] => steve
[surname] => moss
)
[�*B�X��y�~p��~] => Array
(
[id] => �*B�X��y�~p��~
[name] => john
[surname] => doe
)
)
As you can see ID's are some wierd characters, it's because they are byte representations in database. They actually look like \xf5*B\xa0X\x00\x11\xe1\x99y\xbf~p\xbc\xd1~.
In PHPCASSA there is function CassandraUtil::import(); to which I can pass these bytes and it will return guid. It works fine, but I want my array to automatically converted from bytes to guids.
Only option I find is looping through every item in array and assigning new value to it. Somehow I think that it is not the best approach. Is there any other ways to do this?
TL;DR
Have array with bytes like above, need to use CassandraUtil::import(); on array keys and id's to get readable id's. What is the most effective way of doing so.
UPDATE
Sorry, only saw the top level array key, I think you would have to run the function below as well as another one after:
function cassImportWalkRecur(&$item, $key)
{
if ($key == 'id')
$item = CassandraUtil::import();
}
$array = array_walk_recursive($array, 'cassImportWalkRecur');
That should apply it to the ID fields. If you need to check the data first, there maybe a way to detect the encoding, but I am not sure how to do that.
You should be able to create a function and use array_walk to traverse the array and update the keys. Something like:
function cassImportWalk($item, &$key)
{
$key = CassandraUtil::import();
}
$array = array_walk($array, 'cassImportWalk');
Untested (also you may have to change the CassandraUtil usage), but should work.
Unless I am misunderstanding the question this can be done simply and cleanly like so:
$users = $db->get('1');
$keys = array_keys($users);
$readableKeys = array_map("CassandraUtil::import",$keys);
foreach($users as $currentKey => $subArray) {
$readableKey = array_shift($readableKeys);
$subArray['id'] = $readableKey;
$users[$readableKey] = $subArray;
unset($users[$currentKey]);
}
Would array_flip() all keys and values, then array_walk() and apply my function, before doing a final array_flip().

Categories