I have an extremely large function for turning my database output of menu links into a multidimensional array that nests each of the links in a menu fashion. I'm wondering if anyone sees a way this class function can be shortened or simplified in some way.
The mysqli query:
private function _interactions($product, $permissions, $mymenu){
$myMenuArray = !empty($mymenu) ? explode(",", $mymenu) : NULL;
$myDBMenuArray = array();
$stmt = $this->mysqli->select("SELECT * FROM skss_".$product."_menu WHERE permissions >= ?", array($permissions), array("%i"));
if(count($stmt)>0 && empty($myMenuArray)){
array_walk($stmt, (function(&$item){$item = (array)$item;}));
$myDBMenuArray = array_merge($stmt);
}
else if(count($stmt)>0){
foreach($stmt as $obj){
$found = array_search($obj->data_target, $myMenuArray);
if($found !== FALSE){ $myDBMenuArray[] = (array)$obj; }
}
}
return $this->_buildMenuAndActions($myDBMenuArray);
}
Which returns this array from the DB:
Array
(
[0] => Array
(
[data_target] => '#address-modal'
[ancor_value] => 'Address Dialog'
[inmenu] => 0
[static] => 1
[keyboard] => 1
[name] => 'address-modal-link'
[href] =>
[menuID] =>
[permissions] => 9
)
[1] => Array
(
[data_target] => '#error-modal'
[ancor_value] => 'Error Modal'
[inmenu] => 0
[static] => 1
[keyboard] => 1
[name] => 'error-modal-link'
[href] =>
[menuID] =>
[permissions] => 9
)
[2] => Array
(
[data_target] => '#message-modal'
[ancor_value] => 'Message Modal'
[inmenu] => 0
[static] => 1
[keyboard] => 0
[name] => 'message-modal-link'
[href] =>
[menuID] =>
[permissions] => 9
)
[3] => Array
(
[data_target] => '#mytarget'
[ancor_value] => 'unknown'
[inmenu] => 0
[static] => 1
[keyboard] => 1
[name] => 'mytarget'
[href] =>
[menuID] => '#address-modal'
[permissions] => 9
)
[4] => Array
(
[data_target] => '#mytarget2'
[ancor_value] => 'mytarget'
[inmenu] => 0
[static] => 1
[keyboard] => 1
[name] => 'mytarget'
[href] =>
[menuID] => '#address-modal'
[permissions] => 0
)
[5] => Array
(
[data_target] => '#mytarget3'
[ancor_value] => 'mytarget3'
[inmenu] => 0
[static] => 1
[keyboard] => 1
[name] => 'mytarget3'
[href] =>
[menuID] => '#mytarget'
[permissions] => 9
)
[6] => Array
(
[data_target] => '#user-modal'
[ancor_value] => 'User Dialog'
[inmenu] => 0
[static] => 1
[keyboard] => 1
[name] => 'user-modal-link'
[href] =>
[menuID] =>
[permissions] => 9
)
[7] => Array
(
[data_target] => '#userImage-modal'
[ancor_value] => 'User Image Modal'
[inmenu] => 0
[static] => 1
[keyboard] => 0
[name] => 'userImage-modal-link'
[href] =>
[menuID] =>
[permissions] => 9
)
[8] => Array
(
[data_target] => '#wait-modal'
[ancor_value] => 'Wait/Loading Modal'
[inmenu] => 0
[static] => 1
[keyboard] => 0
[name] => 'wait-modal-link'
[href] =>
[menuID] =>
[permissions] => 9
)
)
This is my rather very complicated class function for turning all my links into menu nested items.
private function _buildMenuAndActions($interactions, $myList = array()){
$myMenu = array();
foreach($interactions as $interaction){
// First layers.
// If $interaction['menuID'] would ever purposely be a zero (for
// instance as a numerical row ID), this would need to be a
// "=== NULL" comparison and NULL would need to be maintained
// on the DB.
if(empty($interaction['menuID'])){
$searchFor = $interaction['data_target'];
$filteredArray =
array_filter($interactions, function($element) use($searchFor){
return isset($element['menuID']) && $element['menuID'] == $searchFor;
});
$myMenu[] = array("link" => $this->_create($interaction), "children" => !empty($filteredArray) ? $this->_buildMenuAndActions($filteredArray, $interactions) : array());
}
// Layers with nestable layers.
else if(
!empty($myList) && (array_search($interaction['data_target'], array_column($myList, 'menuID')) !== FALSE)
){
$searchFor = $interaction['data_target'];
$filteredArray =
array_filter($myList, function($element) use($searchFor){
return isset($element['menuID']) && $element['menuID'] == $searchFor;
});
$myMenu[] = array("link" => $this->_create($interaction), "children" => !empty($filteredArray) ? $this->_buildMenuAndActions($filteredArray, $myList) : array());
}
// Layers without nestable layers.
else if(
!empty($myList) && !(array_search($interaction['data_target'], array_column($myList, 'menuID')) !== FALSE)
){
$searchFor = $interaction['data_target'];
$filteredArray =
array_filter($interactions, function($element) use($searchFor){
return isset($element['menuID']) && $element['menuID'] == $searchFor;
});
$myMenu[] = array("link" => $this->_create($interaction), "children" => !empty($filteredArray) ? $this->_buildMenuAndActions($filteredArray) : array());
}
}
return $myMenu;
}
Example output:
Array
(
[0] => Array
(
[link] => '#address-modal'
[children] => Array
(
[0] => Array
(
[link] => '#mytarget'
[children] => Array
(
[0] => Array
(
[link] => '#mytarget3'
[children] => Array
(
)
)
)
)
[1] => Array
(
[link] => '#mytarget2'
[children] => Array
(
)
)
)
)
[1] => Array
(
[link] => '#error-modal'
[children] => Array
(
)
)
[2] => Array
(
[link] => '#message-modal'
[children] => Array
(
)
)
[3] => Array
(
[link] => '#user-modal'
[children] => Array
(
)
)
[4] => Array
(
[link] => '#userImage-modal'
[children] => Array
(
)
)
[5] => Array
(
[link] => '#wait-modal'
[children] => Array
(
)
)
)
So, ah. Any ideas for simplifying this?