2

「メニュー配列」に追加するための「プラグイン」のようなスクリプトを作成しようとしています....すぐに行きます..

次のようにナビゲーション アイテムを開始するとします。

$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
));

新しいセクションを作成し、インスタンスを取得することから始めます。

次に、ユーザーが確認済みとして認証されているかどうかを確認するためにテストする「ロール」を設定します。

set nav アイテムは単に配列を格納します。identifier はアイテムへの参照です (サブアイテムを追加したい場合)。ナビのどこに配置するかを示す「位置」以外はすべて標準です。つまり、NULL はトップレベルです。array('topnav','subnav ') topnav->subnav->dashboard になります。

テストとして、これは次のように保存できます。

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] =>
                        )
                )
        )
) 
4

2 に答える 2

2

これが、再帰で解決された問題に対する私の見解です。

複数の位置を使用できます(これが配列である理由だと思います)。少なくとも1つの位置が見つかった場合、欠落している位置は無視されますが、すべての位置が欠落している場合は文句を言います。

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

于 2012-08-16T20:03:54.357 に答える
2

そこに追加できるように、識別子をその子配列にマップする一時配列が必要です。

私がそれを正しく見れば、親を追加するとき、あなたはすでにここにそのようなものを持っています:

$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;
}

また、配列ではなくオブジェクトを使用して、データをそれほど複製しないようにすることもできます (または、後で変更することもできます)。

于 2012-08-16T19:03:31.540 に答える