6

Ok, so I have an array like so:

$buttons = array(
    'home' => array(
        'title' => $txt['home'],
        'href' => $scripturl,
        'show' => true,
        'sub_buttons' => array(
        ),
        'is_last' => $context['right_to_left'],
    ),
    'help' => array(
        'title' => $txt['help'],
        'href' => $scripturl . '?action=help',
        'show' => true,
        'sub_buttons' => array(
        ),
    ),
    'search' => array(
        'title' => $txt['search'],
        'href' => $scripturl . '?action=search',
        'show' => $context['allow_search'],
        'sub_buttons' => array(
        ),
    ),
    'admin' => array(
        'title' => $txt['admin'],
        'href' => $scripturl . '?action=admin',
        'show' => $context['allow_admin'],
        'sub_buttons' => array(
            'featuresettings' => array(
                'title' => $txt['modSettings_title'],
                'href' => $scripturl . '?action=admin;area=featuresettings',
                'show' => allowedTo('admin_forum'),
            ),
            'packages' => array(
                'title' => $txt['package'],
                'href' => $scripturl . '?action=admin;area=packages',
                'show' => allowedTo('admin_forum'),
            ),
            'errorlog' => array(
                'title' => $txt['errlog'],
                'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc',
                'show' => allowedTo('admin_forum') && !empty($modSettings['enableErrorLogging']),
            ),
            'permissions' => array(
                'title' => $txt['edit_permissions'],
                'href' => $scripturl . '?action=admin;area=permissions',
                'show' => allowedTo('manage_permissions'),
                'is_last' => true,
            ),
        ),
    ),
    'moderate' => array(
        'title' => $txt['moderate'],
        'href' => $scripturl . '?action=moderate',
        'show' => $context['allow_moderation_center'],
        'sub_buttons' => array(
            'modlog' => array(
                'title' => $txt['modlog_view'],
                'href' => $scripturl . '?action=moderate;area=modlog',
                'show' => !empty($modSettings['modlog_enabled']) && !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
            ),
            'poststopics' => array(
                'title' => $txt['mc_unapproved_poststopics'],
                'href' => $scripturl . '?action=moderate;area=postmod;sa=posts',
                'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
            ),
            'attachments' => array(
                'title' => $txt['mc_unapproved_attachments'],
                'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments',
                'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
            ),
            'reports' => array(
                'title' => $txt['mc_reported_posts'],
                'href' => $scripturl . '?action=moderate;area=reports',
                'show' => !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
                'is_last' => true,
            ),
        ),
    ),
    'profile' => array(
        'title' => $txt['profile'],
        'href' => $scripturl . '?action=profile',
        'show' => $context['allow_edit_profile'],
        'sub_buttons' => array(
            'summary' => array(
                'title' => $txt['summary'],
                'href' => $scripturl . '?action=profile',
                'show' => true,
            ),
            'account' => array(
                'title' => $txt['account'],
                'href' => $scripturl . '?action=profile;area=account',
                'show' => allowedTo(array('profile_identity_any', 'profile_identity_own', 'manage_membergroups')),
            ),
            'profile' => array(
                'title' => $txt['forumprofile'],
                'href' => $scripturl . '?action=profile;area=forumprofile',
                'show' => allowedTo(array('profile_extra_any', 'profile_extra_own')),
                'is_last' => true,
            ),
        ),
    ),
    'pm' => array(
        'title' => $txt['pm_short'],
        'href' => $scripturl . '?action=pm',
        'show' => $context['allow_pm'],
        'sub_buttons' => array(
            'pm_read' => array(
                'title' => $txt['pm_menu_read'],
                'href' => $scripturl . '?action=pm',
                'show' => allowedTo('pm_read'),
            ),
            'pm_send' => array(
                'title' => $txt['pm_menu_send'],
                'href' => $scripturl . '?action=pm;sa=send',
                'show' => allowedTo('pm_send'),
                'is_last' => true,
            ),
        ),
    ),
    'calendar' => array(
        'title' => $txt['calendar'],
        'href' => $scripturl . '?action=calendar',
        'show' => $context['allow_calendar'],
        'sub_buttons' => array(
            'view' => array(
                'title' => $txt['calendar_menu'],
                'href' => $scripturl . '?action=calendar',
                'show' => allowedTo('calendar_post'),
            ),
            'post' => array(
                'title' => $txt['calendar_post_event'],
                'href' => $scripturl . '?action=calendar;sa=post',
                'show' => allowedTo('calendar_post'),
                'is_last' => true,
            ),
        ),
    ),
    'mlist' => array(
        'title' => $txt['members_title'],
        'href' => $scripturl . '?action=mlist',
        'show' => $context['allow_memberlist'],
        'sub_buttons' => array(
            'mlist_view' => array(
                'title' => $txt['mlist_menu_view'],
                'href' => $scripturl . '?action=mlist',
                'show' => true,
            ),
            'mlist_search' => array(
                'title' => $txt['mlist_search'],
                'href' => $scripturl . '?action=mlist;sa=search',
                'show' => true,
                'is_last' => true,
            ),
        ),
    ),
    'login' => array(
        'title' => $txt['login'],
        'href' => $scripturl . '?action=login',
        'show' => $user_info['is_guest'],
        'sub_buttons' => array(
        ),
    ),
    'register' => array(
        'title' => $txt['register'],
        'href' => $scripturl . '?action=register',
        'show' => $user_info['is_guest'],
        'sub_buttons' => array(
        ),
        'is_last' => !$context['right_to_left'],
    ),
    'logout' => array(
        'title' => $txt['logout'],
        'href' => $scripturl . '?action=logout;%1$s=%2$s',
        'show' => !$user_info['is_guest'],
        'sub_buttons' => array(
        ),
        'is_last' => !$context['right_to_left'],
    ),
);

