how to iterate through a particular part of an object - php

I have an object which looks like this
zen_categories_ul_generator Object
(
[root_category_id] => 0
[max_level] => 6
[data] => Array
(
[0] => Array
(
[19] => Array
(
[name] => Brushes
[count] => 0
)
[29] => Array
(
[name] => Clips
[count] => 0
)
[2] => Array
(
[name] => Combs
[count] => 0
)
[27] => Array
(
[name] => Jewellery
[count] => 0
)
)
[1] => Array
(
[57] => Array
(
[name] => Testing
[count] => 0
)
)
And I want to loop through all the information at the level $this->data[0], I'm using
foreach($this->data[0] as $category_id => $category) {
$result .= $category_id.' - '.$category['name'];
}
return $result;
but this will just the last item in the array. so in this case it would only have 27 - Jewellery but none of the other array item would be returned.
What am I doing wrong?
thanks
NB I only need to loop through the data[0] - not data[1] as well!
EDIT - here's a paste bin with a more code to make easier to understand what I'm trying to do and how I'm doing it. Any help gratefully received
http://pastebin.com/Vrw9f7Xh

Question:
Ok, so you want to loop through all the information $this->data[0], to render a menu.
Actually, you were pretty close to the solution, yourself.
The line used for rendering the product items, is:
$result .= ''.$category['name'] . ' (' . $category['count'] . ')';
The following is working example, which works standalone.
You might save it as menu.php and test it.
I had to comment the zen_* function out, but i think the relevant part is the rendering, right?
class zen_categories_ul_generator
{
function setTestData($data) { $this->data = $data; }
function buildMenu() {
$result = '';
// removed home link, unchanged and not important in this example
// submenu
$result .= '<li class="submenu">';
$result .= 'Products';
$count = 0;
foreach($this->data[0] as $category_id => $category) {
$count++;
$result .= '<ul class="level2">';
$result .= '<li class="submenu">';
//$result .= ''.$category['name'].''.$count;
$result .= ''.$category['name'] . ' (' . $category['count'] . ')';
$result .= '</li>';
$result .= '</ul>';
}
$result .= '</li> Items:' . $count;
return $result;
}
}
$object = new zen_categories_ul_generator;
// ok, lets add your example data from outside to the object, in order to test the rendering
$data = array(
0 => array(
19 => array('name' => 'Brushes', 'count' => 5),
29 => array('name' => 'Clips', 'count' => 2),
2 => array('name' => 'Combs', 'count' => 1),
27 => array('name' => 'Jewellery', 'count' => 3)
)
);
$object->setTestData($data);
// render the menu
echo $object->buildMenu();
Result
Count is the number of iterations = the number of Products in a Category.
And the counter behind the product name is from the array, the key "count".

Related

From php multidimensional array trying to create nested ul li menu (unlimited nested levels)

Here is what i have got http://codepad.org/iDoXXsLX
Have array like this
Array
(
[0] => Array
(
[NumberRenamed] => 17
[TopicName] => Products
[UpperLevelNumberRenamed] => 0
)
[17] => Array
(
[0] => Array
(
[1] => Array
(
[NumberRenamed] => 18
[TopicName] => Computers
[UpperLevelNumberRenamed] => 17
)
)
)
[18] => Array
(
[0] => Array
(
[2] => Array
(
[NumberRenamed] => 16
[TopicName] => Laptops
[UpperLevelNumberRenamed] => 18
)
)
)
[16] => Array
(
[0] => Array
(
[4] => Array
(
[NumberRenamed] => 8
[TopicName] => Dell
[UpperLevelNumberRenamed] => 16
)
)
)
)
Top level item is Products, first sub-level item is Computers, next sub-level is Laptops, then again next sub-level Dell
For each sub-level item UpperLevelNumberRenamed == to closest upper level NumberRenamed.
Want to get result like this
Products
Computers
Laptops
Dell
Acer
Desktops
Home
Tried this
foreach( $main_topics as $k_main_topics => $v_main_topics ){
if( isset($v_main_topics['UpperLevelNumberRenamed']) and $v_main_topics['UpperLevelNumberRenamed'] == 0 ){
//print only top level topics
echo $v_main_topics['TopicName']. '<br/>';
}
else{//if not top level topic
foreach( $v_main_topics[0] as $k_v_main_topics_0 => $v_v_main_topics_0 ){
echo $v_v_main_topics_0['TopicName']. '<br/>';
}//foreach( $v_main_topics[0] as $k_v_main_topics_0 => $v_v_main_topics_0 )
}//else{
}//foreach( $main_topics as $k_main_topics => $v_main_topics )
But get this
Products
Home
Computers
Laptops
Desktops
Dell
Acer
Something incorrect, but can not understand what. Please, advice what need to correct/change in the code
Trying another way
Initial array is one dimensional array. Trying to get ul li navigation from one dimensional.
Here is what i did http://codepad.org/OLtxyL4X
Here's a summary of what it does:
flatten the array recursively
build a multi-dimensional relation map
create 1D relationships that link UpperLevelNumberRenamed to NumberRenamed
print out the multi-dimensional as an ul-li list.
Here it is:
$flat = array();
foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($main_topics)) as $i)
$flat[] = $i;
$final = array();
$defs = array();
for ($i = 0; $i < count($flat); $i += 3)
if ($flat[$i + 2] == 0) {
$final[$flat[$i + 1]] = array();
$defs[$flat[$i]] = &$final[$flat[$i + 1]];
} else {
$defs[$flat[$i + 2]][$flat[$i + 1]] = array();
$defs[$flat[$i]] = &$defs[$flat[$i + 2]][$flat[$i + 1]];
}
function array2ul($array) {
$out = "<ul>";
foreach($array as $key => $elem)
$out = is_array($elem) ?
$out . "<li><span>$key</span>" . array2ul($elem) . "</li>" :
$out = $out."<li><span>$key:[$elem]</span></li>";
$out = $out . "</ul>";
return $out;
}
echo array2ul($final);
Output:
<ul><li><span>Products</span><ul><li><span>Computers</span><ul><li><span>Laptops</span><ul><li><span>Dell</span><ul></ul></li><li><span>Acer</span><ul></ul></li></ul></li><li><span>Desktops</span><ul></ul></li></ul></li></ul></li><li><span>Home</span><ul></ul></li></ul>
This shall be a working example using recursion, not tested though:
Define the array
$main_array = Array
(
'10' => Array
(
'name' => 'Products'
'children' => Array
(
'12' => Array
(
'name' => 'Laptop',
'children' => Array
(
'13' => Array
(
'name' => 'Dell',
),
'14' => Array
(
'name' => 'Acer',
)
)
)
'14' => Array
(
'name' => 'Desktop',
'children' => Array
(
'15' => Array
(
'name' => 'Sony',
),
'16' => Array
(
'name' => 'Apple',
)
)
),
)
)
)
Create and call the function :
function createList($main_topics)
{
if($main_topics == null || sizeof($main_topics) <= 0)
{
return '';
}
$list = '<ul>';
foreach($main_topics as $k_main_topics => $v_main_topics )
{
$list .= '<li id="' . $k_main_topics'"> '. $v_main_topics['name'] . ' ' . createList(isset($v_main_topics["children"]) ? $v_main_topics["children"] : null) . '</li>' ;
}
$list .= '</ul>';
return $list;
}
echo createList($main_array);

