How to make Laravel whereIn not sorted automatically - php

my array from $temp is Array ( [0] => 22 [1] => 26 [2] => 20 [3] => 24 ) or 22|26|20|24
when I use whereIn like this
$robjeks = DB::table('objek')->whereIn('id', $temp)->get();
the result is 20|22|24|26|
it's automatically sorted. I want it's not sorted.
how to make it same like 22|26|20|24?
thanks for your attention.

This has nothing to do with Laravel. Read here first: avoid Sorting by the MYSQL IN Keyword
Then, to do this, you can use this code:
$temp = [22, 26, 20, 24];
$tempStr = implode(',', $temp);
$robjeks = DB::table('objek')
->whereIn('id', $temp)
->orderByRaw(DB::raw("FIELD(id, $tempStr)"))
->get();
You might be in risk with sql injection in this case, so please sanitize the array of numbers accordingly.
Ref: Laravel: order by where in

I think it has more to do with SQL rather than Laravel. If you are using autoincrement id, then obviously 22 is found before 26. If you want to change that you may follow this link:
Laravel: order by where in
Or manually order your query yourself. eg.: ->orderBy('name') or something else.

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

how to avoid duplicate slugs when saving a friendly url

sorry but I'm new, a true apprentice of the php. Sorry for my English, but I'm Italian.
I'm trying to figure out how to avoid saving duplicates in the slug column of my database when I save.
When I save a new page I check in the database if I find a line with the slug I would like to save. If it is not there, I proceed without problems. If there is instead I would like to save it by adding "1" and then "2" and so on.
I'v tried with
$string="example-2";
$string= str_replace("-", "", $string);
$string=filter_var($string, FILTER_SANITIZE_NUMBER_INT);
and works but but if I save a slug like this:
$string="my2example-2";
It' doesn't work
I can not understand how to do in php to analyze the string and understand if there is already a number at the end of the string.
Example:
the first time i save a sulg 'example'.
Then I want to save a second page with the "exemple" slug, so I look in the database, I find that there is "exemple" then I add "-1" to my string and save it as "example-1".
Then I want to save "exemple" again, I find it exists "example". So i have to search to look for "exemple-1"
How to do it?
and than how do I then identify what number I have arrived to save
"exemple-2"?
thanks
You should keep the original slug then each time you check the DB for an existing entry append -1, -2 etc until you get no matches.
$i = 1;
$baseSlug = $slug;
function slug_exists($slug) {
$query = "SELECT `slug` FROM `table` WHERE `slug`=?";
$stmt = $dbl->prepare($query);
$stmt->bind_param("s", $slug);
$stmt->execute();
if ($stmt->num_rows > 0) {
return true;
} else {
return false;
}
}
while(slug_exist($slug)){
$slug = $baseSlug . "-" . $i++;
}
// Save slug in DB
Instead of querying your database to determine if slug example exists, you can get all slugs that starts with example:
SELECT slug FROM table WHERE slug LIKE 'example%';
Then you just need to filter out values that aren't example or example-[0-9]+. In some databases you can do it directly, but you can also do it with regex in PHP. Last thing is to find slug with highest number (for example by sorting first), and incrementing the numeric part.
Ensure that you're using natural sort ordering
Example from above link:
<?php
$array1 = $array2 = array("img12.png", "img10.png", "img2.png", "img1.png");
asort($array1);
echo "Standard sorting\n";
print_r($array1);
natsort($array2);
echo "\nNatural order sorting\n";
print_r($array2);
?>
results:
Standard sorting
Array
(
[3] => img1.png
[1] => img10.png
[0] => img12.png
[2] => img2.png
)
Natural order sorting
Array
(
[3] => img1.png
[2] => img2.png
[1] => img10.png
[0] => img12.png
)

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

MySQL & PHP - Looping a query AND "mapping" the results of each loop to a unique array WITHOUT "MySQL" functions

