<commit_before><?php

namespace mii\web;

use mii\util\URL;

class Menu
{

    const CURRENT_ITEM = 1;
    const ACTIVE_ITEM = 2;

    /**
     * @var array Array of list items
     *
     * [[
     *      'name' => 'Menu item name',
     *      'url' => 'item url',
     *      'current' => bool (current flag)
     *      'active' => bool (active flag)
     * ], ...]
     *
     */
    public $items = [];

    protected $_current_item;

    protected $_current_uri;

    protected $_block_name;

    /**
     * Current element may be:
     *  string URI
     *  array with 'url' key
     *  object with 'url' method
     *
     * @param string|array|object $current
     * @param string $block_name
     * @param array $params
     */

    public function __construct($items = null, $block_name = null, $current = null)
    {
        $this->_current_uri = trim(URL::site(\Mii::$app->request->uri()), '/');

        if ($items) {
            $this->items = $items;
        }

        if($block_name) {
            $this->_block_name = $block_name;
        }

        $this->process();
    }

    public function process() {

    }

    public function current_item($current = null)
    {

        if ($current === null) {

            return $this->_current_item;

        } elseif (is_object($current)) {

            $this->_current_item = $current->url();

        } elseif (is_array($current)) {

            $this->_current_item = $current['url'];

        } else {

            $this->_current_item = $current;
        }
    }


    /**
     * Return Array with menu structure
     *
     * @return  Array  menu structure
     */
    public function as_array()
    {
        $menu = [];
        foreach($this->items as $item) {

            $active = $this->active($item['url']);

            $children = isset($item['children'])
                ? $children = (new Menu($item['children']))->as_array()
                : [];

            $menu[] = array( 'name'    => $item['name'],
                             'url'     => $item['url'],
                             'children'=> $children,
                             'active'  => ($active === Menu::ACTIVE_ITEM),
                             'current' => ($active === Menu::CURRENT_ITEM));
        }
        return $menu;
    }


    public function render($block_name = null)
    {
        if ($block_name) {
            $this->_block_name = $block_name;
        }

        return block($this->_block_name)->set('list', $this->as_array())->render();
    }


    public function __toString()
    {
        try {
            return $this->render();
        } catch (\Exception $e) {

            /**
             * Display the exception message.
             *
             * We use this method here because it's impossible to throw and
             * exception from __toString().
             */<commit_msg>Возможность сохранять/получать произвольные данные в Menu<commit_after><?php

namespace mii\web;

use mii\util\URL;

class Menu
{

    const CURRENT_ITEM = 1;
    const ACTIVE_ITEM = 2;

    /**
     * @var array Array of list items
     *
     * [[
     *      'name' => 'Menu item name',
     *      'url' => 'item url',
     *      'current' => bool (current flag)
     *      'active' => bool (active flag)
     * ], ...]
     *
     */
    public $items = [];


    protected $_data = [];

    protected $_current_item;

    protected $_current_uri;

    protected $_block_name;


    /**
     * Current element may be:
     *  string URI
     *  array with 'url' key
     *  object with 'url' method
     *
     * @param string|array|object $current
     * @param string $block_name
     * @param array $params
     */

    public function __construct($items = null, $block_name = null, $current = null)
    {
        $this->_current_uri = trim(URL::site(\Mii::$app->request->uri()), '/');

        if ($items) {
            $this->items = $items;
        }

        if($block_name) {
            $this->_block_name = $block_name;
        }

        $this->process();
    }

    public function process() {

    }

    public function current_item($current = null)
    {

        if ($current === null) {

            return $this->_current_item;

        } elseif (is_object($current)) {

            $this->_current_item = $current->url();

        } elseif (is_array($current)) {

            $this->_current_item = $current['url'];

        } else {

            $this->_current_item = $current;
        }
    }


    /**
     * Return Array with menu structure
     *
     * @return  Array  menu structure
     */
    public function as_array()
    {
        $menu = [];
        foreach($this->items as $item) {

            $active = $this->active($item['url']);

            $children = isset($item['children'])
                ? $children = (new Menu($item['children']))->as_array()
                : [];

            $menu[] = array( 'name'    => $item['name'],
                             'url'     => $item['url'],
                             'children'=> $children,
                             'active'  => ($active === Menu::ACTIVE_ITEM),
                             'current' => ($active === Menu::CURRENT_ITEM));
        }
        return $menu;
    }

    public function get($key, $default = NULL)
    {

        if (array_key_exists($key, $this->_data)) {
            return $this->_data[$key];
        } else {
            if ($default !== NULL)
                return $default;

            throw new Exception('Menu variable is not set: :var',
                [':var' => $key]);
        }
    }

    public function set($key, $value = NULL)
    {
        if (is_array($key)) {
            foreach ($key as $name => $value) {
                $this->_data[$name] = $value;
            }
        } else {
            $this->_data[$key] = $value;
        }

        return $this;
    }


    public function render($block_name = null)
    {
        if ($block_name) {
            $this->_block_name = $block_name;
        }

        return block($this->_block_name)
                ->set('list', $this->as_array())
                ->render();
    }


    public function __toString()
    {
        try {
            return $this->render();
        } catch (\Exception $e) {

            /**
             * Display the exception message.
             *
             * We use this method here because it's impossible to throw and
             * exception from __toString().
             */
{'fraction_non_alphanumeric': 0.14779389077445232, 'fraction_numerical': 0.000617093489663684, 'mean_word_length': 1.5176699029126213, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '573336', 'n_tokens_mistral': 1897, 'n_tokens_neox': 1823, 'n_words': 420}