Objects in Objects, Skip one in foreach

I'm trying to loop over each object and show the team name on a website... however I want to skip the $variable->active key.
The number of teams varies...How can I skip the 'active' key?
I tried this but it doesn't seem to work:
$active = $team->active;
if (isset($team->active)) {
foreach ($team as $data) {
if (isset($data->idteam) != $active) {
print_r($data);
$return .= '<li><i class="fa fa-power-off"></i> ' . $data->nameteam . '</li>';
} else {
$return .= "No Teams!";
}
}
}
Here is my object:
teamAccess Object
(
[2] => Team Object
(
[nameteam] => Team 1
[idteam] => 2
[enabled] => 1
[last_access_stamp] => 1399603014
[create_stamp] => 4
[update_stamp] => 1399167351
)
[1] => Team Object
(
[nameteam] => Test Team
[idteam] => 1
[enabled] => 0
[last_access_stamp] => 1399603014
[create_stamp] => 0
[update_stamp] => 0
)
[3] => Team Object
(
[nameteam] => Team 3
[idteam] => 3
[enabled] => 1
[last_access_stamp] => 1399603014
[create_stamp] => 0
[update_stamp] => 0
)
[active] => 3
[alerts] => Array
(
)
)
In the foreach, you can capture the key, and check it in a condition to skip it:
foreach ($team as $key => $data) {
if ($key != 'active') {
$return .= '<li><i class="fa fa-power-off"></i> ' . $data->nameteam . '</li>';
}
}
Observation: it seems that the teamAccess object should have a teams property, which could be an array of team objects. This might be a better structure than having all of the data mixed together as root properties.

