I have a product catalog represented as a single (large) associative PHP array ($productsJSON) that I'm trying to turn into a product catalog.
A catalog consists of (theoretically infinite) category levels nested under one another.
>Parent Category - has CategoryLevel set as 1. Name and text are printed.
->1st child Category - has CategoryLevel set as 2
and so on down. Name and text are printed.
-->Final child Category - has CategoryLevel set as 1, 2, 5, 9 etc and also has IsCollection equal to 'Yes'. Name and text are printed. Product table is drawn.
This is a snippet of the $productsJSON array for reference.
Array
(
[CategoryID] => 8674
[UID] => 2
[timestamp] => 1597620853
[CategoryName] => Cat Aut
[CategorySortOrder] => 1
[CategoryLevel] => 1
[assetType] => category
[IsCollection] => No
[children] => Array
(
[0] => Array
(
[CategoryID] => 8675
[UID] => 5
[timestamp] => 1597620853
[CategoryName] => Test 1
[CategorySortOrder] => 1
[CategoryLevel] => 2
[assetType] => category
[IsCollection] => No
[children] => Array
(
[0] => Array
(
[CategoryID] => 8677
[UID] => 9
[timestamp] => 1597620853
[CategoryName] => Test 1A
[CategorySortOrder] => 1
[CategoryLevel] => 3
[assetType] => category
[IsCollection] => No
[children] => Array
(
[0] => Array
(
[CategoryID] => 8682
[UID] => 14
[timestamp] => 1597620853
[CategoryName] => Collection 1A No1
[CategorySortOrder] => 1
[CategoryLevel] => 4
[assetType] => category
[IsCollection] => Yes
[children] => Array
(
[0] => Array
(
[assetType] => table
[UID] => 14
[timestamp] => 1597620853
[header] => Array
(
[0] => Array
(
[value] => ProductCode
)
[1] => Array
(
[value] => ProductName
)
[2] => Array
(
[value] => ProductWidth
)
[3] => Array
(
[value] => ProductHeight
)
[4] => Array
(
[value] => Length
)
)
[widths] => Array
(
[0] => 2
[1] => 10
[2] => 2
[3] => 2
[4] => 2
)
[rows] => Array
(
[0] => Array
(
[0] => Array
(
[value] => 00001
)
[1] => Array
(
[value] => Product 01
)
[2] => Array
(
[value] => 50
)
[3] => Array
(
[value] => 50
)
[4] => Array
(
[value] => 110
)
)
[1] => Array
(
[0] => Array
(
[value] => 00002
)
[1] => Array
(
[value] => Product 02
)
[2] => Array
(
[value] => 50
)
[3] => Array
(
[value] => 50
)
[4] => Array
(
[value] => 210
)
)
The full array (as a JSON file) can be found here https://pastebin.com/k8vhGGS5
I'm using $productsJSON = json_decode($str, true); to convert to a PHP array.
Stepping through the tree, I need to be able to run a function to add category names, text etc for all Category nodes (whether IsCollection is Yes or No) and then for the terminal level (where IsCollection is Yes) I need to draw the product table. (I already have this function).
What I can't grasp is how to efficiently traverse the catalog array without hardcoding the various paths, e.g. $productsJSON['children'][0]['children'][0]['children'][0]['header'] to iterate through each of the table headers.
I have tried a nested search function, as explained e.g. How to search by key=>value in a multidimensional array in PHP
function search($array, $key, $value)
{
$results = array();
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
echo "<pre>";
print_r(search($productsJSON, 'assetType', 'table'));
echo "</pre>";
I have also tried using the RecursiveIteratorIterator and RecursiveArrayIterator combination, as explained e.g. Iterating over a complex Associative Array in PHP (look at the second answer) - but this seems to explode the array completely and I'm then not able to iterate over each of the categories, or the table header, widths and data rows.
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($productsJSON));
$ntree=-1;
$v=0;
$treeArray = array();
foreach($iterator as $key => $value)
{
echo "$ntree $key - $value<br />";
if($key === "CategoryID" || $key === "CategoryName" || $key === "CategoryLevel" || $key === "IsCollection")
{
if($key === "CategoryID")
{
$ntree++;
$treeArray[$ntree]['CategoryID'] = $value;
}
if($key === "CategoryName")
{
$treeArray[$ntree]['CategoryName'] = $value;
}
if($key === "CategoryLevel")
{
$treeArray[$ntree]['CategoryLevel'] = $value;
}
if($key === "IsCollection")
{
$treeArray[$ntree]['IsCollection'] = $value;
}
}
if($key === "assetType" && $value === "table")
{
$treeArray[$ntree]['assetType'] = $value;
$treeArray[$ntree]['thisV'] = $v;
$tableLine=1;
}
if($tableLine > 2)
{
$treeArray[$ntree]['widths'] = $value;
}
$v++;
$tableLine++;
}
Once I have the array I have no problem getting my category headings on the page, nor writing the table header and data rows.
I have spent the whole weekend poring over Stack Overflow and all sorts of array tutorials but I'm stuck. I'd really appreciate some help.
(Also, this is my first ever question here. Apologies in advance if I haven't explained something as well as I should. I'll do my best to edit the question if/when I get any feedback.)