I am stuck to an array structure and need to sort them. Here is a small example of the array:
$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';
$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
There could be n amount of BRAND_N and n amount of SUB_BRAND_N.
I have an order ID which stucks to a flexible order:
0 = out as in (dont worry about this, catch it at an earlier stage)
1 = BRAND_1.SUB_BRAND_1
2 = BRAND_1.SUB_BRAND_2
3 = BRAND_2.SUB_BRAND_1
This gets extended if there are more as these four cases and the order itself could change. So I have to work with the IDs.
The order should change the position in the array and push the value of the Id to the top in the array, for example:
order id = 2:
$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
order id = 3:
$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';
I have tried this so far:
<?php
$order[1] = 'BRAND_1::SUB_BRAND_1';
$order[2] = 'BRAND_1::SUB_BRAND_2';
$order[3] = 'BRAND_2::SUB_BRAND_1';
// for testing
$orderId = 2;
// get the brand and sub_brand
$part = explode("::", $order[$orderId]);
// set the new brand list
$newBrand[$part[0]]['name'] = $brand[$part[0]]['name'];
$newBrand[$part[0]]['list'][$part[1]] = $brand[$part[0]]['list'][$part[1]];
// unset the brand which should be first of the main brand array
unset($brand[$part[0]]['list'][$part[1]]);
// if there was only one list unset the whole brand part
if( count($brand[$part[0]]['list']) < 1 ) {
unset( $brand[$part[0]] );
}
Now I have two arrays:
$brand includes the whole brands except this one which should be the first
$newBrand includes only this brand which should be at the top
Now I just need to add $brand to $newBrand but there is my problem.
Tried a lot of different ways from rebuilding the array to push the content, replace or merge... but I always run in circles.
I wrote the whole code into codepad.org for better testing: Codepad example
EDIT:
The order is a specification outside the code. The aim is to set one element depending on the orderId to the top in the $brand array. The $orderId will get passed by POST, GET or a class call.
The $order array is just an array which helps me to make the specification accessible in the code.
So the $orderId match one element of the $order array and will return this element which should be on the top of the $brand array. Due to the fact that there is no numeric keys I decide to use the "brand::sub_brand" syntax to access on both depth level.
Here is one possible solution (test it here):
<?php
function getOrderingRules()
{
return array(
1 => 'BRAND_1.SUB_BRAND_1',
2 => 'BRAND_1.SUB_BRAND_2',
3 => 'BRAND_2.SUB_BRAND_1',
);
}
function getOrderedBrands($brands, $orderId)
{
$rules = getOrderingRules();
if (!isset($rules[$orderId])) {
throw new RuntimeException("Rule for order id '$orderId' is not specified");
}
$result = array();
// Push the first element
list($key, $subkey) = explode('.', $rules[$orderId]);
$result[$key] = array(
'name' => $brands[$key]['name'],
'list' => array(
$subkey => $brands[$key]['list'][$subkey],
),
);
// Push remaining elements in the order they appear in $rules
foreach ($rules as $oid => $rule) {
// Skip order id of the first element
if ($oid == $orderId) {
continue;
}
list($key, $subkey) = explode('.', $rules[$oid]);
if (!isset($result[$key])) {
$result[$key] = array(
'name' => $brands[$key]['name'],
'list' => array(),
);
}
$result[$key]['list'][$subkey] = $brands[$key]['list'][$subkey];
}
return $result;
}
// Loading all brands (could be external source, like database)
$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';
$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
// Sort and output
print_r(getOrderedBrands($brand, 1));
print_r(getOrderedBrands($brand, 2));
print_r(getOrderedBrands($brand, 3));
You should be aware that with this array structure ($brands
) you won't be able to set ordering rules like this:
1 = BRAND_1.SUB_BRAND_1
2 = BRAND_2.SUB_BRAND_1
3 = BRAND_1.SUB_BRAND_2
because once you met element keyed by BRAND_1
, you have to iterate over all of it's sub-brands. If you don't have such rules, everything is fine. Otherwise you have to store sorted array structured like this (because actually you are sorting sub-brands, not brands):
$subBrands = array(
array(
'name' => 'Headline Subbrand 1',
'text' => 'Text for it',
'parent' => 'BRAND_1',
'key' => 'SUB_BRAND_1',
),
array(
'name' => 'Headline Subbrand 2',
'text' => 'Text for it',
'parent' => 'BRAND_1',
'key' => 'SUB_BRAND_2',
),
);
$parentBrands = array(
'BRAND_1' => 'Brand Name 1',
'BRAND_2' => 'Brand Name 2',
);
Then you can sort $subBrands
and iterate over it