Loop logic help needed - Can't compare correctly

I have the following table:
And I use this function to get data from it:
function get_cart_by($player_id)
{
global $db;
$sql = 'SELECT DISTINCT(item_id) FROM ' . PCP_MARKET_CART . '
WHERE player_id = ' . (int) $player_id;
$result = $db->sql_query($sql);
$rowset = $db->sql_fetchrowseT($result);
$db->sql_freeresult($result);
$cart = array();
foreach ($rowset as $item)
{
$cart[] = $item['item_id'];
}
return $cart;
}
The result looks like this:
Array
(
[0] => 16
[1] => 17
[2] => 49
[3] => 48
[4] => 18
[5] => 19
[6] => 51
)
Now I have an array that lists all my products from another table without looking at the player_id. I want to use the array demonstrated above and add a custom class to the items that do not use the player_id, like show which items the user already has on cart.
The other array that lists all the products looks like this:
Array
(
[0] => Array
(
[item_id] => 16
[parent_id] => 11
[cat_position] => 0
[item_position] => 1
[item_type] => product
[item_title] => Custom Business
[item_description] => Some description
[item_price] => 9.99
[item_units] => 500
[item_preview] => http://i.imgur.com/3eCpMMm.png
[times_sold] => 0
[daopay_url] => http://i.imgur.com/QA7bBfJ.jpg
[public] => 1
[time] => 1384709635
)
[1] => Array
(
[item_id] => 17
[parent_id] => 11
[cat_position] => 0
[item_position] => 1
[item_type] => product
[item_title] => Custom Business
[item_description] => Some description
[item_price] => 9.99
[item_units] => 500
[item_preview] => http://i.imgur.com/3eCpMMm.png
[times_sold] => 0
[daopay_url] => http://i.imgur.com/QA7bBfJ.jpg
[public] => 1
[time] => 1384709635
)
[2] => Array
(
[item_id] => 49
[parent_id] => 11
[cat_position] => 0
[item_position] => 1
[item_type] => product
[item_title] => Custom Business
[item_description] => Some description
[item_price] => 9.99
[item_units] => 500
[item_preview] => http://i.imgur.com/3eCpMMm.png
[times_sold] => 0
[daopay_url] => http://i.imgur.com/QA7bBfJ.jpg
[public] => 1
[time] => 1384709635
)
)
Now based on the first array, I want to mark the same item IDs on the second arrays and show that they are different (on cart).
I have tried quite a lot and for some reason, I managed to mark only item_id 16 and 17, the rest are not getting "marked" for some reason.
This is the code I used:
$cartar = $market->get_cart_by($user->data['player_id']);
$cartln = sizeof($cartar) - 1;
// Fetch items of the selected category
$items = $market->fetch_cat_items($cat_id); // Equivalent to the array above
$index = 0;
print_r($items);
foreach ($items as $item)
{
$name = $item['item_name'];
if ($cartln >= $index)
{
if ($cartar[$index] == $item['item_id'])
$name .= $cartar[$index];
}
echo $name;
$index++;
}
I tried to make the example explain my case the best way possible. So, when I echo out $name it only outputs thename16 and thename17 (those two), but it doesn't continue to 49 and so on.
Please be aware that the array with all the products in it is quite large, I made it shorter for demonstration purposes only.
Were am I failing in my code? Why are only the first two items getting "marked"? I'm quite in a hurry right now, once I get back from a meeting I'll try to explain my issue further.
i don't know if i understood correctly but maybe you want to do it like this:
foreach ($items as $item) {
$name = $item['item_name'];
if(in_array($item['item_id'],$cartar)) {
$name .= $item['item_id'];
}
echo $name;
}
used in_array() to check if the item_id exists somewhere in $cartar. No matter on which position in array.

Different positions in array

