I have a products table:
products
-id
-name
-image
And a product_atts table:
product_attributes
-product_id (FK)
-size (1, 2)
-memebership (1, 2, 3, 4, 6, 11)
-price
Now, when querying the product_attributes table and joining the products table, I get all of the variations:
Array
(
[0] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 1
[membership] => 1
[price] => 0.00
)
[1] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 1
[membership] => 2
[price] => 0.00
)
[2] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 1
[membership] => 3
[price] => 0.00
)
[3] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 1
[membership] => 4
[price] => 0.00
)
[4] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 1
[membership] => 6
[price] => 0.00
)
[5] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 1
[membership] => 11
[price] => 0.00
)
[6] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 2
[membership] => 1
[price] => 0.00
)
[7] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 2
[membership] => 2
[price] => 0.00
)
[8] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 2
[membership] => 3
[price] => 0.00
)
[9] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 2
[membership] => 4
[price] => 0.00
)
[10] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 2
[membership] => 6
[price] => 0.00
)
[11] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => 2
[membership] => 11
[price] => 0.00
)
)
Is there a way that I can get a result that looks like this:
Array
(
[0] => stdClass Object
(
[name] => Product 1
[image] => Product1.png
[size] => stdClass Object
(
[0] => 1,
[1] => 2
)
[membership] => stdClass Object
(
[0] => 1,
[1] => 2,
[2] => 3,
[3] => 4,
[4] => 6,
[5] => 11
)
[price] => 0.00
)
)
It makes it so much easier to then use this data in my UI, etc.
You might not already have realized it but using Eloquent, you already have everything this way. As soon as you create your relationships in your models, you just need a root model to reach every single one related to it.
Let's say that you have your Product model:
<?php
class Product extends Eloquent {
}
and your Products Details model:
<?php
class ProductDetail extends Eloquent {
}
So you can build a relation between them
class Product extends Eloquent {
public function details()
{
return $this->hasMany('ProductDetail');
}
}
And now if your controller pass to your UI a list of models:
public function index()
{
return View::make('site.products')->with('products', Product::all());
}
In your UI you'll be able to:
<ul>
#foreach($products as $product)
<li>
<p>Product: $product->name</p>
<p>Sizes:</p>
<ul>
#foreach($product->details as $detail)
<li>
{{$detail->size}}
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
Related
I have this query from first table:
$this->db->table('categories')
->select('id, name, parent_id')
->orderBy('parent_id')
->get()
->getResultObject();
data output is:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => cat1
[parent_id] => 0
)
[1] => stdClass Object
(
[id] => 2
[name] => cat2
[parent_id] => 0
)
[2] => stdClass Object
(
[id] => 5
[name] => cat5
[parent_id] => 0
)
[3] => stdClass Object
(
[id] => 6
[name] => cat6
[parent_id] => 0
)
[4] => stdClass Object
(
[id] => 3
[name] => cat3
[parent_id] => 2
)
[5] => stdClass Object
(
[id] => 4
[name] => cat4
[parent_id] => 2
)
)
and query for second table:
$this->db->table('post_category')
->select('category_id')
->where('post_id', $id)
->get()->getResultObject();
output data is:
Array
(
[0] => stdClass Object
(
[category_id] => 1
)
[1] => stdClass Object
(
[category_id] => 4
)
)
Now I need to add selected in array and add data(category_id) from table two in table one if (category_id = id) like this:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => cat1
[parent_id] => 0
[selected] => 1
)
[1] => stdClass Object
(
[id] => 2
[name] => cat2
[parent_id] => 0
[selected] =>
)
[2] => stdClass Object
(
[id] => 5
[name] => cat5
[parent_id] => 0
[selected] =>
)
[3] => stdClass Object
(
[id] => 6
[name] => cat6
[parent_id] => 0
[selected] =>
)
[4] => stdClass Object
(
[id] => 3
[name] => cat3
[parent_id] => 2
[selected] =>
)
[5] => stdClass Object
(
[id] => 4
[name] => cat4
[parent_id] => 2
[selected] => 1
)
)
How do can i add data from table two in table one(if category_id from table two = id from table one) like my last output?!
If you just want to populate the ['selected'] item of a subarray in the first array ("categories") with "1" based on whether there's a "post_category" with that value you can do this:
foreach ($categories as &$category) {
$filtered_post_categories = array_filter($post_categories, function($post_category) use ($category) {
return $post_category->category_id == $category->id;
});
if (count($filtered_post_categories) > 0) {
$category->selected = 1;
}
else {
$category->selected = null;
}
}
My table structure is like this:
id | category | parent |
See image of table for categories
My Modal code:
public function getData($table)
{
return $this->db->select('*')->get($table)->result_array();
}
I get an array like this:
Array
(
[0] => Array
(
[id] => 1
[name] => Mobile Phones
[parent] => 0
[date] => 2017-05-16 08:55:22
[slug] => mobile-phones
)
[1] => Array
(
[id] => 2
[name] => Samsung
[parent] => 1
[date] => 2017-05-16 08:55:29
[slug] => samsung
)
[2] => Array
(
[id] => 3
[name] => Apple
[parent] => 1
[date] => 2017-05-16 18:07:56
[slug] => apple
)
[3] => Array
(
[id] => 4
[name] => Huawei
[parent] => 1
[date] => 2017-05-16 18:08:10
[slug] => huawei
)
[4] => Array
(
[id] => 5
[name] => HTC
[parent] => 1
[date] => 2017-05-16 18:08:22
[slug] => htc
)
[5] => Array
(
[id] => 6
[name] => OnePlus
[parent] => 1
[date] => 2017-05-16 18:08:33
[slug] => oneplus
)
[6] => Array
(
[id] => 7
[name] => LG
[parent] => 1
[date] => 2017-05-16 18:08:44
[slug] => lg
)
[7] => Array
(
[id] => 8
[name] => BlackBerry
[parent] => 1
[date] => 2017-05-16 18:08:55
[slug] => blackberry
)
[8] => Array
(
[id] => 9
[name] => Motorola
[parent] => 1
[date] => 2017-05-16 18:09:14
[slug] => motorola
)
[9] => Array
(
[id] => 10
[name] => Google
[parent] => 1
[date] => 2017-05-16 18:09:52
[slug] => google
)
)
But I want to get an array like below:
Array
(
[0] => Array
(
[id] => 1
[name] => Mobile Phones
[parent] => 0
[date] => 2017-05-16 08:55:22
[slug] => mobile-phones
[root_category] => null
)
[1] => Array
(
[id] => 2
[name] => Samsung
[parent] => 1
[date] => 2017-05-16 08:55:29
[slug] => samsung
[root_category] => Mobile Phones
)
[2] => Array
(
[id] => 3
[name] => android
[parent] => 2
[date] => 2017-05-16 18:07:56
[slug] => android
[root_category] => Mobile Phones > Samsung
)
[3] => Array
(
[id] => 4
[name] => Huawei
[parent] => 3
[date] => 2017-05-16 18:08:10
[slug] => huawei
[root_category] => Mobile Phones > Samsung > android
)
[4] => Array
(
[id] => 5
[name] => HTC
[parent] => 1
[date] => 2017-05-16 18:08:22
[slug] => htc
[root_category] => Mobile Phones
)
[5] => Array
(
[id] => 6
[name] => OnePlus
[parent] => 1
[date] => 2017-05-16 18:08:33
[slug] => oneplus
[root_category] => Mobile Phones
)
[6] => Array
(
[id] => 7
[name] => LG
[parent] => 1
[date] => 2017-05-16 18:08:44
[slug] => lg
[root_category] => Mobile Phones
)
[7] => Array
(
[id] => 8
[name] => Men Fashion
[parent] => 0
[date] => 2017-05-16 18:08:55
[slug] => men-fashion
[root_category] => null
)
[8] => Array
(
[id] => 9
[name] => shirt
[parent] => 8
[date] => 2017-05-16 18:09:14
[slug] => shirt
[root_category] => Men fashion
)
[9] => Array
(
[id] => 10
[name] => T shirt
[parent] => 9
[date] => 2017-05-16 18:09:52
[slug] => google
[root_category] => Men Fashion > shirt
)
}
I'm using codeigniter by the way.
That's not a good practice to make the Hierarchy from database logic.
The database table structure is already good enough to store the parent.
You need to have a function to call it recursively.
If your objective is to create breadcrumb, I assume you will need from the lowest hierarchy climbing up until the parent value is = 0.
function display_sub($id=0)
{
$breadcrumb = [];
// I assume your these are your model and function name.
$category = $this->item_model->get_category($id);
if($category['parent'] != 0)
{
// if parent not 0, add the name to $breadcrumb array,
// then do another run of this function
// but take this menu's parent id as parameter
array_push($breadcrumb,$row['name']);
$this->display_sub($row['parent']);
} else {
// if parent already 0, it's finish the job.
// and you can reverse it and display as intended.
return $breadcrumb;
}
}
How can I convert a database table like that:
into a multi-dimensional array like that ?
I tried a recursive loop like below but can't get it to display properly.
function cost_centres_format($items)
{
foreach ($items as $item) {
echo $item->name.' - '.$item->parent_id;
echo '<br/>';
$sons = $this->purchase_order_model->get_cost_centre_sons($item->internal_purchase_order_cost_centre_id);
if(count($sons)>0){
$this->cost_centres_format($sons);
}
}
}
Here is my solution for it:
function cost_centres_format($items,$parent_id,$array=array()) {
foreach($items as $item) {
if($item->parent_id == $parent_id) {
$array[] = $item;
if($item->internal_purchase_order_cost_centre_id>0) {
$array = cost_centres_format($items,$item->internal_purchase_order_cost_centre_id,$array);
}
}
}
return $array;
}
$array = cost_centres_format($items,0);
Diesel (id:5) will be below Vehicle Maintenance (id:4) because of its original order. You can do an additional sort by name but in your example Capital (id:3) was below Overheads (id:2).
The above code doesn't produce multidimensional array but instead one dimensional array like so :
Array
(
[0] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 1
[name] => Direct Expenses
[parent_id] => 0
)
[1] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 4
[name] => Vehicle Maintenance
[parent_id] => 1
)
[2] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 9
[name] => CN09 AKO
[parent_id] => 4
)
[3] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 10
[name] => DY52 BYO
[parent_id] => 4
)
[4] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 14
[name] => MX08 MVJ
[parent_id] => 4
)
[5] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 15
[name] => YJ55 TXA
[parent_id] => 4
)
[6] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 5
[name] => Diesel
[parent_id] => 1
)
[7] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 6
[name] => Vehicle Rent
[parent_id] => 1
)
[8] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 11
[name] => Vehicle Repair
[parent_id] => 1
)
[9] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 16
[name] => CN09 AKO
[parent_id] => 11
)
[10] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 17
[name] => DY52 BYO
[parent_id] => 11
)
[11] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 18
[name] => MX08 MVJ
[parent_id] => 11
)
[12] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 19
[name] => YJ55 TXA
[parent_id] => 11
)
[13] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 2
[name] => Overheads
[parent_id] => 0
)
[14] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 12
[name] => Internet Service
[parent_id] => 2
)
[15] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 13
[name] => Warehouse Rent
[parent_id] => 2
)
[16] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 3
[name] => Capital
[parent_id] => 0
)
[17] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 7
[name] => New Stock
[parent_id] => 3
)
[18] => stdClass Object
(
[internal_purchase_order_cost_centre_id] => 8
[name] => New Vehicle
[parent_id] => 3
)
)
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => Tops
[parent_id] =>
)
[1] => stdClass Object
(
[id] => 2
[name] => Trousers
[parent_id] =>
)
[2] => stdClass Object
(
[id] => 3
[name] => Dresses
[parent_id] =>
)
[3] => stdClass Object
(
[id] => 4
[name] => Skirts
[parent_id] =>
)
[4] => stdClass Object
(
[id] => 5
[name] => Accessories
[parent_id] =>
)
[5] => stdClass Object
(
[id] => 6
[name] => Coats & Jackets
[parent_id] =>
)
)
Above is the parent categories i fetch from db.
And below are the sub categories
Array
(
[0] => stdClass Object
(
[id] => 8
[name] => Mini Tops
[parent_id] => 1
)
[1] => stdClass Object
(
[id] => 9
[name] => Long Tops
[parent_id] => 2
)
[2] => stdClass Object
(
[id] => 10
[name] => Cargo
[parent_id] => 2
)
[3] => stdClass Object
(
[id] => 11
[name] => Bermuda
[parent_id] => 2
)
[4] => stdClass Object
(
[id] => 12
[name] => Formal Dresses
[parent_id] => 3
)
[5] => stdClass Object
(
[id] => 13
[name] => Casual Dresses
[parent_id] => 3
)
[6] => stdClass Object
(
[id] => 14
[name] => Party Wear
[parent_id] => 3
)
[7] => stdClass Object
(
[id] => 15
[name] => Jewelry
[parent_id] => 4
)
[8] => stdClass Object
(
[id] => 16
[name] => Bracelets
[parent_id] => 4
)
[9] => stdClass Object
(
[id] => 17
[name] => Caps
[parent_id] => 4
)
)
below is how i am making my navitaion bar
<ul>
<li>
Tops
<ul class="sub-menu">
<li>Tshirts</li>
<li>Jumpers</li>
<li>Cardigans</li>
<li>Knitwear</li>
</ul>
</li>
</ul>
As my logics are not so much good i actually trying to make navitaion with these two arrays in a way that the first array which are main links should be on top order where as all respective childs will appear in submenu of there respective parent_id example
Long Top, Cargo and Bermuda should be falling under Trousers Link.
I need guidance how can i achieve this .. I tried foreach loop but stucked in middle
Thanks alot
If you're in control you should try to use a different choice of arrays because now you will be doing an unnecessary amount of looping. To demonstrate:
foreach($categories as $cat) {
echo "<li>".$cat->name."<ul>";
foreach($subcategories as $subcat) {
if($subcat->parent_id == $cat->id) echo "<li>".$subcat->name."</li>"
}
echo "</ul></li>";
}
You have to loop over all subcategories for each category. But if you instead stored subcategories in an array where the index represented the parent ID, you could easily retrieve them.
If you want to solve this with just one array you could make the list of subcategories a property of the corresponding parent category. This would be easy to handle and semantic.
I am attempting sort this array by each stdClass Object's [title] in an Ubercart order.tpl.php file. I have tried doing just a normal sort but since they all are stdClass Objects it doesn't do anything.
<pre>Array
(
[0] => stdClass Object
(
[order_product_id] => 1157
[order_id] => 142
[nid] => 38
[title] => Eatonville Forest Camping Permit
[manufacturer] =>
[model] => eatonville-camp-permit
[qty] => 1
[cost] => 9.00000
[price] => 10.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 0
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
[1] => stdClass Object
(
[order_product_id] => 1158
[order_id] => 142
[nid] => 35
[title] => Eatonville Forest Motorized Recreation Access Permit and Release of Liability
[manufacturer] =>
[model] => eatonville-motor-rec-access
[qty] => 1
[cost] => 175.00000
[price] => 175.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 1
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
[2] => stdClass Object
(
[order_product_id] => 1159
[order_id] => 142
[nid] => 31
[title] => Snoqualmie Forest Non-motorized Recreation Access Permit for Families and Release of Liability
[manufacturer] =>
[model] => snoqualmie-family-non-motor-rec-access
[qty] => 1
[cost] => 150.00000
[price] => 150.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 1
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
[3] => stdClass Object
(
[order_product_id] => 1160
[order_id] => 142
[nid] => 40
[title] => Snoqualmie Forest Camping Permit
[manufacturer] =>
[model] => snoqualmie-camp-permit
[qty] => 1
[cost] => 300.00000
[price] => 300.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 1
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
[4] => stdClass Object
(
[order_product_id] => 1161
[order_id] => 142
[nid] => 39
[title] => White River Forest Camping Permit
[manufacturer] =>
[model] => whiteriver-camp-permit
[qty] => 1
[cost] => 300.00000
[price] => 300.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 1
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
[5] => stdClass Object
(
[order_product_id] => 1162
[order_id] => 142
[nid] => 30
[title] => White River Forest Family Non-motorized Recreation Access Permit for Families and Release of Liability
[manufacturer] =>
[model] => whiteriver-family-non-motor-rec-access
[qty] => 1
[cost] => 150.00000
[price] => 150.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 1
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
[6] => stdClass Object
(
[order_product_id] => 1163
[order_id] => 142
[nid] => 33
[title] => White River Forest Non-motorized Recreation Access Permit for Individuals and Release of Liability
[manufacturer] =>
[model] => whiteriver-non-motor-rec-access
[qty] => 1
[cost] => 75.00000
[price] => 75.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 1
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
[7] => stdClass Object
(
[order_product_id] => 1164
[order_id] => 142
[nid] => 34
[title] => Snoqualmie Forest Non-motorized Recreation Access Permit for Individuals and Release of Liability
[manufacturer] =>
[model] => snoqualmie-non-motor-rec-access
[qty] => 1
[cost] => 75.00000
[price] => 75.00000
[weight] => 0
[data] => Array
(
[attributes] => Array
(
)
[shippable] => 1
[restrict_qty] => 1
[module] => uc_product
)
[order_uid] => 13
)
)</pre>
This is the code controlling it in the order.tpl.php
<pre>php if (is_array($order->products)) {
$context = array(
'revision' => 'formatted',
'type' => 'order_product',
'subject' => array(
'order' => $order,
),
);
}
</pre>
I think usort() should work:
function sortByTitle($a, $b){
return strcmp($a->title, $b->title);
}
usort($theArray, 'sortByTitle');
You may want to throw in some checking to make sure the title member actually exists.