HEX
Server: Apache
System: Linux sg241.singhost.net 2.6.32-896.16.1.lve1.4.51.el6.x86_64 #1 SMP Wed Jan 17 13:19:23 EST 2018 x86_64
User: honghock (909)
PHP: 8.0.30
Disabled: passthru,system,shell_exec,show_source,exec,popen,proc_open
Upload Files
File: //opt/cpanel/ea-php54/root/usr/share/pear/RVSeagullMod/modules/navigation/classes/ArrayDriver.php
<?php

/**
 * @todo remove duplication
 */
if (!defined('SGL_NODE_USER')) {
    define('SGL_NODE_USER',  2); // nested set parent_id
    define('SGL_NODE_ADMIN', 4); // nested set parent_id
    define('SGL_NODE_GROUP', 1);
}

/**
 * Navigation driver, which uses PHP arrays to build navigation.
 *
 * @package seagull
 * @subpackage navigation
 * @author Dmitri Lakachauskis <lakiboy83@gmail.com>
 */
class ArrayDriver
{
    /**
     * Navigation structure.
     *
     * @access private
     *
     * @var array
     */
    var $_aSections = array();

    /**
     * Array of current IDs by root IDs.
     *
     * @access private
     *
     * @var array
     */
    var $_aCurrentIndexes = array();

    /**
     * Index of current root node.
     *
     * @access private
     *
     * @var integer
     */
    var $_currentRootIndex;

    /**
     * Array of current titles by root IDs.
     *
     * @access private
     *
     * @var array
     */
    var $_aCurrentTitles = array();

    /**
     * Params for rendering.
     *
     * @access private
     *
     * @var array
     */
    var $_aParams = array();

    public static function singleton(&$output)
    {
        static $instance;
        if (!isset($instance)) {
            $instance =  new ArrayDriver($output);
            ///fix PHP 5.3
            $instance = &$instance;
        }
        return $instance;
    }

    /**
     * Constructor:
     *   - creates initial array from navigation.php files
     *   - identifies current node
     *   - checks permissions
     *
     * NOTE: only two levels menu supported by now.
     *
     * @access public
     *
     * @param SGL_Output $output
     *
     * @return ArrayDriver
     */
    function ArrayDriver(&$output)
    {
        // get nodes
        if (!($aNodes = $this->_loadCachedNodes())) {
            $aNodes = ArrayDriver::getNavigationStructure();
            ArrayDriver::saveNodes($aNodes);
        }

        // skip admin root if not allowed
        if (empty($output->adminGuiAllowed)) {
            unset($aNodes[SGL_NODE_ADMIN]);

            // set default root index
            // it can be changed with ArrayDriver::setParams()
            $this->_currentRootIndex = SGL_NODE_USER;
        } else {
            $this->_currentRootIndex = SGL_NODE_ADMIN;
        }

        foreach ($aNodes as $rootId => $aSections) {
            if (!isset($this->_aCurrentIndexes[$rootId])) {
                $this->_aCurrentIndexes[$rootId] = 0;
            }
            foreach ($aSections as $sectionId => $section) {
                if (!$this->_nodeAccessAllowed($section)) {
                    unset($aNodes[$rootId][$sectionId]);
                    continue;
                }
                $section['link']       = $this->_makeLinkFromNode($section);
                $section['url']        = $section['link'];
                $section['is_current'] = $this->_isCurrentNode($section);

                if (!empty($section['is_current'])) {
                    $this->_aCurrentTitles[$rootId] = $section['title'];
                    $this->_aCurrentIndexes[$rootId] = $sectionId;
                }

                // save changes made to section
                $aNodes[$rootId][$sectionId] = $section;

                if (!empty($section['sub'])) {
                    foreach ($section['sub'] as $subSectionId => $subSection) {
                        if (!$this->_nodeAccessAllowed($subSection)) {
                            unset($aNodes[$rootId][$sectionId]['sub'][$subSectionId]);
                            continue;
                        }
                        $subSection['link']       = $this->_makeLinkFromNode($subSection);
                        $subSection['url']        = $subSection['link'];
                        $subSection['is_current'] = $this->_isCurrentNode($subSection);

                        if (!empty($subSection['is_current'])) {
                            $this->_aCurrentTitles[$rootId] = $subSection['title'];
                            $this->_aCurrentIndexes[$rootId] = $subSectionId;
                            $aNodes[$rootId][$sectionId]['is_current'] = $subSection['is_current'];
                        }

                        // save changes made to subsection
                        $aNodes[$rootId][$sectionId]['sub'][$subSectionId] = $subSection;
                    }
                }
            }
        }
        $this->_aSections = $aNodes;
    }

