我正在尝试创建一个类似脚本的“插件”,用于添加“菜单数组”......我会直接进入..
假设我发起了这样的导航项目:
$sections->add_section('dashboard');
$DashBoardSection = $sections->load_section('dashboard');
$DashBoardSection->set_role(NULL);
$DashBoardSection->set_nav_item(array(
'identifier' => 'dashboard',
'text' => 'Dashboard',
'url' => NULL,
'position' => NULL
));
首先创建一个新部分并获取实例。
然后我们设置一个“角色”,我们将在其中进行测试,以确定用户是否经过身份验证,以确认是否可以查看。
设置导航项只是存储数组。标识符是对项目的引用(它用于我们想要添加子项目时),除了“位置”之外的所有标准,它指出它在nav中的位置,即NULL是顶级,数组('topnav','subnav ')将是topnav-> subnav->仪表板。
作为测试,可以按如下方式存储:
Array
(
[0] => Array
(
[identifier] => dashboard
[text] => Dashboard
[url] =>
[position] =>
)
[1] => Array
(
[identifier] => dashboard2
[text] => Dashboard2
[url] =>
[position] => Array
(
[0] => dashboard
)
)
)
我的问题是如何将其转换为以下结构:
Array
(
[0] => Array
(
[identifier] => dashboard
[text] => Dashboard
[url] =>
[position] =>
[children] => Array
(
[0] => Array
(
[identifier] => dashboard2
[text] => Dashboard2
[url] =>
)
)
)
)
将头发拉过这一头,任何帮助都会非常感激。
问候
我目前有
public function build_navigation( $role ){
$role = (int)$role;
$nav = array();
foreach( $this->sections as $section ) {
if( $section->get_role() === NULL || $section->get_role() === $role ) {
$nav_array = $section->get_nav();
foreach( $nav_array as $key => $nav_item ) {
if( $nav_item['position'] === NULL ) {
$nav[$nav_item['identifier']] = $nav_item;
}elseif( is_array( $nav_item['position'] ) ){
#...#
}
}
}
}
return $nav;
}
修改
想象一下这是给出的数组(可以按任意顺序)
Array
(
[0] => Array
(
[identifier] => dashboard_child2
[text] => Dashboard Child 2
[url] =>
[position] => Array
(
[0] => dashboard
)
)
[1] => Array
(
[identifier] => dashboard_child_child_1
[text] => Dashboard Child Child 1
[url] =>
[position] => Array
(
[0] => dashboard
[1] => dashboard_child1
)
)
[2] => Array
(
[identifier] => dashboard_child1
[text] => Dashboard Child 1
[url] =>
[position] => Array
(
[0] => dashboard
)
)
[3] => Array
(
[identifier] => dashboard
[text] => Dashboard
[url] =>
[position] =>
)
[4] => Array
(
[identifier] => dashboard2
[text] => Dashboard2
[url] =>
[position] => Array
(
[0] => dashboard
)
)
)
需要格式化为:
Array
(
[dashboard] => Array
(
[text] => Dashboard
[url] =>
[children] => Array
(
[dashboard_child2] => Array
(
[text] => Dashboard Child 2
[url] =>
)
[dashboard_child1] => Array
(
[text] => Dashboard Child 1
[url] =>
[children] => Array
(
[dashboard_child_child_1] => Array
(
[text] => Dashboard Child Child 1
[url] =>
)
)
)
[dashboard2] => Array
(
[text] => Dashboard2
[url] =>
)
)
)
)
答案 0 :(得分:2)
您需要一个临时数组,将标识符映射到它的children数组,以便您可以将其添加到那里。
如果我看到了这一点,那么当您添加父级时,您已经有了类似的内容:
$nav[$nav_item['identifier']] = $nav_item;
编辑:如评论所述,添加父母需要谨慎:
$node = &$nav[$nav_item['identifier']];
$children = isset($node['children']) ? $node['children'] : array();
$node = $nav_item;
$node['children'] = $children;
unset($node);
然后加入孩子们:
foreach($nav_item['position'] as $identifier)
{
$nav[$identifier]['children'][] = $nav_item;
}
此外,您可以使用对象,而不是数组,这样您就不会复制太多数据(或者您可以在以后更改它),但是,只是想一想,这对于解决您的问题来说不是必需的,所以可能需要稍后解决。
答案 1 :(得分:2)
这是我对问题的看法,通过递归解决。
你可以使用多个位置(我猜这就是为什么它是一个数组),如果至少找到了位置,它会忽略缺失的位置,但如果每个位置都丢失,它会抱怨。
function translate($in) {
$out = array();
// first pass, move root nodes to output
foreach ($in as $k => $row) {
if (!$row['position']) {
$out[$row['identifier']] = $row;
unset($in[$k]);
}
}
// while we have input
do {
$elements_placed = 0;
// step trough input
foreach ($in as $row_index => $row) {
foreach ($row['position'] as $pos) {
// build context for the node placing
$data = array(
'row' => $row,
'in' => &$in,
'row_index' => $row_index,
'elements_placed' => &$elements_placed,
'pos' => $pos,
);
// kick of recursion
walker($out, $data);
}
}
} while ($elements_placed != 0);
if (count($in)) {
trigger_error("Error in user data, can't place every item");
}
return $out;
}
function walker(&$out, $data) {
foreach ($out as &$row) {
// it looks like a node array
if (is_array($row) && isset($row['identifier'])) {
// if it has children recurse in there too
if (isset($row['children'])) {
walker($row['children'], $data);
}
// it looks like a node array that we are looking for place the row
if ($row['identifier'] == $data['pos']) {
if (!isset($row['children'])) {
$row['children'] = array($data['row']['identifier'] => $data['row']);
} else {
$row['children'][$data['row']['identifier']] = $data['row'];
}
// report back to the solver that we found a place
++$data['elements_placed'];
// remove the row from the $in array
unset($data['in'][$data['row_index']]);
}
}
}
}
$in = array (
array (
'identifier' => 'secondlevelchild2',
'text' => 'secondlevelchild2',
'url' => '',
'position' => array (
'dashboard2',
),
),
array (
'identifier' => 'secondlevelchild',
'text' => 'secondlevelchild',
'url' => '',
'position' => array (
'dashboard2',
),
),
array (
'identifier' => 'dashboard',
'text' => 'Dashboard',
'url' => '',
'position' => '',
),
array (
'identifier' => 'dashboard2',
'text' => 'Dashboard2',
'url' => '',
'position' => array (
'dashboard', 'home',
),
),
array (
'identifier' => 'thirdlevelchild',
'text' => 'thirdlevelchild',
'url' => '',
'position' => array (
'secondlevelchild2',
),
),
);
$out = translate($in);
var_export($out);
在它的当前形式中,一旦放置它们,它就不会从节点数组中删除identifier
或position
个键。