admin/controllers/AdminRouter.php
public function prepAdminControllersNav()
    {
        $adminControllersNav = [];

        foreach ($this->adminControllers as $module => $moduleDetails) {
            foreach ($moduleDetails->controllers as $controller => $controllerDetails) {
                foreach ($controllerDetails['groupings'] as $grouping) {

                    //  Begin by defining which group this action belongs in
                    $sGroupLabel = $grouping->getLabel();

                    if (!isset($adminControllersNav[md5($sGroupLabel)])) {
                        $adminControllersNav[md5($sGroupLabel)]           = new \stdClass();
                        $adminControllersNav[md5($sGroupLabel)]->label    = $sGroupLabel;
                        $adminControllersNav[md5($sGroupLabel)]->icon     = [];
                        $adminControllersNav[md5($sGroupLabel)]->sortable = true;
                        $adminControllersNav[md5($sGroupLabel)]->open     = false;
                        $adminControllersNav[md5($sGroupLabel)]->actions  = [];
                    }

                    /**
                     * Add the group icon to the icon array. Multiple calls to the same group
                     * will add their own icon, the most common icon will be used. In the event
                     * of a tie then the first icon defined will be used, unless one has been
                     * marked as !important.
                     */

                    $moduleIcon = $grouping->getIcon();

                    if (!empty($moduleIcon)) {

                        $adminControllersNav[md5($sGroupLabel)]->icon[] = $moduleIcon;
                    }

                    //  Group actions
                    $groupActions = $grouping->getActions();

                    foreach ($groupActions as $actionUrl => $actionDetails) {

                        $url = $module . '/' . lcfirst($controller);
                        $url .= empty($actionUrl) ? '' : '/';
                        $url .= $actionUrl;

                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]         = new \stdClass();
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->order  = $actionDetails->order;
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->label  = $actionDetails->label;
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->alerts = $actionDetails->alerts;
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->class  = $controllerDetails['className'];
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->path   = $controllerDetails['path'];
                    }
                }
            }
        }

        //  Reset the indexes
        $adminControllersNav = array_values($adminControllersNav);

        //  Remove navGroups with no actions and set as sortable
        $numGroups = count($adminControllersNav);
        for ($i = 0; $i < $numGroups; $i++) {

            //  Remove if empty
            if (empty($adminControllersNav[$i]->actions)) {
                $adminControllersNav[$i] = null;
                continue;
            }

            //  Set sortable
            if (in_array($adminControllersNav[$i]->label, $this->adminControllersNavSticky)) {
                $adminControllersNav[$i]->sortable = false;
            }
        }

        //  Filter and reset the indexes, again
        $adminControllersNav = array_filter($adminControllersNav);
        $adminControllersNav = array_values($adminControllersNav);

        //  Split the groups
        $stickyTop    = [];
        $middle       = [];
        $stickyBottom = [];

        foreach ($this->adminControllersNavSticky as $sticky) {
            foreach ($adminControllersNav as $group) {
                if ($group->label == $sticky) {
                    if (in_array($sticky, $this->adminControllersNavStickyBottom)) {
                        $stickyBottom[] = $group;
                    } else {
                        $stickyTop[] = $group;
                    }
                }
            }
        }

        foreach ($adminControllersNav as $group) {

            if (!in_array($group->label, $this->adminControllersNavSticky)) {
                $middle[] = $group;
            }
        }

        /**
         * Sort everything alphabetically, then loop through the user's prefs and sort
         * by their preferences. If any modules are left over they'll appear at the end,
         * in alphabetical order. Also, set the open state of the module.
         */

        //  Sort alphabetically
        arraySortMulti($middle, 'label');

        //  Get user's prefs
        $oAdminModel = Factory::model('Admin', 'nails/module-admin');
        $userNavPref = $oAdminModel->getAdminData('nav_state');

        if (!empty($userNavPref)) {

            $temp = [];

            foreach ($userNavPref as $groupMd5 => $state) {
                for ($i = 0; $i < count($middle); $i++) {

                    if (empty($middle[$i])) {
                        continue;
                    }

                    if ($groupMd5 == md5($middle[$i]->label)) {
                        if (!in_array($middle[$i]->label, $this->adminControllersNavSticky)) {
                            $temp[]     = $middle[$i];
                            $middle[$i] = null;
                        }
                    }
                }
            }

            //  Filter out the blanks
            $middle = array_filter($middle);
            $middle = array_values($middle);

            //  Merge
            $middle = array_merge($temp, $middle);
        }

        //  Save to the class
        $this->adminControllersNav = array_merge($stickyTop, $middle, $stickyBottom);

        //  Set the open states of the modules
        if (!empty($userNavPref)) {
            foreach ($userNavPref as $groupMd5 => $state) {
                for ($i = 0; $i < count($this->adminControllersNav); $i++) {
                    if ($groupMd5 == md5($this->adminControllersNav[$i]->label)) {
                        $this->adminControllersNav[$i]->open = $state->open;
                    }
                }
            }
        }

        /**
         * Finally, now that everything has been sorted, go through all the groupings
         * and sort their methods alphabetically so there's some feeling of order in
         * amongst all this chaos.
         */

        foreach ($this->adminControllersNav as $grouping) {
            arraySortMulti($grouping->actions, 'order');
        }
    }