    /**
     * Go through all modules and read navigation.php files.
     * Combines all sections in one array ready for use with HTML_Menu.
     *
     * @static
     *
     * @access public
     *
     * @return array
     */
    function getNavigationStructure()
    {
        $aMenu = array();
        $aModules = SGL_Util::getAllModuleDirs(true);
        foreach ($aModules as $dirName) {
            $structureFile = SGL_MOD_DIR . '/' . $dirName . '/data/navigation.php';
            if (!file_exists($structureFile)) {
                continue;
            }
            include $structureFile;
            // skip if no sections were defined
            if (empty($aSections) || !is_array($aSections)) {
                continue;
            }

            $sectionRootId = null;
            foreach ($aSections as $section) {
                // find root ID
                if (empty($sectionRootId) || $section['parent_id'] != SGL_NODE_GROUP) {
                    $sectionRootId = $section['parent_id'];
                    if (empty($aMenu[$sectionRootId])) {
                        $aMenu[$sectionRootId] = array();
                    }
                }

                // simplify node
                $section['manager'] = SGL_Inflector::getSimplifiedNameFromManagerName($section['manager']);
                if (!empty($section['uriType']) && $section['uriType'] == 'dynamic') {
                    unset($section['uriType']);
                }
                if (isset($section['actionMapping'])) {
                    if (!empty($section['actionMapping'])) {
                        $section['action'] = $section['actionMapping'];
                    }
                    unset($section['actionMapping']);
                }
                if (isset($section['add_params'])) {
                    if (!empty($section['add_params'])) {
                        $section['params'] = $section['add_params'];
                    }
                    unset($section['add_params']);
                }
                if (!empty($section['is_enabled'])) {
                    unset($section['is_enabled']);
                }
                if (isset($section['perms']) && $section['perms'] == SGL_ANY_ROLE) {
                    unset($section['perms']);
                }

                $parentId = $section['parent_id'];
                unset($section['parent_id']);

                // create first level item
                if ($parentId != SGL_NODE_GROUP) {
                    $nextId = $currentIndex = $currentNodeId = $parentId * 10 + count($aMenu[$sectionRootId]) + 1;
                    $aMenu[$sectionRootId][$nextId] = $section;

                // create second level item
                } else {
                    $subNav = &$aMenu[$sectionRootId][$currentNodeId]['sub'];
                    if (empty($subNav)) {
                        $subNav = array();
                    }
                    $currentIndex = $nextId * 10 + count($subNav) + 1;
                    $subNav[$currentIndex] = $section;
                }
            }
        }
        return $aMenu;
    }

    /**
     * Load nodes from cached file.
     *
     * @access private
     *
     * @return array
     */
    function _loadCachedNodes()
    {
        $fileName = SGL_VAR_DIR . '/navigation.php';
        if (file_exists($fileName)) {
            include $fileName;
        }
        return !empty($aSections) && is_array($aSections)
            ? $aSections
            : false;
    }

    /**
     * Cache nodes to file.
     *
     * @access public
     *
     * @static
     *
     * @param array $aNodes
     *
     * @return boolean
     */
    function saveNodes($aNodes)
    {
        $data = var_export($aNodes, true);
        $data = "<?php\n\$aSections = $data;\n?>";
        $ok = file_put_contents(SGL_VAR_DIR . '/navigation.php', $data);
        return $ok;
    }

    /**
     * Check node permission by current role.
     *
     * @access private
     *
     * @param array $aNode
     *
     * @return boolean
     */
    function _nodeAccessAllowed($aNode)
    {
        static $rid;
        if (is_null($rid)) {
            $rid = SGL_Session::getRoleId();
        }
        $ret = false;
        if (!isset($aNode['is_enabled']) || !empty($aNode['is_enabled'])) {
            if (!empty($aNode['perms'])) {
                $aPerms = explode(',', $aNode['perms']);
                foreach ($aPerms as $permId) {
                    $permValue = SGL_String::pseudoConstantToInt($permId);
                    if ($permValue == $rid || $permValue == SGL_ANY_ROLE) {
                        $ret = true;
                        break;
                    }
                }
            } else {
                $ret = true;
            }
        }
        return $ret;
    }