I'll note that this is a very special case, hence the question to begin with. Under normal circumstances, such a function would be simple:
I have an array named $post_id, which contains 5 values
(Each numerical)
In order to print each value in the array, I use the following loop:
.
for ($i = 0; $i < $num; $i++)
{
echo $post_id[$i] . ' ';
}
...Which prints the following: 49, 48, 47, 46, 43
3. In my database, I have a table that looks like this:
post_categories
_____________________
post_id | category
__________|__________
43 | puppies
43 | trucks
46 | sports
46 | rio
46 | dolphins
49 | fifa
4. So, using the data in the array $post_id, I'd like to loop a database query to retrieve each value in the category column from the post_categories table, and place them into uniquely named arrays based on the "post id", so that something like...
echo $post_id_49[0] . ' ', $post_id_46[1];
...Would print "fifa rio", assuming you use the above table.
An example of such a query:
//Note - This is "false" markup, you'll find out why below
for ($i = 0; $i < $num; $i++)
{
$query = "SELECT category FROM post_categories WHERE post_id = $post_id[$i]";
fakeMarkup_executeQuery($query);
}
Why is this a "special" case? For the same reason the above query is "false".
To elaborate, I'm working inside of a software package that doesn't allow for "normal" queries so to say, it uses it's own query markup so that the same code can work with multiple database types, leaving it up to the user to specify their database type which leaves the program to interpret the query according to the type of database. It does, however, allow the query to be stored in the same "form" that all queries are, like "$result = *query here*" (With the only difference being that it executes itself).
For that reason, functions such as mysql_fetch_array (Or any MySQL/MySQLi function akin to that) cannot, and will not work. The software does not provide any form of built in alternatives either, effectively leaving the user to invent their own methods to achieve the same results. I know, pretty lame.
So, this is where I'm stuck. As you'd expect, all and any information you find on the Internet assumes you can use these MySQL & MySQLi functions. What I need, is an alternative method to grab one array from the results of a looped query per loop. I simply cannot come to any conclusion that actually works.
tl;dr I need to be able to (1) loop a query, (2) get the output from each loop as it's own array with it's own name, and (3), do so without the use of functions like mysql_fetch_array. The query itself does not actually matter, so don't focus on that. I know what do with the query.
I understand this is horrifically confusing, long, and complicated. I've been trudging through this mess for days - Close to the point of "cheating" and storing the data I'm trying to get here as raw code in the database. Bad practice, but sure as heck a lot easier on my aching mind.
I salute any brave soul who attempts to unravel this mess, good luck. If this is genuinely impossible, let me know so that I can send the software devs an angry letter. All I can guess is that they never considered that a case like mine would come up. Maybe this is much more simple then I make it to be, but regardless, I personally cannot come to an logical conclusion.
Additional note: I had to rewrite this twice due to some un explained error eliminating it. For the sake of my own sanity, I'm going to take a break after posting, so I may not be able to answer any follow up questions right away. Refer to the tl;dr for the simplest explanation of my need.
Sure you can do this , here ( assuming $post_ids is an array of post_id that you stated you had in the OP ), can I then assume that I could get category in a similar array with a similar query?
I don't see why you couldn't simply do this.
$post_id = array(49, 48, 47, 46, 43);
$result = array();
foreach($post_id as $id)
{
//without knowing the data returned i cant write exact code, what is returned?
$query = "SELECT category FROM post_categories WHERE post_id = $id";
$cats = fakeMarkup_executeQuery($query);
if(!empty($cats)) {
if(!isset($result[$id])){
$result[$id] = array();
}
foreach( $cats as $cat ){
$result[$id][] => $cat;
}
}
}
Output should be.
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
Ok, assuming you can run a function (we'll call it find select) that accepts your query / ID and returns an array (list of rows) of associative arrays of column names to values (row), try this...
$post_categories = [];
foreach ($post_id as $id) {
$rows = select("SOME QUERY WHERE post_id = $id");
/*
for example, for $id = 46
$rows = [
['category' => 'sports'],
['category' => 'rio'],
['category' => 'dolphins']
];
*/
if ($rows) { // check for empty / no records found
$post_categories[$id] = array_map(function($row) {
return $row['category'];
}, $rows);
}
}
This will result in something like the following array...
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)

Multiple foreach to process nested arrays -- PHP CodeIgniter

I would first like to thank you for taking the time to look at my question--I am quite novice at PHP/CodeIgniter programming, however, I enjoy it very much.
What I am trying to do:
1) Retrieve each CompanyId associated with the company when the user is logged in. I achieve this by passing the $CompanyId (in my controller) from the session as a parameter to a query in my model. I have this working well as such:
// Assign query result to array to be used in view
$data['campaigns'] = $this->model_record->retrieve_campaign($CompanyId);
2) The return value is an array nested as such:
Array (
[campaigns] => Array (
[0] => Array (
[CampaignId] => 1
[DID] => 2394434444
[FWDDID] => 3214822821
[ProductId] => 1
[CampaignName] => Fort Myers Bus #1
[ProductName] => CallTrack - Sharktek
[Active] => 1
[CompanyId] => 1 )
)
3) Once this is processed, I am trying to create a for each loop that queries each CampaignId through another query in my model. Due to the MVC pattern I am implementing, I have to pass the results of this query to my $data array to send to the view.
foreach($data['campaigns'] as $campaign) {
$ids[] = $campaign['CampaignId'];
}
foreach ($ids as $row) {
$data['ids'] = $this->model_record->week_data(0,$row, $StartDate);
}
4) I am then trying to test view all the results of my queries in my view, however, I am only receiving one value, but when I echo the results of the foreach of the CampaignIds, it they all show up. Does anyone have any suggestions?
<?php
foreach($ids as $row):
echo $ids['MyCount'];
endforeach
?>
5 Extra) I have not begun to approach this yet, but once I get this working, I would like to run the query week_data 7 times as it is returning the data for each day of the week. My assumption is that I would place a for loop until it hits 7, is this correct?
Thank you again, for attempting to help me--I greatly appreciate the work many of you put into this community.
This line:
$data['ids'] = $this->model_record->week_data(0,$row, $StartDate);
Should look like:
$data['ids'][] = $this->model_record->week_data(0,$row, $StartDate);
As it is, the first line overwrites $data['ids'] until all you're left with is the last one. You need to add them to an array to collect all of them.

Categories