Your IP : 216.73.216.79


Current Path : /var/www/html/quest5/common/widgets/inspinia/
Upload File :
Current File : /var/www/html/quest5/common/widgets/inspinia/Nav.php

<?php
/**
 * @link http://www.tintsoft.com/
 * @copyright Copyright (c) 2012 TintSoft Technology Co. Ltd.
 * @license http://www.tintsoft.com/license/
 */

namespace common\widgets\inspinia;

use Yii;
use yii\helpers\Url;
use yii\base\Widget;
use yii\helpers\ArrayHelper;
use yii\base\InvalidConfigException;
use yii\helpers\Html;

/**
 * Class Nav
 * @package backend\widgets
 */
class Nav extends Widget
{
    /**
     * @var array the HTML attributes for the widget container tag.
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $options = [
        'class' => 'nav metismenu',
        'id' => 'side-menu',
    ];

    /**
     * @var array list of items in the nav widget. Each array element represents a single
     * menu item which can be either a string or an array with the following structure:
     * - label: string, required, the nav item label.
     * - url: optional, the item's URL. Defaults to "#".
     * - visible: boolean, optional, whether this menu item is visible. Defaults to true.
     * - linkOptions: array, optional, the HTML attributes of the item's link.
     * - options: array, optional, the HTML attributes of the item container (LI).
     * - active: boolean, optional, whether the item should be on active state or not.
     * - items: array|string, optional, the configuration array for creating a [[Dropdown]] widget,
     *   or a string representing the dropdown menu. Note that Bootstrap does not support sub-dropdown menus.
     *   If a menu item is a string, it will be rendered directly without HTML encoding.
     */
    public $items = [];
    /**
     * @var boolean whether the nav items labels should be HTML-encoded.
     */
    public $encodeLabels = true;
    /**
     * @var boolean whether to automatically activate items according to whether their route setting
     * matches the currently requested route.
     * @see isItemActive
     */
    public $activateItems = true;
    /**
     * @var boolean whether to activate parent menu items when one of the corresponding child menu items is active.
     */
    public $activateParents = true;

    /**
     * @var string the template used to render the body of a menu which is a link.
     * In this template, the token `{url}` will be replaced with the corresponding link URL;
     * while `{label}` will be replaced with the link text.
     * This property will be overridden by the `template` option set in individual menu items via [[items]].
     */
    public $linkTemplate = '<a href="{url}">{icon} <span>{label}</span></a>';

    /**
     * @var string the template used to render a list of sub-menus.
     * In this template, the token `{items}` will be replaced with the rendered sub-menu items.
     */
    public $submenuTemplate = "\n<ul class=\"nav nav-second-level collapse\">\n{items}\n</ul>\n";

    /**
     * @var string the template used to render the body of a menu which is NOT a link.
     * In this template, the token `{label}` will be replaced with the label of the menu item.
     * This property will be overridden by the `template` option set in individual menu items via [[items]].
     */
    public $labelTemplate = '{label}';

    /**
     * @var string the route used to determine if a menu item is active or not.
     * If not set, it will use the route of the current request.
     * @see params
     * @see isItemActive
     */
    public $route;
    /**
     * @var array the parameters used to determine if a menu item is active or not.
     * If not set, it will use `$_GET`.
     * @see route
     * @see isItemActive
     */
    public $params;

    /**
     * @var string 头部��
     */
    public $top;

    /**
     * �始化
     */
    public function init()
    {
        parent::init();
        if ($this->route === null && Yii::$app->controller !== null) {
            $this->route = Yii::$app->controller->getRoute();
        }
        if ($this->params === null) {
            $this->params = Yii::$app->request->getQueryParams();
        }
    }

    /**
     * 执行
     */
    public function run()
    {
        $tag = ArrayHelper::remove($options, 'tag', 'ul');
        return Html::tag($tag, $this->top . $this->renderItems($this->items), $this->options);
    }