    /**
     * Check if supplied node is current.
     *
     * @access private
     *
     * @param array $aNode
     *
     * @return boolean
     */
    function _isCurrentNode($aNode)
    {
        $req = SGL_Request::singleton();
        $ret = false;

        // compare node's module and manager with current
        if ($req->getModuleName() == $aNode['module']
                && $req->getManagerName() == $aNode['manager']) {
            // compare node's action with current
            if (!empty($aNode['action'])) {
                $ret = $req->getActionName() == $aNode['action'];
            } else {
                $ret = $req->getActionName() == 'default';
            }
            // compare node's params with current
            if (!empty($aNode['params'])) {
                $ret     = true; // by default params match
                $aParams = explode('/', $aNode['params']);
                for ($i = 0, $cnt = count($aParams); $i < $cnt; $i = $i + 2) {
                    $k = $aParams[$i];
                    $v = isset($aParams[$i + 1]) ? $aParams[$i + 1] : null;
                    if ($req->get($k) != $v) {
                        $ret = false;
                        break;
                    }
                }
            }
        }
        return $ret;
    }

    /**
     * Create URL from supplied node.
     *
     * @access private
     *
     * @param array $aNode
     *
     * @return string
     *
     * @todo check for URI type
     */
    function _makeLinkFromNode($aNode)
    {
        $action = !empty($aNode['action']) ? $aNode['action'] : '';
        $params = '';
        if (!empty($aNode['params'])) {
            $aVars = explode('/', $aNode['params']);
            for ($i = 0, $cnt = count($aVars); $i < $cnt; $i += 2) {
                if (isset($aVars[$i + 1])) {
                    if (!empty($params)) {
                        $params .= '||';
                    }
                    $params .= $aVars[$i] . '|' . $aVars[$i + 1];
                }
            }
        }
        return SGL_Output::makeUrl($action,
            $aNode['manager'], $aNode['module'], array(), $params);
    }

    /**
     * Set rendering params.
     *
     * @access public
     *
     * @param mixed $aParams  can be integer or array for BC with old block
     *
     * @return void
     */
    function setParams($aParams)
    {
        if (is_array($aParams)) {
            $this->_aParams = $aParams;
            if (isset($aParams['startParentNode'])) {
                $this->_currentRootIndex = $aParams['startParentNode'];
            }
        } else {
            $this->_currentRootIndex = $aParams;
        }
    }

    /**
     * Render navigation.
     *
     * @access public
     *
     * @param string $renderer  name of renderer
     * @param string $menuType  type of menu
     *
     * @return array or false (if nothing to render)
     *
     * @todo add breadcrumbs to result set
     */
    function render($renderer = 'SimpleRenderer', $menuType = 'tree')
    {
        // nothing to render
        if (empty($this->_aSections[$this->_currentRootIndex])) {
            $ret = false;
        } else {
            $fileNameRenderer = dirname(__FILE__) . '/ArrayDriver/' . $renderer . '.php';
            // check if renderer file exists
            if (!file_exists($fileNameRenderer)) {
                $msg = sprintf('%s: %s renderer not found', __CLASS__, $renderer);
                $ret = SGL::raiseError($msg);
            } else {
                require_once $fileNameRenderer;
                $rendererClassName = 'ArrayDriver_' . $renderer;
                // check if renderer class exists
                if (!class_exists($rendererClassName)) {
                    $msg = sprintf('%s: %s class not found', __CLASS__, $rendererClassName);
                    $ret = SGL::raiseError($msg);
                } else {
                    $currentIdx = $this->_aCurrentIndexes[$this->_currentRootIndex];
                    $aSections  = $this->_aSections[$this->_currentRootIndex];

                    $aParams = $this->_aParams;
                    $aParams['currentIndex'] = $currentIdx;
                    $aParams['menuType']     = $menuType;

                    // render
                    $renderer = new $rendererClassName($aParams);
                    ///fix PHP 5.3
                    $renderer = &$renderer;
                    $html = $renderer->toHtml($aSections);
                    if (!SGL::isError($html)) {
                        $ret = array(
                            0 => $currentIdx,
                            1 => $html,
                            2 => '' // breadcrumbs
                        );
                    } else {
                        $ret = $html;
                    }
                }
            }
        }
        return $ret;
    }

    /**
     * Return current section name.
     *
     * @access public
     *
     * @return string
     */
    function getCurrentSectionName()
    {
        return isset($this->_aCurrentTitles[$this->_currentRootIndex])
            ? $this->_aCurrentTitles[$this->_currentRootIndex]
            : SGL_Config::get('site.name');
    }
}

?>