Now I want to be able to insert an array into it, either before or after any of the keys within the array above. The array that I want to insert can look like this:

$new_menu_buttons['testing'] = array(
    'title' => $txt['testing'],
    'href' => $scripturl . '?action=testing',
    'show' => true,
    'target' => '_self',
    'active_button' => false,
);

Someone recommended functions to handle this and methods to use, but I'm not sure how to do this, they are wanting offsets for these functions also. Here is the function structure that someone recommended I use for this, than just call these functions when needed:

function array_insert_before($array, $key, $new_array)
{
    // Splice array in two at key, keeping key on the right side
    // Append new value on the left tail
    // Glue both arrays into a new array
    // Return new array
}
function array_insert_after($array, $key, $new_array)
{
    // Symmetric with right & left switched
}

So, I want to be able to call the functions like so:

If it needs to go after the key, 'home' that is specified:

$menu_buttons = array_insert_after($buttons, 'home', $new_menu_buttons);

If it needs to go before the key, 'home' that is specified:

$menu_buttons = array_insert_before($buttons, 'home', $new_menu_buttons);

Basically, I really need help with these functions, any help would be great.

Should I be using array_splice or array_slice? Would someone be willing to start me off in the right direction here with some actual code please?

Thanks guys :)

Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
SoLoGHoST
  • 2,673
  • 7
  • 30
  • 51
  • wouldnt it be easier to introduce a position value and sort it by that before creating the navigation? Or use an SplHeap or PriorityQueue to keep the navigation in order? – Gordon Jun 28 '11 at 06:53
  • If you feel that this question has been answered, then you should mark it answered (check button under the ratings for an answer). – cwallenpoole Jun 29 '11 at 05:16

2 Answers2

5

This should get you started. Note: I haven't tested this. It's off the top of my head.

/**
 * This will insert $new at the beginning if $key is not found
 */
function array_insert_before($array, $key, $new)
{
    $keys = array_keys($array);
    $pos = (int) array_search($key, $keys);
    return array_merge(
        array_slice($array, 0, $pos),
        $new,
        array_slice($array, $pos)
    );
}

array_insert_after() is pretty much the same, except $pos is increased by one. You should be able to figure that out by yourself.

Sander Marechal
  • 22,978
  • 13
  • 65
  • 96
  • 2
    @Sander Marechal - Instead of using your `return array_merge(...)` call, you could use `return array_splice($array, $position, 0, $new);`. If the `length` parameter is set to 0, it'll insert at the after `offset` and leave the rest intact. – Francois Deschenes Jun 28 '11 at 06:04
  • hello Sander, `$key` will always be found, since this is a key from the same $array, it's NOT user-inputted. But it needs to be this way since I need to do this within the array, after it has been created. Thanks will give it a go and see if this helps me any. – SoLoGHoST Jun 28 '11 at 06:27
  • SoLoGHoST - The `return array_merge(...)` is calling `array_slice` twice so that's a total of 3 function calls. You can replace it with what I wrote in my first comment (the `return array_splice(...)`). To answer your comment to @Sander Marechal, `array_search` is searching for the position of the key in the array and not whether or not it exists. The `array_slice` and `array_splice` both need to know the position and not the key. – Francois Deschenes Jun 28 '11 at 06:38
  • @SoLoGHoSt - The line should have `return` in it actually. It should return on the next line (`return $array`); The other thing is in @Sander Marechal's code above, `array_search($keys, $key)` should be `array_search($key, $keys);`. – Francois Deschenes Jun 28 '11 at 06:54
  • 1
    @Sander Marechal - The `array_splice` doesn't work, I think it's because the `replacement` parameter in the `array_splice` function does not PRESERVE the keys for the `$new` array. The way you had it worked PERFECT, cept you should have `array_search($key, $keys;)` instead. I used your method and adapted it better for my needs in the Answer below. – SoLoGHoST Jun 28 '11 at 17:05
  • `array_search($key, $keys);` I meant to say. – SoLoGHoST Jun 29 '11 at 01:06
  • @SoLoGHoST: You're correct. I've rolled back my edit and updated it with your correction. – Sander Marechal Jun 29 '11 at 05:01
0

Ok, after playing with it for quite some time, I finally got it working the way I want it. I am using certain keys within the $new_menu_buttons to decide on what to do. e.g.: position tells me if it is after or before, parent tells me where to search for the key at, and slug gives me the key to use for each new menu array that gets added. array_splice isn't working for me, so I'm using the array_merge approach instead which works just great. Here it is for anyone else who gets stuck with this problem.

function array_insert_buttons($buttons, $new_menu_buttons)
{
    foreach($new_menu_buttons as $new)
    {
        $keys = array_keys($buttons);
        $position = (int)array_search($new['parent'], $keys);

        if ($new['position'] == 'after')
            $position = $position + 1;

        // Create the new array in the correct format, using the slug!
        $new_button = array();
        $new_button[$new['slug']] = $new;

        // Don't need these keys anymore.
        unset($new_button[$new['slug']]['position']);
        unset($new_button[$new['slug']]['parent']);
        unset($new_button[$new['slug']]['slug']);

        // Putting it all together now.
        $buttons = array_merge(
            array_slice($buttons, 0, $position),
            $new_button,
            array_slice($buttons, $position)
        );
    }

    return $buttons;
}

Thanks for your help guys :)

SoLoGHoST
  • 2,673
  • 7
  • 30
  • 51