public function prepAdminControllersNav()
    {
        $adminControllersNav = [];

        foreach ($this->adminControllers as $module => $moduleDetails) {
            foreach ($moduleDetails->controllers as $controller => $controllerDetails) {
                foreach ($controllerDetails['groupings'] as $grouping) {

                    //  Begin by defining which group this action belongs in
                    $sGroupLabel = $grouping->getLabel();

                    if (!isset($adminControllersNav[md5($sGroupLabel)])) {
                        $adminControllersNav[md5($sGroupLabel)]           = new \stdClass();
                        $adminControllersNav[md5($sGroupLabel)]->label    = $sGroupLabel;
                        $adminControllersNav[md5($sGroupLabel)]->icon     = [];
                        $adminControllersNav[md5($sGroupLabel)]->sortable = true;
                        $adminControllersNav[md5($sGroupLabel)]->open     = false;
                        $adminControllersNav[md5($sGroupLabel)]->actions  = [];
                    }

                    /**
                     * Add the group icon to the icon array. Multiple calls to the same group
                     * will add their own icon, the most common icon will be used. In the event
                     * of a tie then the first icon defined will be used, unless one has been
                     * marked as !important.
                     */

                    $moduleIcon = $grouping->getIcon();

                    if (!empty($moduleIcon)) {

                        $adminControllersNav[md5($sGroupLabel)]->icon[] = $moduleIcon;
                    }

                    //  Group actions
                    $groupActions = $grouping->getActions();

                    foreach ($groupActions as $actionUrl => $actionDetails) {

                        $url = $module . '/' . lcfirst($controller);
                        $url .= empty($actionUrl) ? '' : '/';
                        $url .= $actionUrl;

                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]         = new \stdClass();
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->order  = $actionDetails->order;
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->label  = $actionDetails->label;
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->alerts = $actionDetails->alerts;
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->class  = $controllerDetails['className'];
                        $adminControllersNav[md5($sGroupLabel)]->actions[$url]->path   = $controllerDetails['path'];
                    }
                }
            }
        }

        //  Reset the indexes
        $adminControllersNav = array_values($adminControllersNav);

        //  Remove navGroups with no actions and set as sortable
        $numGroups = count($adminControllersNav);
        for ($i = 0; $i < $numGroups; $i++) {

            //  Remove if empty
            if (empty($adminControllersNav[$i]->actions)) {
                $adminControllersNav[$i] = null;
                continue;
            }

            //  Set sortable
            if (in_array($adminControllersNav[$i]->label, $this->adminControllersNavSticky)) {
                $adminControllersNav[$i]->sortable = false;
            }
        }

        //  Filter and reset the indexes, again
        $adminControllersNav = array_filter($adminControllersNav);
        $adminControllersNav = array_values($adminControllersNav);

        //  Split the groups
        $stickyTop    = [];
        $middle       = [];
        $stickyBottom = [];

        foreach ($this->adminControllersNavSticky as $sticky) {
            foreach ($adminControllersNav as $group) {
                if ($group->label == $sticky) {
                    if (in_array($sticky, $this->adminControllersNavStickyBottom)) {
                        $stickyBottom[] = $group;
                    } else {
                        $stickyTop[] = $group;
                    }
                }
            }
        }

        foreach ($adminControllersNav as $group) {

            if (!in_array($group->label, $this->adminControllersNavSticky)) {
                $middle[] = $group;
            }
        }

        /**
         * Sort everything alphabetically, then loop through the user's prefs and sort
         * by their preferences. If any modules are left over they'll appear at the end,
         * in alphabetical order. Also, set the open state of the module.
         */

        //  Sort alphabetically
        arraySortMulti($middle, 'label');

        //  Get user's prefs
        $oAdminModel = Factory::model('Admin', 'nails/module-admin');
        $userNavPref = $oAdminModel->getAdminData('nav_state');

        if (!empty($userNavPref)) {

            $temp = [];

            foreach ($userNavPref as $groupMd5 => $state) {
                for ($i = 0; $i < count($middle); $i++) {

                    if (empty($middle[$i])) {
                        continue;
                    }

                    if ($groupMd5 == md5($middle[$i]->label)) {
                        if (!in_array($middle[$i]->label, $this->adminControllersNavSticky)) {
                            $temp[]     = $middle[$i];
                            $middle[$i] = null;
                        }
                    }
                }
            }

            //  Filter out the blanks
            $middle = array_filter($middle);
            $middle = array_values($middle);

            //  Merge
            $middle = array_merge($temp, $middle);
        }

        //  Save to the class
        $this->adminControllersNav = array_merge($stickyTop, $middle, $stickyBottom);

        //  Set the open states of the modules
        if (!empty($userNavPref)) {
            foreach ($userNavPref as $groupMd5 => $state) {
                for ($i = 0; $i < count($this->adminControllersNav); $i++) {
                    if ($groupMd5 == md5($this->adminControllersNav[$i]->label)) {
                        $this->adminControllersNav[$i]->open = $state->open;
                    }
                }
            }
        }

        /**
         * Finally, now that everything has been sorted, go through all the groupings
         * and sort their methods alphabetically so there's some feeling of order in
         * amongst all this chaos.
         */

        foreach ($this->adminControllersNav as $grouping) {
            arraySortMulti($grouping->actions, 'order');
        }
    }
Generates a "view friendly" array of the admin controllers, takes into
consideration the user's order and state preferences

@return void