I have an sql query which outputs an array the output looks like this
Array
(
[0] => Array
(
[customer_id] => 7
[language_id] => 1
[variableitem_id] => 13
[name] => QUESTION_HEADLINE
[value] => Bitte geben Sie Ihren Downloadkey ein:
)
[1] => Array
(
[customer_id] => 7
[language_id] => 1
[variableitem_id] => 15
[name] => QUESTION_BUTTON
[value] => Start!
)
[2] => Array
(
[customer_id] => 7
[language_id] => 1
[variableitem_id] => 6
[name] => PAGETITLE
[value] => Steigenberger Hotels and Resorts - Mediathek
)
)
In my controller I get it as
$data['variables_data'] = $this->Home_model->getVariables($customer_id, $language_id);
Now for different ids in the url like for
localhost/home/user/12 and localhost/home/user/14
the positions of the variable differs
for example in my view when I echo
$variable[0]['value']
it gives QUESTION_HEADLINE for one user and PAGE_TITLE for the other .
Is it possible to make them same for all of the user like if I echo
$variable[0]['value']
it should return me QUESTION_HEADLINE every time and for every user
Code for Home model get_variables function
function getVariables($customer_id, $language_id) {
$query = $this->db->query("SELECT customers_idcustomers AS customer_id,
languages_idlanguages AS language_id,
variableitems_idvariableitems AS variableitem_id,
variableitem AS name,
variabletext AS value
FROM variables v
LEFT JOIN variableitems vi ON v.variableitems_idvariableitems = vi.idvariableitems
WHERE v.customers_idcustomers ='" . $customer_id . "'
AND v.languages_idlanguages =" . $language_id
);
$var = $query->result_array();
return $var;
}
Thanks in advance
You can set it explicitly, like
foreach($outArray as $output)
{
$output['name']="Any thing you want";
}
So , as i understand you want to make reduce your output to one dimension. It can be done with MYSQL also. Here php version:
In your controller
$data = $this->Home_model->getVariables($customer_id, $language_id);
$data['variables'] = array(
'customer_id' => $data[0]['customer_id'],
'language_id' => $data[0]['language_id'],
'variableitem_id' => array(),
'name' => array(),
'value' => array()
);
foreach($data as $k => $v) {
$data['variables']['variableitem_id'][] = $v['variableitem_id'];
$data['variables']['name'][] = $v['name'];
$data['variables']['value'][] = $v['value'];
}
And in your view
echo $variables['value'][2].' '.$variables['value'][3];
//do whatever you want

How to output an array based on primary keys and foreign keys

Considering this array
Array
(
[0] => Array
(
[id] => 51
[category_id] => 37
[title] => Sims
)
[1] => Array
(
[id] => 37
[category_id] => 26
[title] => Blackberry
)
[2] => Array
(
[id] => 26
[category_id] => 0
[title] => Mobile Device
)
I would like to be able to print out:
Mobile Device > Blackberry > Sims
Based on the relationship between category_id and id.
Can you use the id as the key into the array? It will make your life a bit simpler. For example, if you define your array:
Array
(
[51] => Array
(
[id] => 51
[category_id] => 37
[title] => Sims
)
[37] => Array
(
[id] => 37
[category_id] => 26
[title] => Blackberry
)
[27] => Array
(
[id] => 26
[category_id] => 0
[title] => Mobile Device
)
Then you can write code like:
//assume $a is your array, defined above
//and that you have used the id for the array key
$id = 51
do {
print $a['title'];
$id = $a['category_id'];
}while($id != 0);
EDIT: array_multisort probably isn't cleanest way to do this.
<?php
$array = Array(
array('id' => 51, 'category_id' => 37, 'title' => 'Sims'),
array('id' => 37, 'category_id' => 26, 'title' => 'Blackberry'),
array('id' => 26, 'category_id' => 0, 'title' => 'Mobile Device'));
// First build an associative array ID->Object
$map = array();
foreach( $array as $value )
{
$map[$value['id']] = $value;
}
// Then build your path
$path = array();
$value = $array[0];
while( true )
{
$path[] = $value['title'];
if( $value['category_id'] == 0 )
{
break;
}
$value = $map[$value['category_id']];
if( !isset($value) )
{
die("Data Inconsistency");
}
}
// Display path
echo implode(array_reverse($path), ' > ');
?>
Try array_multisort()
Does your original array also contains entries that are to be left out?
If not, use this:
$sort_array = array();
foreach ($original_array as $key => $value) {
$sort_array[] = $value['category_id'];
}
array_multisort($sort_array, SORT_ASC, $original_array);
The above will sort $original_array based on the category_id index.
If your array contains entries that have nothing to do with the rest, and you want to leave them out, you have to use something like this:
// remap keys based on category_id
$parts = array();
foreach ($original_array as $array) {
$parts[$array['category_id']] = $array;
}
// build tree list
$category_id = 0;
$result = array();
while (isset($parts[$category_id])) {
$result[] = $parts[$category_id]['title'];
$category_id = $parts[$category_id]['id'];
}
echo implode(' > ', $result);

Categories