    /**
     * 渲染所以项目
     * @param $items
     * @return null|string
     * @throws InvalidConfigException
     */
    public function renderItems($items)
    {
        $item['parent'] = "";
        if (is_string($items)) {
            return $items;
        }
        
        if(empty($items)) $items = [];
        
        $lines = [];
        foreach ($items as $item) {
            if (is_string($item)) {
                return $item;
            }
            if (!isset ($item['label'])) {
                throw new InvalidConfigException ("The 'label' option is required.");
            }
            $encodeLabel = isset ($item['encode']) ? $item['encode'] : $this->encodeLabels;

            if (isset($item['parent']) && $item['parent'] == null) {
                // $item['label'] = $encodeLabel ? Html::tag('span', Html::encode($item['label']), ['class' => 'nav-label']) : $item['label'];
            } else {
                // $item['label'] = $encodeLabel ? Html::encode($item['label']) : $item['label'];
            }

            $item['icon'] = isset ($item['icon']) ? Html::tag('i', '', ['class' => 'fa fa-lg fa-fw ' . $item['icon']]) : '';

            $options = ArrayHelper::getValue($item, 'options', []);
            $subItems = ArrayHelper::getValue($item, 'items');
            if (isset ($item['active'])) {
                $active = ArrayHelper::remove($item, 'active', false);
            } else {
                $active = $this->isItemActive($item);
            }
            if ($subItems !== null && is_array($subItems)) {
                if ($this->activateItems) {
                    $subItems = $this->isChildActive($subItems, $active);
                    if ($active) { //如果被激活则父��是打开状�
                        Html::addCssClass($options, 'active');
                    }
                }

                $subItems = $this->renderItems($subItems);
                if($subItems){
                    $submenuTemplate = ArrayHelper::getValue($item, 'submenuTemplate', $this->submenuTemplate);
                    $subItems = strtr($submenuTemplate, [
                        '{items}' => $this->renderItems($subItems),
                    ]);
                }

            }
            if ($this->activateItems && $active) {//无���则激活当���
                Html::addCssClass($options, 'active');
            }
            if (isset ($item['visible']) && !$item['visible']) {
                continue;
            }
            if ($subItems == null) {
                Html::removeCssClass($options, 'open');
            }
            $menu = $this->renderItem($item);
            $lines[] = Html::tag('li', $menu . $subItems, $options);
        }
        if (empty($lines)) {
            return null;
        }
        return implode("\n", $lines);
    }

    /**
     * Renders the content of a menu item.
     * Note that the container and the sub-menus are not rendered here.
     * @param array $item the menu item to be rendered. Please refer to [[items]] to see what data might be in the item.
     * @return string the rendering result
     */
    protected function renderItem($item)
    {
        /* fix undifined parent */
        $item['parent'] = "";

        if ($item['parent'] == null && isset($item['items'])) {//如果是顶级��并且有���
            $linkTemplate = '<a href="{url}">{icon}<span> {label} </span><span class="fa arrow"></span></a>';
        } else {
            $linkTemplate = $this->linkTemplate;
        }
        if (isset($item['url'])) {
            $template = ArrayHelper::getValue($item, 'template', $linkTemplate);

            return strtr($template, [
                '{icon}' => $item['icon'],
                '{url}' => Html::encode(Url::to($item['url'])),
                '{label}' => $item['label'],
            ]);
        } else {
            $template = ArrayHelper::getValue($item, 'template', $this->labelTemplate);

            return strtr($template, [
                '{label}' => $item['label'],
            ]);
        }
    }

    /**
     * @param array $items @see items 
     * @param boolean $active should the parent be active too
     * @return array @see items
     */
    protected function isChildActive($items, &$active)
    {
        foreach ($items as $i => $child) {
            if (ArrayHelper::remove($items[$i], 'active', false) || $this->isItemActive($child)) {
                Html::addCssClass($items[$i]['options'], 'active');
                if ($this->activateParents) {
                    $active = true;
                }
            }
            if (isset($child['items']) && is_array($child['items'])) {
                $child['items'] = $this->isChildActive($child['items'], $active);
            }
        }
        return $items;
    }

    /**
     * This is done by checking if [[route]] and [[params]] match that specified in the `url` option of the menu item.
     * When the `url` option of a menu item is specified in terms of an array, its first element is treated
     * as the route for the item and the rest of the elements are the associated parameters.
     * Only when its route and parameters match [[route]] and [[params]], respectively, will a menu item
     * be considered active.
     *
     * @param array $item the menu item to be checked
     * @return boolean whether the menu item is active
     */
    protected function isItemActive($item)
    {
        if (isset ($item['url']) && is_array($item['url']) && isset ($item['url'][0])) {
            $route = $item['url'][0];
            if ($route[0] !== '/' && Yii::$app->controller) {
                $route = Yii::$app->controller->module->getUniqueId() . '/' . $route;
            }
            if (ltrim($route, '/') !== $this->route) {
                return false;
            }
            unset ($item['url']['#']);
            if (count($item['url']) > 1) {
                foreach (array_splice($item['url'], 1) as $name => $value) {
                    if ($value !== null && (!isset ($this->params[$name]) || $this->params[$name] != $value)) {
                        return false;
                    }
                }
            }
            return true;
        }
        return false;
    }
}