As one of the steps toward a greater website redesign I am putting the majority of the content of our website into html files to be used as includes. I am intending on passing a variable to the PHP template page through the URL to call the proper include.
Our website has many programs that each need an index page as well as about 5 sub-pages. These program pages will need a menu system to navigate between the different pages.I am naming the pages pagex_1, pagex_2, pagex_3, etc. where "pagex" is descriptive of the page content.
My question is, what would be the best way to handle this menu system? Is there a way to modify the initial variable used to arrive at the index page to create links in the menu to arrive at the other pages?
Thanks for any help!
I'd store the menu structure in an associative PHP array like so:
$menu = array(
'index'=>array(
'title'=>'Homepage',
'include'=>'home.html',
'subitems'=>array()
),
'products' => array(
'title'=>'Products',
'include'=>'products.html',
'subitems'=>array(
'product1'=>array(
...
),
'product2'=>array(
...
),
'product3'=>array(
...
)
)
)
);
Make that array available to the template script as well (e.g. by include/require). Then use delimiters in the variable to identify the menu item (like a file system does with folders and files) and therefore the resulting page to be included:
'index' would identify the index page
'products' would identifiy the products start page
'products/product1' would identify the product 1 subpage inside the products page
... and so on.
// Menu Array multidimensional
$menu = array(
'index' => array(
'title' => 'Homepage',
'include' => 'home.html',
'subitems' => array()
),
'products' => array(
'title' => 'Products',
'include' => 'products.html',
'subitems' => array(
'product1' => array(
'title' => 'product1',
'include' => 'product1.html',
'subitems' => array(
'product1.2' => array(
'title' => 'product1.2',
'include' => 'product1.2.html',
'subitems' => array()
)
)
),
'product2' => array(
'title' => 'product2',
'include' => 'product2.html',
'subitems' => array()
),
'product3' => array(
'title' => 'product3',
'include' => 'product31.html',
'subitems' => array()
),
'product4' => array(
'title' => 'product4',
'include' => 'product4.html',
'subitems' => array()
)
)
)
);
// Make menu
function makeMenu($menu_array,$is_sub = false,$list=['ul','li']){
$attr = (!$is_sub) ? ' class="menu"' : ' class="submenu"';
$child = NULL;
$menu = "<{$list[0]}{$attr}>";
foreach($menu_array as $id => $items){
foreach($items as $key => $val){
if( is_array($val) ) {
if ( !empty($val) ) $child = makeMenu($val,true,$list);
} else {
$$key = $val;
}
}//foreach
$menu .= "<{$list[1]}>";
$menu .= ''.$title.'';
$menu .= $child; // Sub Menu
$menu .= "</{$list[1]}>";
unset($url, $text, $sub);
}//foreach
$menu .= "</{$list[0]}>";
return $menu;
}
// retrieve the desired page with the shaft
function makeSubMenu($menu, $key) {
return makeMenu(array($menu[$key]));
}
// chain Article
function chainItem(array $array, $unset = '' ){
$ds = array();
if ( is_array($array) )
foreach((array)$unset as $arr) unset($array[$arr]);
foreach($array as $key=>$value)
if (!is_array($value)) $ds[$key] = $value;
return $ds;
}
// Build walk recursive -> single array insert database MySql
function walkRecursive($array, $ordId = true, $unset=[], $children = 'children', $i = 1, $parent = 0, &$res = [] ) {
if ( !is_array($array) ) return array();
foreach(array_values($array) as $key=>$arr) {
$das = array(
'id' => $id = $ordId ? $arr['id'] : $i++,
'parent' => $parent
);
$res[] = array_merge($das,chainItem($arr,$unset));
if( isset($arr[$children]) ) {
walkRecursive($arr[$children], $ordId, $unset, $children, $i, $id, $res );
}
}
return $res;
}
echo makeMenu($menu);
// Result of the print
<ul class="menu">
<li>Homepage</li>
<li>Products
<ul class="submenu">
<li>product1
<ul class="submenu">
<li>product1.2</li>
</ul>
</li>
<li>product2
<ul class="submenu">
<li>product1.2</li>
</ul>
</li>
<li>product3
<ul class="submenu">
<li>product1.2</li>
</ul>
</li>
<li>product4
<ul class="submenu">
<li>product1.2</li>
</ul>
</li>
</ul>
</li>
</ul>
// Build walk recursive -> single array insert database MySql
header("Content-type: text/plain");
print_r( walkRecursive($menu,false,['parent','id'],'subitems') );
// Print array -> Result:
Array
(
[0] => Array
(
[id] => 1
[parent] => 0
[title] => Homepage
[include] => home.html
)
[1] => Array
(
[id] => 2
[parent] => 0
[title] => Products
[include] => products.html
)
[2] => Array
(
[id] => 3
[parent] => 2
[title] => product1
[include] => product1.html
)
[3] => Array
(
[id] => 4
[parent] => 3
[title] => product1.2
[include] => product1.2.html
)
[4] => Array
(
[id] => 4
[parent] => 2
[title] => product2
[include] => product2.html
)
[5] => Array
(
[id] => 5
[parent] => 2
[title] => product3
[include] => product31.html
)
[6] => Array
(
[id] => 6
[parent] => 2
[title] => product4
[include] => product4.html
)
)
Related
I have this tree :
Array
(
[0] => Array
(
[id] => 1
[parent_id] => 0
[title] => Parent Page
[children] => Array
(
[0] => Array
(
[id] => 2
[parent_id] => 1
[title] => Sub Page
),
[1] => Array
(
[id] => 5
[parent_id] => 1
[title] => Sub Page 2
)
)
)
[1] => Array
(
[id] => 4
[parent_id] => 0
[title] => Another Parent Page
)
)
And I'm looking for a display from top to bottom.
And display something like this :
1
1.2
1.5
4
But if I have id 3 which is a leaf from 5 I would like this :
1
1.2
1.5
1.5.3
4
I have search a lot and my brain is limited when i'm using recursivity..
I have tried this :
function printAll($a){
foreach ($a as $v){
if (!array_key_exists('children', $v)){
debugLog($v['id']);
return;
}
else{
$arrayChildrens = $v['children'];
foreach($arrayChildrens as $c){
$arrayChildrens = $c['children'];
$this->printAll($arrayChildrens);
}
}
}
}
But doesn't work..
I tried to begin just to display
1
2
5
4
But my goal is to display id parents before id ( like Ishowed you before)
Thanks a lot !
This function should give you your expected output.
function printAll($a, $prefix = '') {
//loop through $a
foreach($a as $v) {
//echo current level `id` with previous `$prefix`
echo "{$prefix}{$v['id']}\n";
//check if current level contains children
if(!empty($v['children'])) {
//clean up prefix to remove extra `.` at the end of prefixes
$prev_prefix = rtrim($prefix, '.');
//recurse printAll again passing the children as `$a` and a `$prefix` being the previous levels combined e.g `1.5`
//also clean up extra periods at the start of the prefix
printAll($v['children'], ltrim("{$prev_prefix}.{$v['id']}.", "."));
}
}
}
Output:
1
1.2
1.5
1.5.3
4
Using a proper return
Usually with a function you actually want the function to return values instead of echoing them automatically to your page. If you want this function to return an array of values instead of echoing them, you could do this:
function printAll($a, $level = '', $values = []) {
foreach($a as $v) {
$values[] = $value = "{$level}{$v['id']}";
if(!empty($v['children'])) {
$values = printAll($v['children'], "{$value}.", $values);
}
}
return $values;
}
Which will have a result like this:
Array
(
[0] => 1
[1] => 1.2
[2] => 1.5
[3] => 1.5.3
[4] => 4
)
This should do the job.
$arr = array(
array(
'id' => 1,
'parent_id' => 0,
'title' => 'Parent Page',
'children' => array(
array(
'id' => 2,
'parent_id' => 1,
'title' => 'Sub Page',
),
array(
'id' => 5,
'parent_id' => 1,
'title' => 'Sub Page 2',
'children' => array(
array(
'id' => 7,
'parent_id' => 5,
'title' => 'Sub Page',
),
array(
'id' => 8,
'parent_id' => 5,
'title' => 'Sub Page 2',
)
)
)
)
),
array(
'id' => 4,
'parent_id' => 0,
'title' => 'Another Parent Page',
)
);
function printAll($arr, $parent = [])
{
if (is_array($arr)) {
foreach ($arr as $k => $v) {
if (isset($v['id'])) {
$parent[] = $v['id'];
echo implode('.', $parent) . PHP_EOL;
}
if (isset($v['children'])) {
printAll($v['children'], $parent);
}
array_pop($parent);
}
}
}
printAll($arr);
Output
1
1.2
1.5
1.5.7
1.5.8
4
Working demo.
I am new to PHP and am trying to apply a named array within a named array. I have been able to apply each rope name (i.e. "Poly Soak") along with img, title, blurb, desc, etc. but am having a difficult time trying to apply $specTable into a table. I am also trying to apply $applications and $benefits with no luck.
I am using the using the GET command to generate each page. Pages populate as follows:
water-rescue-ropes.php?value=aqua-d
water-rescue-ropes.php?value=poly-soak... etc
function strip_bad_chars( $input ) {
$output = preg_replace( "/[^a-zA-Z0-9_-]/", "", $input );
return $output; }
if (isset($_GET['value'])) {
$waterRescueRope = strip_bad_chars( $_GET['value'] );
$rope = $waterRescueRopes[$waterRescueRope];}
Here is the edited array info:
$waterRescueRopes = array(
"poly-soak" => array(
'img' => "3P",
'title' => "Poly Soak™",
'blurb' => "Pelican’s 16 strand kernmantle construction is a...",
'desc' => "Polypropylene Water Rescue Rope",
'construction' => "16 Strand",
'cover' => "Polypropylene",
'core' => "Polypropylene",
array(
array(
'sku' => "3P-12Y",
'diameter' => "3/8"",
'tensile' => 3000,
'weight' => 3.4,
),
array(
'sku' => "3P-14Y",
'diameter' => "7/16"",
'tensile' => 3380,
'weight' => 4.7,
),
),
array("Water Rescue", "Canyoneering"),
array("Lightweight", "Buoyant", "High Visibility"),
),
"poly-soak-economy" => array(
'img' => "FQK",
'title' => "Poly Soak™ Economy",
'blurb' => "All the great benefits and features of our Poly Soak rope but at a lower cost.",
'desc' => "Polypropylene Economy Water Rescue Rope",
'construction' => "16 Strand",
'cover' => "Polypropylene",
'core' => "Polypropylene",
array(
array(
'sku' => "FQK-502",
'diameter' => "1/8"",
'tensile' => 2000,
'weight' => 1.5,
),
),
array("Water Rescue"),
array("Economical", "Lightweight", "Buoyant"),
),
"poly-soak-2" => array(
'img' => "3PN",
'title' => "Poly Soak™",
'blurb' => "This UL certified polypropylene rope is approved for...",
'desc' => "NFPA® Water Rescue Rope",
'construction' => "24 Strand",
'cover' => "Polypropylene",
'core' => "Polypropylene",
array(
array(
'sku' => "3PN-12Y",
'diameter' => "3/8"",
'tensile' => 4200,
'weight' => 3.05,
),
),
array("Water Rescue", "Canyoneering", "Mooring"),
array("Bright Colors for Greater Visibility", "Supple for Compact Storage", "Certified to the Highest Standard", "Buoyant"),
),
"aqua-d" => array(
'img' => "3q",
'title' => "Aqua-D™",
'blurb' => "This water rescue rope has a blended Dyneema® and polypropylene core. With a multifilament polypropylene cover, this rope floats and has near zero water retention. It is extremely strong, light 'weight', and has a no-stretch braid that meets the needs of coastal and river rescue professionals worldwide.",
'desc' => "Dyneema® Polypropylene Water Rescue Rope",
'construction' => "16 Strand",
'cover' => "Polypropylene",
'core' => "Dyneema®",
array(
array(
'sku' => "3Q-08Y",
'diameter' => "1/4"",
'tensile' => "3200",
'weight' => "1.7",
),
array(
'sku' => "3Q-10Y",
'diameter' => "5/16"",
'tensile' => "3400",
'weight' => "2.3",
),
array(
'sku' => "3Q-12Y",
'diameter' => "3/8"",
'tensile' => "4950",
'weight' => "3.4",
),
),
array("Minimal Water Retention", "Strong & Lightweight", "Buoyant"),
array("Water Rescue"),
), );
Additional included functions:
function get_specs($array = false)
{
if (!is_array($array))
return array();
elseif(empty($array))
return array();
foreach($array as $polytype => $polydata) {
$new[$polytype]['specs'] = (!empty($polydata[0]))? $polydata[0]:array();
$new[$polytype]['applications'] = (!empty($polydata[1]))? $polydata[1]:array();
$new[$polytype]['benefits'] = (!empty($polydata[2]))? $polydata[2]:array();
}
return $new;
}
Here is the edited specTable:
<?php function display_specs($spec = array(),$name = false)
{
if(!empty($spec[$name]['specs'])) {
ob_start();
foreach($spec[$name]['specs'] as $specs) {
?>
<tr>
<td><?php echo $specs['sku']; ?></td>
<td><?php echo $specs['diameter']; ?></td>
<td><?php echo $specs['tensile']; ?></td>
<td><?php echo $specs['weight']; ?></td>
</tr>
<?php
}
$data = ob_get_contents();
}
} ?>
// Isolates the specs from the main array
$specs = get_specs($waterRescueRopes);
// Alternately, you can loop through the main array and get all
<?php foreach($specs as $polytype => $spec) {
echo display_specs($specs,$_GET['value']);
}
?>
Edited Applications (Benefits is in similar list):
<?php function display_applications($spec = array(),$name = false)
{
if(!empty($spec[$name]['applications'])) {
ob_start();
foreach($spec[$name]['applications'] as $apps) {
?>
<li><?php echo $apps; ?></li>
<?php
}
$data = ob_get_contents();
return $data;
}
}
?>
<tr valign='top'>
<td class="td-item-cell"><article>
<div class="rel_product_wrapper">
<h3>Applications</h3>
<ul>
<li>
<?php
foreach($specs as $polytype => $spec) {
echo display_applications($specs,$_GET['value']);
}
?>
</li>
</ul>
</div>
</article></td>
</tr>
I currently have them populating what I need but multiple times ( four times for the four types of rope, I am assuming).
Thank you for your time! I appreciate it! :)
Remove the variables in your array, then create a function to extract just those aspects you need separately. The reason what you are doing does not work is because each time you write $specTable on each array, you re-assign/overwrite the previously-assigned $specTable to the current array until finally it is assigned the last array in the main array. That is why only one shows up. You need to save out those aspects to new arrays:
FUNCTIONS: Place functions at the top of the page OR in a different file that you include on this page for use. It is better to include using something like include("function.specs.php") because then you can reuse the functions on different pages if you want.
function get_specs($array = false)
{
if (!is_array($array))
return array();
elseif(empty($array))
return array();
foreach($array as $polytype => $polydata) {
$new[$polytype]['specs'] = (!empty($polydata[0]))? $polydata[0]:array();
$new[$polytype]['applications'] = (!empty($polydata[1]))? $polydata[1]:array();
$new[$polytype]['benefits'] = (!empty($polydata[2]))? $polydata[2]:array();
}
return $new;
}
function display_specs($spec = array(),$name = false)
{
if(!empty($spec[$name]['specs'])) {
ob_start();
foreach($spec[$name]['specs'] as $specs) {
?>
<tr>
<td><?php echo $specs['sku']; ?></td>
<td><?php echo $specs['diameter']; ?></td>
<td><?php echo $specs['tensile']; ?></td>
<td><?php echo $specs['weight']; ?></td>
</tr>
<?php
}
$data = ob_get_contents();
return $data;
}
}
// For sake of ease, you can do an application one by itself,
// Normally, you could just do one class/method that handles all the
// the different arrays
function display_applications($spec = array(),$name = false)
{
if(!empty($spec[$name]['applications'])) {
ob_start();
foreach($spec[$name]['applications'] as $apps) {
?>
<tr>
<td><?php echo $apps; ?></td>
</tr>
<?php
}
$data = ob_get_contents();
return $data;
}
}
Using the functions on your page:
// Isolates the specs from the main array
$specs = get_specs($waterRescueRopes);
// To select one product out of the bunch, just use the name from the array.
// Note, you need the $specs array as the first argument
echo display_specs($specs,"poly-soak");
echo display_applications($specs,"poly-soak");
// Alternately, you can loop through the main array and get all: ?>
<table>
<?php
foreach($specs as $polytype => $spec) {
echo display_specs($specs,$polytype);
echo display_applications($specs,$polytype);
}
?>
</table>
Applications Part: Because the function already does the loop for you, you just need to echo it:
<tr valign='top'>
<td class="td-item-cell"><article>
<div class="rel_product_wrapper">
<h3>Applications</h3>
<ul>
<li>
<?php echo display_applications($specs,$_GET['value']); ?>
</li>
</ul>
</div>
</article></td>
</tr>
The RAW print_r($specs) gives you:
Array
(
[poly-soak] => Array
(
[specs] => Array
(
[0] => Array
(
[sku] => 3P-12Y
[diameter] => 3/8"
[tensile] => 3000
[weight] => 3.4
)
[1] => Array
(
[sku] => 3P-14Y
[diameter] => 7/16"
[tensile] => 3380
[weight] => 4.7
)
)
[applications] => Array
(
[0] => Water Rescue
[1] => Canyoneering
)
[benefits] => Array
(
[0] => Lightweight
[1] => Buoyant
[2] => High Visibility
)
)
[poly-soak-economy] => Array
(
[specs] => Array
(
[0] => Array
(
[sku] => FQK-502
[diameter] => 1/8"
[tensile] => 2000
[weight] => 1.5
)
)
[applications] => Array
(
[0] => Water Rescue
)
[benefits] => Array
(
[0] => Economical
[1] => Lightweight
[2] => Buoyant
)
)
[poly-soak-2] => Array
(
[specs] => Array
(
[0] => Array
(
[sku] => 3PN-12Y
[diameter] => 3/8"
[tensile] => 4200
[weight] => 3.05
)
)
[applications] => Array
(
[0] => Water Rescue
[1] => Canyoneering
[2] => Mooring
)
[benefits] => Array
(
[0] => Bright Colors for Greater Visibility
[1] => Supple for Compact Storage
[2] => Certified to the Highest Standard
[3] => Buoyant
)
)
[aqua-d] => Array
(
[specs] => Array
(
[0] => Array
(
[sku] => 3Q-08Y
[diameter] => 1/4"
[tensile] => 3200
[weight] => 1.7
)
[1] => Array
(
[sku] => 3Q-10Y
[diameter] => 5/16"
[tensile] => 3400
[weight] => 2.3
)
[2] => Array
(
[sku] => 3Q-12Y
[diameter] => 3/8"
[tensile] => 4950
[weight] => 3.4
)
)
[applications] => Array
(
[0] => Minimal Water Retention
[1] => Strong & Lightweight
[2] => Buoyant
)
[benefits] => Array
(
[0] => Water Rescue
)
)
)
I have the following array:
Array
(
[0] => Array
(
[name] => bss2
[label] => front
[text] => just a testing item
)
[1] => Array
(
[name] => bss3
[label] => front top
[text] => front top testing item
)
[2] => Array
(
[name] => J334
[label] => back top
[text] => masking test back top
)
[3] => Array
(
[name] => J3366
[label] => back
[text] => back non mask test
)
)
What i would like to accomplish is to check to see if label = front then group the ones with front together and same with back all in one big array to have it looks like so:
[approval] => Array(
[0] => Array(
[name] => front
[prev] => Array(
[0]=>Array(
[name] => bss2
)
[1]=>Array(
[name] => bss2
)
)
)
[1] => Array(
[name] => back
[prev] => Array(
[0]=>Array(
[name] => J334
)
[1]=>Array(
[name] => J3366
)
)
)
)
so far I dont have much and am stuck but this is my code
foreach($info as $data) {
if(strtolower(strpos($data['label'], "front") !==false)) {
} else {
}
}
Iv also tried using array_chunk which works great but what would happen if there are 3 elements that need to be grouped or 4
array_chunk($info, 2);
or what would happen if the order is different where one is front and second is back it will then combine the front and back together.
Any help is greatly appreciated thank you.
This should do it, assuming the only choices are front and back.
$result = array(array('name' => 'front', 'prev' => array()),
array('name' => 'back', 'prev' => array()));
foreach ($info as $data) {
$i = (strpos(strtolower($data['label']), "front") !== false)
$result[$i]['prev'][] = array('name' => $data['name'];
}
$newinfo = array('approval' => $result;
It's not clear to me exactly what you're after... If it's just front and back or if you want top and any other group as well?
Methods
Anyway, here are a few options that should cover most cases.
Front and Back only
This is the simplest and will just check for front and back. If it finds them then it will ad to front and back in $newArray as is required.
$newArray = array(array('front'), array('back')); //The new reformatted array
for($i = 0; $i < count($initialArray); $i++){
if(strpos($initialArray[$i]['label'], 'front') !== FALSE){//Check if group is front
$newArray[0]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to front
}
if(strpos($initialArray[$i]['label'], 'back') !== FALSE){//Check if group is back
$newArray[1]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to back
}
}
Pre-defined groups
This one's a bit more complex and will search for all groups found in $groups. The code below shows only front and back but you could also add in, for example, top or any others.
$groups = array('front', 'back'); //Groups to search for e.g. front, back, and top
$newArray = array(); //The new reformatted array
for($i = 0; $i < count($initialArray); $i++){
foreach($groups as $group){
if(strpos($initialArray[$i]['label'], $group) !== FALSE){//Check if group is in label
$groupKey = array_search($group, $groups); //Search for the key in $groups
$newArray[$groupKey]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to relevant group
}
}
}
Automated
This is the most advanced code which will automatically search and add new groups as they are found in the array. It's also fully automated so all you have to do is point it at the correct array.
$groups = array(); //Index of groups like: top, front, and back
$newArray = array(); //The new reformatted array
for($i = 0; $i < count($initialArray); $i++){
$possibleGroups = explode(' ', strtolower($initialArray[$i]['label'])); //Get list of applicable groups
foreach($possibleGroups as $newGroup){
if(!in_array($newGroup, $groups)){ //If group doesn't already exist in $groups add it
$groups[] = $newGroup;
$newArray[] = array('name'=>$newGroup, 'prev'=>array());
}
$groupKey = array_search($newGroup, $groups); //Search for the key in $groups
$newArray[$groupKey]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to relevant group
}
}
Test array
The above codes have been tested with the following array...
$initialArray = array(
array(
'name' =>'bss2',
'label'=>'front',
'text' =>'sometihng...'
),
array(
'name' =>'bss3',
'label'=>'front top',
'text' =>'sometihng...'
),
array(
'name' =>'j334',
'label'=>'back top',
'text' =>'sometihng...'
),
array(
'name' =>'j3366',
'label'=>'back',
'text' =>'sometihng...'
)
);
Example Output
Output of the third method (automated) using the test array above.
array (
0 =>
array (
'name' => 'front',
'prev' =>
array (
0 =>
array (
'name' => 'bss2',
),
1 =>
array (
'name' => 'bss3',
),
),
),
1 =>
array (
'name' => 'top',
'prev' =>
array (
0 =>
array (
'name' => 'bss3',
),
1 =>
array (
'name' => 'j334',
),
),
),
2 =>
array (
'name' => 'back',
'prev' =>
array (
0 =>
array (
'name' => 'j334',
),
1 =>
array (
'name' => 'j3366',
),
),
),
)
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How check any value of array exist in another array php?
I am creating a shopping site. To simplify, I have 2 arrays, one holds all my items and the other holds all the items that are added on the cart :
$Items
Array
(
[0] => stdClass Object
(
[id] => 1
[title] => Verity soap caddy
[price] => 6.00
)
[1] => stdClass Object
(
[id] => 2
[title] => Kier 30cm towel rail
[price] => 14.00
)
//a lot more
)
$cartItems
Array
(
[0] => Array
(
[rowid] => c4ca4238a0b923820dcc509a6f75849b
[id] => 1
[qty] => 1
[price] => 6.00
[name] => Verity soap caddy
[subtotal] => 6
)
)
I would like to loop through the $cartItems and add a class (identify) if an item is also in the cart. This is how I tried to do it
foreach($items as $items){
if($cartItems[$items->id]['id']){
echo '<h1 class="inCart">'. $item->title . '</h1>' //...
}else{
echo '<h1>'. $item->title . '</h1>' //...
}
}
The above code does not work - even though $cartItems[0]['id'] would return what I need. My thinking is, whilst looping through $items, check if the similar id exists in the $cartItems array. I also tried to add $cartItems[$i]['id'] and increment $i within the loop, and that did not work.
Of course the html output that I wanted to get is (simplified)
<h1 class="IsOnCart"> Item Title</h1>
<h1> Item Title</h1>
<h1 class="IsOnCart"> Item Title</h1>
<h1> Item Title</h1>
Is there a way to implement this?
Thanks
$intersection = array_intersect($arr1, $arr2);
if (in_array($value, $intersection)) {
// both arrays contain $value
}
You can try
$items = array(
0 =>
(object) (array(
'id' => 1,
'title' => 'Verity soap caddy',
'price' => '6.00',
)),
1 =>
(object) (array(
'id' => 2,
'title' => 'Kier 30cm towel rail',
'price' => '14.00',
)),
);
$cartItems = array(
0 => array(
'rowid' => 'c4ca4238a0b923820dcc509a6f75849b',
'id' => 1,
'qty' => 1,
'price' => '6.00',
'name' => 'Verity soap caddy',
'subtotal' => 6,
),
);
$itemsIncart = array_reduce(array_uintersect($items, $cartItems, function ($a, $b) {
$a = (array) $a;
$b = (array) $b;
return $a['id'] === $b['id'] ? 0 : 1;
}), function ($a, $b) {
$a[$b->id] = true;
return $a;
});
foreach ( $items as $item ) {
if (array_key_exists($item->id, $itemsIncart))
printf('<h1 class="inCart">%s *</h1>', $item->title);
else
printf('<h1>%s</h1>', $item->title);
}
Output
<h1 class="inCart">Verity soap caddy</h1>
<h1>Kier 30cm towel rail</h1>
I am trying to figure out the best way to write a PHP function that will recursively build a multi-dimensional array with an unknown number of sublevels from a mysql table. Its purpose is to create a data structure which can be looped through to create a navigation menu on a website, with each menu item possibly having a submenu with child menu items.
The fields of note in the table are:
int ItemID
int ParentID
varchar ItemText
text ItemLink
tinyint HasChildren
So an example of a returned array from the function would be:
$menuItems =
array(
itemID# =>
array(
'ItemText' => 'Home',
'ItemLink' => 'index.php',
'Children' => array(
itemID# => array (
'ItemText' => 'Home Sub 1',
'ItemLink' => 'somepage.php',
'Children' => 0
),
itemID# => array (
'ItemText' => 'Home Sub 2',
'ItemLink' => 'somepage2.php',
'Children' => 0
),
)
),
itemID# =>
array(
'ItemText' => 'Contact',
'ItemLink' => 'contact.php',
'Children' => 0
)
)
);
Would greatly appreciate if someone could point me in the right direction to accomplish this. Thanks!
Not too hard. What you do is store the menu items in an array where you can look them up by ID. Then you iterate over the menu items and if they have a non-null ParentID you add them to their parent's list of children. Then you remove all the children from the master list so you have only top-level items left.
Code:
<?php
$menuItems = array
(
1 => array
(
'ItemText' => 'Home',
'ItemLink' => 'index.php',
'ParentID' => null,
),
2 => array
(
'ItemText' => 'Home Sub 1',
'ItemLink' => 'somepage.php',
'ParentID' => 1,
),
3 => array
(
'ItemText' => 'Home Sub 2',
'ItemLink' => 'somepage2.php',
'ParentID' => 1,
),
4 => array
(
'ItemText' => 'Contact',
'ItemLink' => 'contact.php',
'ParentID' => null,
),
);
// Each node starts with 0 children
foreach ($menuItems as &$menuItem)
$menuItem['Children'] = array();
// If menu item has ParentID, add it to parent's Children array
foreach ($menuItems as $ID => &$menuItem)
{
if ($menuItem['ParentID'] != null)
$menuItems[$menuItem['ParentID']]['Children'][$ID] = &$menuItem;
}
// Remove children from $menuItems so only top level items remain
foreach (array_keys($menuItems) as $ID)
{
if ($menuItems[$ID]['ParentID'] != null)
unset($menuItems[$ID]);
}
print_r($menuItems);
?>
Output:
Array
(
[1] => Array
(
[ItemText] => Home
[ItemLink] => index.php
[ParentID] =>
[Children] => Array
(
[2] => Array
(
[ItemText] => Home Sub 1
[ItemLink] => somepage.php
[ParentID] => 1
[Children] => Array
(
)
)
[3] => Array
(
[ItemText] => Home Sub 2
[ItemLink] => somepage2.php
[ParentID] => 1
[Children] => Array
(
)
)
)
)
[4] => Array
(
[ItemText] => Contact
[ItemLink] => contact.php
[ParentID] =>
[Children] => Array
(
)
)
)
Have a function that calls itself every time it gets an array element.
As in:
Your function is called to display a node. Then it checks if the node its calling from has a sub menu, and if does, it calls itself again. And the process repeats until it dies out, and all the previous function calls return.
void printData($mysql_table_node){
if($mysql_table_node.has_node()){
for($i = 0; $i < $mysqql_table_node.num_nodes()){
printData($mysql_table_node->own_node);
}
}
return;
}
Multi-dimensional tree and an unordered HTML list generator
Recursively build a tree from a multi-dimensional array.
Generate a multi-dimensional HTML list code, from the tree (1).
You can't never know how many dimensions is in the given list of items.
Each element can have a son->Grandson->Great grandson an so on.
So, you must use a recursive function to generate a multi-dimensional list.
Here is the code:
<?php
$categories = array(
'1'=> array('name'=>'one','parent'=>null),
'2'=> array('name'=>'two','parent'=>null),
'20'=> array('name'=>'twenty','parent'=>'2'),
'21'=> array('name'=>'twenty one','parent'=>'2'),
'210'=> array('name'=>'two hundred and ten', 'parent'=>'21'),
'211'=> array('name'=>'two hundred and eleven', 'parent'=>'21'),
'212'=> array('name'=>'two hundred and twelve', 'parent'=>'21')
);
$tree=Menu::CreateTree($categories);
print_r($tree);
Menu::GenerateMenuHtmlCode($tree);
class Menu
{
public static function GenerateMenuHtmlCode($tree)
{
echo '<ul>';
foreach ($tree as $key=>$value)
{
echo "<li>".$value['name'];
if(!empty($value['sons']))
self::GenerateMenuHtmlCode($value['sons']);
echo "</li>";
}
echo '</ul>';
}
public static function CreateTree($categories)
{
$tree=array();
self::AddElement(&$categories,&$tree,null);
return $tree;
}
private function AddElement($categories,&$tree,$parent)
{
foreach ($categories as $key=>$value)
{
if($value['parent']==$parent)
{
$tree[$key]=$categories[$key];
$tree[$key]['sons']=array();
self::AddElement($categories,&$tree[$key]['sons'],$key);
}
if(empty($tree['sons'])) unset ($tree['sons']);
}
unset($categories[$parent]);
return ;
}
}
?>
The result:
Array
(
[1] => Array
(
[name] => one
[parent] =>
[sons] => Array()
)
[2] => Array
(
[name] => two
[parent] =>
[sons] => Array
(
[20] => Array
(
[name] => twenty
[parent] => 2
[sons] => Array()
)
[21] => Array
(
[name] => twenty one
[parent] => 2
[sons] => Array
(
[210] => Array
(
[name] => two hundred and ten
[parent] => 21
[sons] => Array()
)
[211] => Array
(
[name] => two hundred and eleven
[parent] => 21
[sons] => Array()
)
[212] => Array
(
[name] => two hundred and twelve
[parent] => 21
[sons] => Array()
)
)
)
)
)
)
and:
<ul>
<li>one</li>
<li>two
<ul>
<li>twenty</li>
<li>twenty one
<ul>
<li>two hundred and ten</li>
<li>two hundred and eleven</li>
<li>two hundred and twelve</li>
</ul>
</li>
</ul>
</li>
</ul>
I know this is a late reply but I found this script above and it was fantastic. I ran into an issue though with it unsetting my children because of the way the ItemID was working, when I ran it with a similarly designed table to the OP. To get around this, and given the amount of RAM in most web servers should be able to handle this, I've taken John Kugelman's great example and modified it slightly. Instead of having to apply children to all of the items and then unsetting them after, I create a new array and build it all in one
Code:
$new_array = array();
foreach ($menuItems as $key => &$menuItem) {
if (($menuItem['ParentID'] != NULL) && ($menuItem['ParentID'] != '')) {
$new_array[$menuItem['ParentID']]['Children'][$menuItem['ItemID']] = &$menuItem;
} else {
$new_array[$menuItem['ItemID']] = &$menuItem;
}
}
print_r($new_array);
Hope this helps someone else because the above certainly helped me