<?php namespace alct\noapi;

class Twitter
{
    /**
     * Add HTML markup around @mentions, #hashtags and URLs ; convert \n to
.
     *
     * @param string $string
     *
     * @return string
     */
    protected function html($string)
    {
        $pattern = [
            '~(https?://(?:w{3}\d*\.)?([^\s]+))~i' => '$2',
            '~(?<=[^\w]|^)@(\w+)(?=[^\w]|$)~i' => '@$1',
            '~(?<=[^\w]|^)#(\w+)(?=[^\w]|$)~iu' => '#$1',
            '~\n~' => '
',
        ];

        return preg_replace(array_keys($pattern), array_values($pattern), $string);
    }

    /**
     * Clean Twitter specific text quirks.
     *
     * @param string $string
     *
     * @return string
     */
    protected function clean($string)
    {
        $pattern = [
            '~pic\.twitter\.com~iU'    => 'https://pic.twitter.com',
            '~\xc2\xa0~'               => ' ',   // replace non breaking spaces by simple ones
            '~(?<!^)(https?://)~'      => ' $1', // make sure every URL is preceeded by a whitespace
            '~\s{2,}~U'                => ' ',   // replace consecutive spaces by a single one
            '~(https?://[^\s]+) ?…~iU' => '$1',  // remove elipsis after URLs
        ];

        return preg_replace(array_keys($pattern), array_values($pattern), $string);
    }

    /**
     * Extract a series of information from a twitter page.
     *
     * @see doc/Twitter.md for the detailed structure of the returned array
     * @see Twitter::queryToMeta() for details about the $meta array
     *
     * @param string $page content of a twitter page
     * @param array  $meta
     *
     * @return array|bool false on error
     */
    protected function parse($page, $meta)
    {
        $twitter['meta'] = $meta;

        $tweet = '//ol[@id="stream-items-id"]/li[@data-item-type="tweet"]';

        // foo_bar will be converted to foo['bar']
        $tweet_details = [
            'user_avatar'   => './/img[contains(@class, "avatar")]/@src',
            'user_fullname' => './/@data-name',
            'user_name'     => './/@data-screen-name',
            'stats_fav'     => './/span[contains(@class, "ProfileTweet-action--favorite")]//@data-tweet-stat-count',
            'stats_rt'      => './/span[contains(@class, "ProfileTweet-action--retweet")]//@data-tweet-stat-count',
            'id'            => './/@data-tweet-id',
            'retweetid'     => './/@data-retweet-id',
            'text'          => './/p[contains(@class, "tweet-text")]',
            'datetime'      => './/@data-time',
        ];

        $user_stats = '//ul[contains(@class, "ProfileNav-list")]';

        $user_stats_details = [
            'followers' => './/li[contains(@class, "ProfileNav-item--followers")]/a/@title',
            'following' => './/li[contains(@class, "ProfileNav-item--following")]/a/@title',
            'likes'     => './/li[contains(@class, "ProfileNav-item--favorites")]/a/@title',
            'lists'     => './/li[contains(@class, "ProfileNav-item--lists")]/a/@title',
            'tweets'    => './/li[contains(@class, "ProfileNav-item--tweets")]/a/@title',
        ];

        libxml_use_internal_errors(true);

        $dom = new \DOMDocument;
        $dom->preserveWhiteSpace = false;
        $dom->loadHTML($page);

        $xpath = new \DomXpath($dom);

        foreach ($xpath->query($tweet) as $item) {

            foreach ($tweet_details as $key => $query) {

                $value = @$xpath->query($query, $item)->item(0)->textContent;

                if ($key == 'retweetid') {

                    $details['retweet'] = empty($value) ? 0 : 1;

                    continue;
                }

                if ($key == 'text') {

                    $value = $this->clean($value);
                    $value = htmlspecialchars($value, ENT_NOQUOTES);

                    $details['text']['raw'] = $value;
                    $details['text']['html'] = $this->html($value);

                    $details['reply'] = substr($value, 0, 1) === '@' ? 1 : 0;

                    continue;
                }

                if ($key == 'datetime') $value = date('c', $value);

                if (strpos($key, '_') !== false) {

                    $subarray = explode('_', $key);
                    $subname  = $subarray[0];
                    $subkey   = $subarray[1];

                    $details[$subname][$subkey] = $value;

                } else {

                    $details[$key] = $value;
                }
            }

            $details['user']['url'] = 'https://twitter.com/' . $details['user']['name'];
            $details['url'] = $details['user']['url'] . '/status/' . $details['id'];

            // type casting
            $details['id'] = (int) $details['id'];
            $details['stats']['fav'] = (int) $details['stats']['fav'];
            $details['stats']['rt']  = (int) $details['stats']['rt'];

            ksort($details);

            $twitter['tweets'][] = $details;
        }

        $twitter['tweets_count'] = count($twitter['tweets']);

        if ($meta['type'] == 'user') {

            $item = $xpath->query($user_stats)->item(0);

            foreach ($user_stats_details as $key => $query) {

                $value = @$xpath->query($query, $item)->item(0)->textContent;

                $twitter['user_stats'][$key] = preg_match('~([\d,]+)~', $value, $matches) ? (int) strtr($matches[1], [',' => '']) : 0;
            }
        }

        ksort($twitter);

        return $twitter;
    }

    /**
     * Convert a query to an associative array of metadata.
     *
     * @see doc/Twitter.md
     *
     * @param string $query
     *
     * @return array with the following structure:
     *     (array)
     *         type  (string) hashtag, search or user
     *         url   (string) URL of the target page
     *         query (string)
     */
    protected function queryToMeta($query)
    {
        $query = str_replace(' ', '+', $query);

        if (preg_match('~^(?:hashtag:|#)(\w+)$~i', $query, $matches)) {

            $type = 'hashtag';
            $url  = 'https://twitter.com/hashtag/' . $matches[1] . '?f=tweets';

        } elseif (preg_match('~^(?:user:|@)(\w+)$~i', $query, $matches)) {

            $type = 'user';
            $url  = 'https://twitter.com/' . $matches[1];

        } elseif (preg_match('~^(?:search:)(.+)$~i', $query, $matches)) {

            $type = 'search';
            $url  = 'https://twitter.com/search?f=tweets&q=' . $matches[1];

        } else {

            $type = 'search';
            $url  = 'https://twitter.com/search?f=tweets&q=' . $query;
        }

        return [ 'query' => $query, 'type' => $type, 'url' => $url ];
    }

    /**
     * Download and parse the twitter page corresponding to a query.
     *
     * @see doc/Twitter.md
     * @see Twitter::queryToMeta()
     *
     * @param string $query
     *
     * @return array|bool false on error
     */
    public function twitter($query)
    {
        $meta = $this->queryToMeta($query);

        if (! $page = NoAPI::curl($meta['url'])) return false;

        return $this->parse($page, $meta);
    }
}


<?php
/**
 * This file is part of the Maths package.
 *
 * Copyright (c) 2014-2016 Pierre Cassat <me@e-piwi.fr> and contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The source code of this package is available online at
 * <http://github.com/atelierspierrot/maths>.
 */

namespace Maths\Geometry;

use \Maths\Maths;
use \Maths\Geometry\Circle;
use \Maths\PointInterface;

/**
 * Class Disc
 *
 * @author  piwi <me@e-piwi.fr>
 */
class Disc
    extends Circle
{

    /**
     * @return  string
     */
    public function __toString()
    {
        return '[disc O'
            .Maths::coordinatesToString(array($this->getPointO()->getAbscissa(), $this->getPointO()->getOrdinate()))
            .',r='.$this->getRadius().']';
    }

// Characteristics

    /**
     * @return  float
     */
    public function getArea()
    {
        return (pi() * ($this->getRadius() * $this->getRadius()));
    }

// Utilities

    /**
     * Test if a point is on the external circle of the disc
     *
     * @param   \Maths\PointInterface   $a
     * @return  bool
     */
    public function isValidCirclePoint(PointInterface $a)
    {
        return (bool) parent::isValidPoint($a);
    }

    /**
     * Test if a point is part of the disc ([O->a] <= r)
     *
     * @param   \Maths\PointInterface   $a
     * @return  bool
     */
    public function isValidPoint(PointInterface $a)
    {
        $s = new Segment($this->getPointO(), $a);
        return (bool) ($s->getLength() <= $this->getRadius());
    }
}


<?php

namespace QCharts\CoreBundle\DependencyInjection;

use QCharts\CoreBundle\DependencyInjection\Defaults\DefaultsFactory;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
 * This is the class that validates and merges configuration from your app/config files
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
 */
class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('qcharts');

        $defaultCharts = DefaultsFactory::getValues("charts");
        $defaultUrls = DefaultsFactory::getValues("urls");
        $defaultPaths = DefaultsFactory::getValues("paths");

        $rootNode
            ->treatNullLike($defaultPaths)
            ->children()
                ->arrayNode('paths')
                ->info("Paths used by QCharts")
                ->treatNullLike($defaultPaths["paths"])
                    ->children()
                        ->scalarNode('snapshots')
                            ->defaultValue($defaultPaths["paths"]["snapshots"])
                            ->info('Absolute path to locate the queries snapshots')
                        ->end()
                    ->end()
                ->end()
                ->arrayNode('urls')
                ->info('URLs to use when redirects are needed, login redirect for example')
                ->treatNullLike($defaultUrls)
                    ->children()
                        ->arrayNode('redirects')
                            ->info('key: value, array syntax')
                            ->treatNullLike($defaultUrls["redirects"])
                                ->prototype('variable')
                                ->end()
                            ->defaultValue($defaultUrls["redirects"])
                        ->end()
                    ->end()
                ->end()
                ->arrayNode('roles')
                    ->info('Required, Roles used for the authorization, role hierarchy is up to your implementation.')
                    ->children()
                        ->scalarNode('user')
                            ->info('User that can see results')
                        ->end()
                        ->scalarNode('admin')
                            ->info('User that can add/edit/delete queries')
                        ->end()
                        ->scalarNode('super_admin')
                            ->info('User that manages the users ans snapshots console')
                        ->end()
                    ->end()
                ->end()
                ->arrayNode('charts')
                    ->info('RECOMMENDED, The type of charts supported, format = [key]: [value to display]')
                    ->treatNullLike($defaultCharts)
                    ->prototype('variable')
                    ->end()
                    ->defaultValue($defaultCharts)
                ->end()
                ->arrayNode('limits')
                    ->info('The limits of the query execution')
                    ->children()
                        ->floatNode('time')
                            ->info('REQUIRED, The limit time a query execution has in seconds!')
                        ->end()
                        ->integerNode('row')
                            ->info('REQUIRED, Limiting the numbers of rows from the results')
                        ->end()
                    ->end()
                ->end()
                ->booleanNode('allow_demo_users')
                    ->defaultFalse()
                    ->info('Allow access to anonymous visitors to access the application')
                ->end()
            ->end()
        ;

        return $treeBuilder;
    }
}


<?php

namespace Reaction\Widgets\Bootstrap;

use Reaction\Assets\BootstrapPluginAsset;
use Reaction\Helpers\Html;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Helpers\ArrayHelper;
use Reaction\Base\JsExpression;

/**
 * Tabs renders a Tab bootstrap javascript component.
 *
 * For example:
 *
 * ```php
 * echo Tabs::widget([
 *     'items' => [
 *         [
 *             'label' => 'One',
 *             'content' => 'Anim pariatur cliche...',
 *             'active' => true
 *         ],
 *         [
 *             'label' => 'Two',
 *             'content' => 'Anim pariatur cliche...',
 *             'headerOptions' => [...],
 *             'options' => ['id' => 'myveryownID'],
 *         ],
 *         [
 *             'label' => 'Example',
 *             'url' => 'http://www.example.com',
 *         ],
 *         [
 *             'label' => 'Dropdown',
 *             'items' => [
 *                  [
 *                      'label' => 'DropdownA',
 *                      'content' => 'DropdownA, Anim pariatur cliche...',
 *                  ],
 *                  [
 *                      'label' => 'DropdownB',
 *                      'content' => 'DropdownB, Anim pariatur cliche...',
 *                  ],
 *                  [
 *                      'label' => 'External Link',
 *                      'url' => 'http://www.example.com',
 *                  ],
 *             ],
 *         ],
 *     ],
 * ]);
 * ```
 */
class Tabs extends Widget
{
    /**
     * @var array list of tabs in the tabs widget. Each array element represents a single
     * tab with the following structure:
     *
     * - label: string, required, the tab header label.
     * - encode: boolean, optional, whether this label should be HTML-encoded. This param will override
     *   global `$this->encodeLabels` param.
     * - headerOptions: array, optional, the HTML attributes of the tab header.
     * - linkOptions: array, optional, the HTML attributes of the tab header link tags.
     * - content: string, optional, the content (HTML) of the tab pane.
     * - url: string, optional, an external URL. When this is specified, clicking on this tab will bring
     *   the browser to this URL. This option is available since version 2.0.4.
     * - options: array, optional, the HTML attributes of the tab pane container.
     * - active: boolean, optional, whether this item tab header and pane should be active. If no item is marked as
     *   'active' explicitly - the first one will be activated.
     * - visible: boolean, optional, whether the item tab header and pane should be visible or not. Defaults to true.
     * - items: array, optional, can be used instead of `content` to specify a dropdown items
     *   configuration array. Each item can hold three extra keys, besides the above ones:
     *     * active: boolean, optional, whether the item tab header and pane should be visible or not.
     *     * content: string, required if `items` is not set. The content (HTML) of the tab pane.
     *     * contentOptions: optional, array, the HTML attributes of the tab content container.
     */
    public $items = [];
    /**
     * @var array list of HTML attributes for the item container tags. This will be overwritten
     * by the "options" set in individual [[items]]. The following special options are recognized:
     *
     * - tag: string, defaults to "div", the tag name of the item container tags.
     *
     * @see \Reaction\Helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $itemOptions = [];
    /**
     * @var array list of HTML attributes for the header container tags. This will be overwritten
     * by the "headerOptions" set in individual [[items]].
     * @see \Reaction\Helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $headerOptions = [];
    /**
     * @var array list of HTML attributes for the tab header link tags. This will be overwritten
     * by the "linkOptions" set in individual [[items]].
     * @see \Reaction\Helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $linkOptions = [];
    /**
     * @var boolean whether the labels for header items should be HTML-encoded.
     */
    public $encodeLabels = true;
    /**
     * @var string specifies the Bootstrap tab styling.
     */
    public $navType = 'nav-tabs';
    /**
     * @var boolean whether to render the `tab-content` container and its content. You may set this property
     * to be false so that you can manually render `tab-content` yourself in case your tab contents are complex.
     */
    public $renderTabContent = true;
    /**
     * @var array list of HTML attributes for the `tab-content` container. This will always contain the CSS class `tab-content`.
     * @see \Reaction\Helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $tabContentOptions = [];
    /**
     * @var string name of a class to use for rendering dropdowns withing this widget. Defaults to [[Dropdown]].
     */
    public $dropdownClass = 'Reaction\Widgets\Bootstrap\Dropdown';

    /**
     * @var bool
     */
    protected $hasDropDown = false;

    /**
     * Initializes the widget.
     */
    public function init()
    {
        parent::init();
        $this->options['role'] = 'tablist';
        Html::addCssClass($this->options, ['widget' => 'nav', $this->navType]);
        Html::addCssClass($this->tabContentOptions, 'tab-content');
        Html::addCssClass($this->headerOptions, 'nav-item');
        Html::addCssClass($this->linkOptions, 'nav-link');
    }

    /**
     * Renders the widget.
     */
    public function run()
    {
        $items = $this->renderItems();
        $this->registerPlugin('tab');
        return $items;
    }

    /**
     * Renders tab items as specified on [[items]].
     * @return string the rendering result.
     * @throws InvalidConfigException.
     */
    protected function renderItems()
    {
        $headers = [];
        $panes = [];

        if (!$this->hasActiveTab()) {
            $this->activateFirstVisibleTab();
        }

        foreach ($this->items as $n => $item) {
            if (!ArrayHelper::remove($item, 'visible', true)) {
                continue;
            }
            if (!array_key_exists('label', $item)) {
                throw new InvalidConfigException("The 'label' option is required.");
            }
            $encodeLabel = isset($item['encode']) ? $item['encode'] : $this->encodeLabels;
            $label = $encodeLabel ? $this->htmlHlp->encode($item['label']) : $item['label'];
            $headerOptions = array_merge($this->headerOptions, ArrayHelper::getValue($item, 'headerOptions', []));
            $linkOptions = array_merge($this->linkOptions, ArrayHelper::getValue($item, 'linkOptions', []));

            if (isset($item['items'])) {
                Html::addCssClass($linkOptions, ['widget' => 'dropdown-toggle']);

                if ($this->renderDropdown($n, $item['items'], $panes)) {
                    Html::addCssClass($linkOptions, 'active');
                }

                Html::addCssClass($linkOptions, ['widget' => 'dropdown-toggle']);
                if (!isset($linkOptions['data-toggle'])) {
                    $linkOptions['data-toggle'] = 'dropdown';
                }

                /** @var Widget $dropdownClass */
                $dropdownClass = $this->dropdownClass;
                $header = $this->htmlHlp->a($label, "#", $linkOptions) . "\n"
                    . $dropdownClass::widget([
                        'app' => $this->app,
                        'items' => $item['items'],
                        'clientOptions' => false,
                        'view' => $this->getView(),
                    ]);
                $this->hasDropDown = true;
            } else {
                $options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', []));
                $options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-tab' . $n);

                Html::addCssClass($options, ['widget' => 'tab-pane']);
                if (ArrayHelper::remove($item, 'active')) {
                    Html::addCssClass($options, 'active show');
                    Html::addCssClass($linkOptions, 'active');
                }

                if (isset($item['url'])) {
                    $header = $this->htmlHlp->a($label, $item['url'], $linkOptions);
                } else {
                    if (!isset($linkOptions['data-toggle'])) {
                        $linkOptions['data-toggle'] = 'tab';
                    }
                    $header = $this->htmlHlp->a($label, '#' . $options['id'], $linkOptions);
                }

                if ($this->renderTabContent) {
                    $tag = ArrayHelper::remove($options, 'tag', 'div');
                    $panes[] = $this->htmlHlp->tag($tag, isset($item['content']) ? $item['content'] : '', $options);
                }
            }

            $headers[] = $this->htmlHlp->tag('li', $header, $headerOptions);
        }

        return $this->renderNavTabs($headers, $this->options)
            . $this->renderPanes($panes);
    }

    /**
     * @return bool if there's active tab defined
     */
    protected function hasActiveTab()
    {
        foreach ($this->items as $item) {
            if (isset($item['active']) && $item['active'] === true) {
                return true;
            }
        }

        return false;
    }

    /**
     * Sets the first visible tab as active.
     *
     * This method activates the first tab that is visible and
     * not explicitly set to inactive (`'active' => false`).
     */
    protected function activateFirstVisibleTab()
    {
        foreach ($this->items as $i => $item) {
            $active = ArrayHelper::getValue($item, 'active', null);
            $visible = ArrayHelper::getValue($item, 'visible', true);
            if ($visible && $active !== false) {
                $this->items[$i]['active'] = true;
                return;
            }
        }
    }

    /**
     * Normalizes dropdown item options by removing tab specific keys `content` and `contentOptions`, and also
     * configure `panes` accordingly.
     * @param string $itemNumber number of the item
     * @param array $items the dropdown items configuration.
     * @param array $panes the panes reference array.
     * @return bool whether any of the dropdown items is `active` or not.
     * @throws InvalidConfigException
     */
    protected function renderDropdown($itemNumber, &$items, &$panes)
    {
        $itemActive = false;

        foreach ($items as $n => &$item) {
            if (is_string($item)) {
                continue;
            }
            if (isset($item['visible']) && !$item['visible']) {
                continue;
            }
            if (!(array_key_exists('content', $item) xor array_key_exists('url', $item))) {
                throw new InvalidConfigException("Either the 'content' or the 'url' option is required, but only one can be set.");
            }
            if (array_key_exists('url', $item)) {
                continue;
            }

            $content = ArrayHelper::remove($item, 'content');
            $options = ArrayHelper::remove($item, 'contentOptions', []);
            Html::addCssClass($options, ['widget' => 'tab-pane']);
            if (ArrayHelper::remove($item, 'active')) {
                Html::addCssClass($options, 'active');
                Html::addCssClass($item['options'], 'active');
                $itemActive = true;
            }

            $options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-dd' . $itemNumber . '-tab' . $n);
            $item['url'] = '#' . $options['id'];
            if (!isset($item['linkOptions']['data-toggle'])) {
                $item['linkOptions']['data-toggle'] = 'tab';
            }
            $panes[] = $this->htmlHlp->tag('div', $content, $options);

            unset($item);
        }

        return $itemActive;
    }

    /**
     * Renders tab panes.
     *
     * @param array $panes
     * @return string the rendering result.
     */
    public function renderPanes($panes)
    {
        return $this->renderTabContent ? "\n" . $this->htmlHlp->tag('div', implode("\n", $panes), $this->tabContentOptions) : '';
    }

    /**
     * Render nav tabs
     * @param array $items
     * @param array $options
     * @return string
     */
    protected function renderNavTabs($items = [], $options = []) {
        return Nav::widget([
            'app' => $this->app,
            'items' => $items,
            'options' => $options,
        ]);
    }

    /**
     * Registers a specific Bootstrap plugin and the related events
     * @param string $name the name of the Bootstrap plugin
     */
    protected function registerPlugin($name)
    {
        $view = $this->getView();

        BootstrapPluginAsset::register($view);

        if ($this->hasDropDown && !isset($this->clientEvents['shown.bs.tab'])) {
            //FIX dropdown links
            $this->clientEvents['shown.bs.tab'] = ['a', new JsExpression("function(e) {
            var btn = $(this), nav = btn.parents('.nav:first'), dropDown = btn.parents('.dropdown-menu:first');
                btn.parents('.nav:first').find('[data-toggle=\"tab\"]').not(btn).removeClass('active');
                if(dropDown.length) {
                    dropDown.siblings('.dropdown-toggle').addClass('active');
                }
            }")];
        }

        $this->registerClientEvents();
    }

    /**
     * Registers JS event handlers that are listed in [[clientEvents]].
     */
    protected function registerClientEvents()
    {
        if (!empty($this->clientEvents)) {
            $id = $this->options['id'];
            $js = [];
            foreach ($this->clientEvents as $event => $handler) {
                if (is_array($handler) && count($handler) === 2) {
                    $subSelector = $handler[0];
                    $handlerCallback = $handler[1];
                    $js[] = "jQuery('#$id').on('$event', '$subSelector', $handlerCallback);";
                } else {
                    $js[] = "jQuery('#$id').on('$event', $handler);";
                }
            }
            $this->getView()->registerJs(implode("\n", $js));
        }
    }
}


<?php

/*
 * This file is part of the Dektrium project.
 *
 * (c) Dektrium project <http://github.com/dektrium/>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace jarrus90\User\models;

use jarrus90\User\traits\ModuleTrait;
use Yii;
use yii\base\Model;

/**
 * Registration form collects user input on registration process, validates it and creates new User model.
 *
 * @author Dmitry Erofeev <dmeroff@gmail.com>
 */
class RegistrationForm extends Model {

    use ModuleTrait;

    /**
     * @var string User email address
     */
    public $email;

    /**
     * @var string Username
     */
    public $username;

    /**
     * @var string Password
     */
    public $password;

    /**
     * @inheritdoc
     */
    public function rules() {
        $user = User::className();

        return [
            // username rules
            'usernameLength' => ['username', 'string', 'min' => 3, 'max' => 255],
            'usernameTrim' => ['username', 'filter', 'filter' => 'trim'],
            'usernamePattern' => ['username', 'match', 'pattern' => $user::$usernameRegexp],
            'usernameRequired' => ['username', 'required'],
            'usernameUnique' => [
                'username',
                'unique',
                'targetClass' => $user,
                'message' => Yii::t('user', 'This username has already been taken')
            ],
            // email rules
            'emailTrim' => ['email', 'filter', 'filter' => 'trim'],
            'emailRequired' => ['email', 'required'],
            'emailPattern' => ['email', 'email'],
            'emailUnique' => [
                'email',
                'unique',
                'targetClass' => $user,
                'message' => Yii::t('user', 'This email address has already been taken')
            ],
            // password rules
            'passwordRequired' => ['password', 'required', 'skipOnEmpty' => $this->module->enableGeneratingPassword],
            'passwordLength' => ['password', 'string', 'min' => 6],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'email' => Yii::t('user', 'Email'),
            'username' => Yii::t('user', 'Username'),
            'password' => Yii::t('user', 'Password'),
        ];
    }

    /**
     * @inheritdoc
     */
    public function formName() {
        return 'register-form';
    }

    /**
     * Registers a new user account. If registration was successful it will set flash message.
     *
     * @return bool
     */
    public function register() {
        if (!$this->validate()) {
            return false;
        }

        /** @var User $user */
        $user = Yii::createObject(User::className());
        $user->setScenario('register');
        $this->loadAttributes($user);

        if (!$user->register()) {
            return false;
        }

        Yii::$app->session->setFlash(
                'info', Yii::t('user', 'Your account has been created and a message with further instructions has been sent to your email')
        );

        return true;
    }

    /**
     * Loads attributes to the user model. You should override this method if you are going to add new fields to the
     * registration form. You can read more in special guide.
     *
     * By default this method set all attributes of this model to the attributes of User model, so you should properly
     * configure safe attributes of your User model.
     *
     * @param User $user
     */
    protected function loadAttributes(User $user) {
        $user->setAttributes($this->attributes);
    }

}


<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Filter
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Mcrypt.php 24593 2012-01-05 20:35:02Z matthew $
 */

/**
 * @see Zend_Filter_Encrypt_Interface
 */

/**
 * Encryption adapter for mcrypt
 *
 * @category   Zend
 * @package    Zend_Filter
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
{
    /**
     * Definitions for encryption
     * array(
     *     'key' => encryption key string
     *     'algorithm' => algorithm to use
     *     'algorithm_directory' => directory where to find the algorithm
     *     'mode' => encryption mode to use
     *     'modedirectory' => directory where to find the mode
     * )
     */
    protected $_encryption = array(
        'key'                 => 'ZendFramework',
        'algorithm'           => 'blowfish',
        'algorithm_directory' => '',
        'mode'                => 'cbc',
        'mode_directory'      => '',
        'vector'              => null,
        'salt'                => false
    );

    /**
     * Internal compression
     *
     * @var array
     */
    protected $_compression;

    protected static $_srandCalled = false;

    /**
     * Class constructor
     *
     * @param string|array|Zend_Config $options Cryption Options
     */
    public function __construct($options)
    {
        if (!extension_loaded('mcrypt')) {

            throw new Zend_Filter_Exception('This filter needs the mcrypt extension');
        }

        if ($options instanceof Zend_Config) {
            $options = $options->toArray();
        } elseif (is_string($options)) {
            $options = array('key' => $options);
        } elseif (!is_array($options)) {

            throw new Zend_Filter_Exception('Invalid options argument provided to filter');
        }

        if (array_key_exists('compression', $options)) {
            $this->setCompression($options['compression']);
            unset($options['compress']);
        }

        $this->setEncryption($options);
    }

    /**
     * Returns the set encryption options
     *
     * @return array
     */
    public function getEncryption()
    {
        return $this->_encryption;
    }

    /**
     * Sets new encryption options
     *
     * @param  string|array $options Encryption options
     * @return Zend_Filter_File_Encryption
     */
    public function setEncryption($options)
    {
        if (is_string($options)) {
            $options = array('key' => $options);
        }

        if (!is_array($options)) {

            throw new Zend_Filter_Exception('Invalid options argument provided to filter');
        }

        $options = $options + $this->getEncryption();
        $algorithms = mcrypt_list_algorithms($options['algorithm_directory']);
        if (!in_array($options['algorithm'], $algorithms)) {

            throw new Zend_Filter_Exception("The algorithm '{$options['algorithm']}' is not supported");
        }

        $modes = mcrypt_list_modes($options['mode_directory']);
        if (!in_array($options['mode'], $modes)) {

            throw new Zend_Filter_Exception("The mode '{$options['mode']}' is not supported");
        }

        if (!mcrypt_module_self_test($options['algorithm'], $options['algorithm_directory'])) {

            throw new Zend_Filter_Exception('The given algorithm can not be used due an internal mcrypt problem');
        }

        if (!isset($options['vector'])) {
            $options['vector'] = null;
        }

        $this->_encryption = $options;
        $this->setVector($options['vector']);

        return $this;
    }

    /**
     * Returns the set vector
     *
     * @return string
     */
    public function getVector()
    {
        return $this->_encryption['vector'];
    }

    /**
     * Sets the initialization vector
     *
     * @param string $vector (Optional) Vector to set
     * @return Zend_Filter_Encrypt_Mcrypt
     */
    public function setVector($vector = null)
    {
        $cipher = $this->_openCipher();
        $size   = mcrypt_enc_get_iv_size($cipher);
        if (empty($vector)) {
            $this->_srand();
            if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && version_compare(PHP_VERSION, '5.3.0', '<')) {
                $method = MCRYPT_RAND;
            } else {
                if (file_exists('/dev/urandom') || (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')) {
                    $method = MCRYPT_DEV_URANDOM;
                } elseif (file_exists('/dev/random')) {
                    $method = MCRYPT_DEV_RANDOM;
                } else {
                    $method = MCRYPT_RAND;
                }
            }
            $vector = mcrypt_create_iv($size, $method);
        } else if (strlen($vector) != $size) {

            throw new Zend_Filter_Exception('The given vector has a wrong size for the set algorithm');
        }

        $this->_encryption['vector'] = $vector;
        $this->_closeCipher($cipher);

        return $this;
    }

    /**
     * Returns the compression
     *
     * @return array
     */
    public function getCompression()
    {
        return $this->_compression;
    }

    /**
     * Sets a internal compression for values to encrypt
     *
     * @param string|array $compression
     * @return Zend_Filter_Encrypt_Mcrypt
     */
    public function setCompression($compression)
    {
        if (is_string($this->_compression)) {
            $compression = array('adapter' => $compression);
        }

        $this->_compression = $compression;
        return $this;
    }

    /**
     * Defined by Zend_Filter_Interface
     *
     * Encrypts $value with the defined settings
     *
     * @param  string $value The content to encrypt
     * @return string The encrypted content
     */
    public function encrypt($value)
    {
        // compress prior to encryption
        if (!empty($this->_compression)) {

            $compress = new Zend_Filter_Compress($this->_compression);
            $value    = $compress->filter($value);
        }

        $cipher  = $this->_openCipher();
        $this->_initCipher($cipher);
        $encrypted = mcrypt_generic($cipher, $value);
        mcrypt_generic_deinit($cipher);
        $this->_closeCipher($cipher);

        return $encrypted;
    }

    /**
     * Defined by Zend_Filter_Interface
     *
     * Decrypts $value with the defined settings
     *
     * @param  string $value Content to decrypt
     * @return string The decrypted content
     */
    public function decrypt($value)
    {
        $cipher = $this->_openCipher();
        $this->_initCipher($cipher);
        $decrypted = mdecrypt_generic($cipher, $value);
        mcrypt_generic_deinit($cipher);
        $this->_closeCipher($cipher);

        // decompress after decryption
        if (!empty($this->_compression)) {

            $decompress = new Zend_Filter_Decompress($this->_compression);
            $decrypted  = $decompress->filter($decrypted);
        }

        return $decrypted;
    }

    /**
     * Returns the adapter name
     *
     * @return string
     */
    public function toString()
    {
        return 'Mcrypt';
    }

    /**
     * Open a cipher
     *
     * @throws Zend_Filter_Exception When the cipher can not be opened
     * @return resource Returns the opened cipher
     */
    protected function _openCipher()
    {
        $cipher = mcrypt_module_open(
            $this->_encryption['algorithm'],
            $this->_encryption['algorithm_directory'],
            $this->_encryption['mode'],
            $this->_encryption['mode_directory']);

        if ($cipher === false) {

            throw new Zend_Filter_Exception('Mcrypt can not be opened with your settings');
        }

        return $cipher;
    }

    /**
     * Close a cipher
     *
     * @param  resource $cipher Cipher to close
     * @return Zend_Filter_Encrypt_Mcrypt
     */
    protected function _closeCipher($cipher)
    {
        mcrypt_module_close($cipher);

        return $this;
    }

    /**
     * Initialises the cipher with the set key
     *
     * @param  resource $cipher
     * @throws
     * @return resource
     */
    protected function _initCipher($cipher)
    {
        $key = $this->_encryption['key'];

        $keysizes = mcrypt_enc_get_supported_key_sizes($cipher);
        if (empty($keysizes) || ($this->_encryption['salt'] == true)) {
            $this->_srand();
            $keysize = mcrypt_enc_get_key_size($cipher);
            $key     = substr(md5($key), 0, $keysize);
        } else if (!in_array(strlen($key), $keysizes)) {

            throw new Zend_Filter_Exception('The given key has a wrong size for the set algorithm');
        }

        $result = mcrypt_generic_init($cipher, $key, $this->_encryption['vector']);
        if ($result < 0) {

            throw new Zend_Filter_Exception('Mcrypt could not be initialize with the given setting');
        }

        return $this;
    }

    /**
     * _srand() interception
     *
     * @see ZF-8742
     */
    protected function _srand()
    {
        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
            return;
        }

        if (!self::$_srandCalled) {
            srand((double) microtime() * 1000000);
            self::$_srandCalled = true;
        }
    }
}


<?php

declare(strict_types=1);

namespace NAttreid\Console\Collections;

use Exception;
use NAttreid\AppManager\AppManager;
use NAttreid\Console\CommandCollection;
use NAttreid\Console\InvalidArgumentException;
use NAttreid\Utils\TempFile;

/**
 * Sprava aplikace
 *
 * @author Attreid <attreid@gmail.com>
 */
class App extends CommandCollection
{

	/** @var AppManager */
	private $app;

	public function __construct(AppManager $app)
	{
		$this->app = $app;
	}

	/**
	 * Smazani session
	 * @param string $expiration (2 minutes, 4 days, atd) null smaze pouze expirovanou session
	 */
	public function clearSession(string $expiration = null): void
	{
		$this->app->clearSession($expiration);
	}

	/**
	 * Smazani cache
	 */
	public function clearCache(): void
	{
		$this->app->clearCache();
	}

	/**
	 * Smazani cache modelu
	 */
	public function invalidateCache(): void
	{
		$this->app->invalidateCache();
	}

	/**
	 * Smazani logu
	 */
	public function clearLog(): void
	{
		$this->app->clearLog();
	}

	/**
	 * Smazani temp
	 */
	public function clearTemp(): void
	{
		$this->app->clearTemp();
	}

	/**
	 * Zaloha databaze
	 * @param string $path
	 * @throws Exception
	 */
	public function backupDatabase(string $path): void
	{
		if (empty($path)) {
			throw new InvalidArgumentException();
		}
		$file = new TempFile(basename($path));
		$this->app->backupDatabase($file);
		$file->move(dirname($path));
	}

	/**
	 * Zaloha
	 * @param string $path
	 * @throws Exception
	 */
	public function backup(string $path): void
	{
		if (empty($path)) {
			throw new InvalidArgumentException();
		}
		$file = new TempFile(basename($path));
		$this->app->backup($file);
		$file->move(dirname($path));
	}

	/**
	 * Git pull
	 */
	public function gitPull(): void
	{
		$this->app->gitPull(true);
	}

	/**
	 * Aktualizace composeru
	 */
	public function composerUpdate(): void
	{
		$this->app->composerUpdate(true);
	}

	/**
	 * Zapnuti udrzby
	 */
	public function maintenance(): void
	{
		$this->printLine('Maintenance On');
		$this->printLine("To turn off maintenance run application with parameter maintenanceOff in browser or 'php index.php maintenanceOff' in console");
		$this->app->maintenance();
	}

}


<?php

namespace Behavior;

use Think\Behavior;

/**
 * 语言检测 并自动加载语言包
 */
final class CheckLangBehavior extends Behavior
{

    /**
     * 执行入口
     *
     * @param mixed $params
     */
    public function run(&$params)
    {
        static::_checkLanguage();
    }

    /**
     * 语言检查
     * 检查浏览器支持语言，并自动加载语言包

     * @return void
     */
    private static function _checkLanguage()
    {
        // 不开启语言包功能，仅仅加载框架语言文件直接返回
        if (!C('LANG_SWITCH_ON', null, false)) {
            return;
        }
        $langSet = C('DEFAULT_LANG');
        $varLang = C('VAR_LANGUAGE', null, 'l');
        $langList = C('LANG_LIST', null, 'zh-cn');
        // 启用了语言包功能
        // 根据是否启用自动侦测设置获取语言选择
        $_identity = md5('__language__');
        if (C('LANG_AUTO_DETECT', null, true)) {
            if (isset($_GET[$varLang])) {
                // url中设置了语言变量
                $langSet = $_GET[$varLang];
                cookie($_identity, $langSet, 3600);
            } elseif (cookie($_identity)) {
                // 获取上次用户的选择
                $langSet = cookie($_identity);
            } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
                // 自动侦测浏览器语言
                preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
                $langSet = $matches[1];
                cookie($_identity, $langSet, 3600);
            }
            if (false === stripos($langList, $langSet)) {
                // 非法语言参数
                $langSet = C('DEFAULT_LANG');
            }
        }
        // 定义当前语言
        define('LANG_SET', strtolower($langSet));

        // 读取框架语言包
        $file = __DIR__.'/../Lang/'.LANG_SET.'.php';
        if (LANG_SET != C('DEFAULT_LANG') && is_file($file)) {
            /** @noinspection PhpIncludeInspection */
            L(include $file);
        }

        // 读取应用公共语言包
        $file = LANG_PATH.LANG_SET.'.php';
        if (is_file($file)) {
            /** @noinspection PhpIncludeInspection */
            L(include $file);
        }

        // 读取模块语言包
        $file = MODULE_PATH.'Lang/'.LANG_SET.'.php';
        if (is_file($file)) {
            /** @noinspection PhpIncludeInspection */
            L(include $file);
        }

        // 读取当前控制器语言包
        $file = MODULE_PATH.'Lang/'.LANG_SET.'/'.strtolower(CONTROLLER_NAME).'.php';
        if (is_file($file)) {
            /** @noinspection PhpIncludeInspection */
            L(include $file);
        }
    }
}


<?php namespace RestGalleries\Auth;

use RestGalleries\Auth\AuthAdapter;
use RestGalleries\Http\RequestAdapter;
use RestGalleries\Http\Guzzle\GuzzleRequest;
use RestGalleries\Http\Plugins\RequestPluginAdapter;
use RestGalleries\Http\Guzzle\Plugins\GuzzleAuth;

/**
 * Common father class, makes the hard work to get the account data and verify the tokens.
 */
abstract class Auth implements AuthAdapter
{
    /**
     * "OAuth dance" URLs for the connect process.
     *
     * @var array
     */
    protected $endPoints;

    /**
     * Stores the client credentials and token credentials.
     *
     * @var array
     */
    protected $credentials = [];

    /**
     * What protocol is going to treat?.
     *
     * @var integer
     */
    protected $protocol;

    /**
     * Takes credentials and URLs, checks credentials and gets tokens.
     * Returns an account with their credentials.
     *
     * @param  array  $clientCredentials
     * @param  array  $endPoints
     * @param  string $userDataUrl
     * @return object
     */
    public static function connect(array $clientCredentials, array $endPoints, $userDataUrl)
    {
        $instance = new static;

        if (! $instance->protocol = self::getAuthProtocol($clientCredentials)) {
            throw new \InvalidArgumentException('Credential keys are invalid.');
        }

        $instance->credentials = $clientCredentials;
        $instance->endPoints   = $endPoints;
        $tokenCredentials      = $instance->fetchTokenCredentials();

        $instance->addToCredentials($tokenCredentials);
        $instance->filterCredentialsByKey('token_credentials');

        return $instance->fetchUserData($userDataUrl);

    }

    /**
     * Calls to the auth client and "makes the magic" returning token credentials.
     *
     * @return array
     */
    abstract protected function fetchTokenCredentials();

    /**
     * Checks the token credentials and returns an object with its account data.
     *
     * @param  array  $tokenCredentials
     * @param  string $userDataUrl
     * @return object
     */
    public static function verifyCredentials(array $tokenCredentials, $userDataUrl)
    {
        $instance = new static;

        if (! $instance->protocol = self::getAuthProtocol($tokenCredentials)) {
            throw new \InvalidArgumentException('Credential keys are invalid.');
        }

        $instance->addToCredentials($tokenCredentials);
        $instance->filterCredentialsByKey('token_credentials');

        return $instance->fetchUserData($userDataUrl);

    }

    /**
     * Merge the new credential values to the existing credentials.
     *
     * @param  array $credentials
     * @return void
     */
    protected function addToCredentials(array $credentials)
    {
        $this->credentials = array_merge(
            $this->credentials,
            $credentials
        );
    }

    /**
     * Filters the given credentials for use them with the "Auth::fetchUserData" method.
     *
     * @param  array $tokenCredentials
     * @return void
     */
    protected function filterCredentialsByKey($filter = 'client_credentials')
    {
        $this->removeCredentialPrefixes('oauth_');

        $method = 'get';
        $method .= ucfirst($this->protocol);
        $method .= 'Keys';

        $keys = call_user_func_array([$this, $method], [null]);

        $this->credentials = array_only(
            $this->credentials,
            $keys[$filter]
        );

    }

    /**
     * Remove an string from the the beginning of each credential key.
     *
     * @param  string $prefix
     * @return void
     */
    protected function removeCredentialPrefixes($prefix)
    {
        $this->credentials = array_remove_key_prefix(
            $this->credentials,
            $prefix
        );
    }

    /**
     * Makes the http request to the "checkUrl", and gets an object with account data.
     * Additionally it adds token credentials data to the object by if needed.
     *
     * @param  string $userDataUrl
     * @return object
     */
    protected function fetchUserData($userDataUrl)
    {
        $plugins = [
            'auth' => $this->newAuthExtension(),
        ];

        $request  = $this->newRequest();
        $userData = $request::init($userDataUrl)
            ->addPlugins($plugins)
            ->GET()
            ->getBody();

        $this->addDataTokens($userData, $this->credentials);

        return $userData;

    }

    /**
     * Object builder to create and use the Http request client.
     * In this case, is set up as default Guzzle Http client.
     *
     * @param  \RestGalleries\Http\RequestAdapter $request
     * @return \RestGalleries\Http\RequestAdapter
     */
    public function newRequest(RequestAdapter $request = null)
    {
        if (empty($request)) {
            $request = new GuzzleRequest;
        }

        return $request;

    }

    /**
     * Object builder to create auth plugin extension for request client.
     * In this case, it creates GuzzleAuth object by default.
     *
     * @param  \RestGalleries\Http\RequestPluginAdapter $authExtension
     * @return \RestGalleries\Http\RequestPluginAdapter
     */
    public function newAuthExtension(RequestPluginAdapter $authExtension = null)
    {
        if (empty($authExtension)) {
            $authExtension = new GuzzleAuth($this->credentials);
        }

        return $authExtension;

    }

    /**
     * Add token credentials to the object.
     *
     * @param  object $object
     * @param  array  $tokens
     * @return void
     */
    protected function addDataTokens(&$object, $tokenCredentials)
    {
        $tokens = &$object->tokens;

        $callback = function ($value, $key) use (&$tokens) {
            $tokens = array_add($tokens, $key, $value);
        };

        array_walk($tokenCredentials, $callback);

    }

    /**
     * Checks the credentials and returns the name of the auth system used, if credentials are not founds, returns false.
     *
     * @param  array $credentials
     * @return string|boolean
     */
    public static function getAuthProtocol(array $credentials)
    {
        $instance       = new static;
        $credentialKeys = array_keys($credentials);

        if ($instance->isOauth1($credentialKeys)) {
            return 'oauth1';
        }

        if ($instance->isOauth2($credentialKeys)) {
            return 'oauth2';
        }

        return false;

    }

    /**
     * Checks if the credentials are using OAuth1.0.
     *
     * @param  array $credentials
     * @return boolean
     */
    protected function isOauth1($credentialsKeys)
    {
        $keys = $this->getOauth1Keys();
        foreach ($keys as $value) {
            if (subarray($value, $credentialsKeys)) {
                return true;
            }
        }

        return false;

    }

    /**
     * Checks if the credentials are using OAuth2.0.
     *
     * @param  array $credentials
     * @return boolean
     */
    protected function isOauth2($credentialsKeys)
    {
        $keys = $this->getOauth2Keys();
        foreach ($keys as $value) {
            if (subarray($value, $credentialsKeys)) {
                return true;
            }
        }

        return false;

    }

    /**
     * Credential keys (token-client ouath1) necessary for normalize the obtained tokens, and check the client token for know the protocol.
     *
     * @return array
     */
    public static function getOauth1Keys()
    {
        return [
            'client_credentials' => ['consumer_key', 'consumer_secret', 'callback'],
            'token_credentials' => ['consumer_key', 'consumer_secret', 'token', 'token_secret']
        ];
    }

    /**
     * Credential keys (token-client ouath2)necessary for normalize the obtained tokens, and check for know the protocol.
     *
     * @return array
     */
    public static function getOauth2Keys()
    {
        return [
            'client_credentials' => ['client_id', 'client_secret', 'callback'],
            'token_credentials' => ['access_token', 'expires']
        ];
    }

}


<?php

namespace execut\menu\models;

use execut\crudFields\Behavior;
use execut\crudFields\BehaviorStub;
use execut\crudFields\fields\HasOneSelect2;
use execut\crudFields\ModelsHelperTrait;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;
use yii\helpers\ArrayHelper;

/**
 * This is the model class for table "menu_items".
 */
class Item extends ActiveRecord
{
    const MODEL_NAME = '{n,plural,=0{Items} =1{Item} other{Items}}';
    use BehaviorStub, ModelsHelperTrait;
//    public function init()
//    {
//        parent::init(); // TODO: Change the autogenerated stub
////        $this->visible = true;
//        $defaultId = Menu::getDefaultId();
//        if ($defaultId) {
//            $this->menu_menu_id = $defaultId;
//        }
//    }

    public function behaviors()
    {
        return ArrayHelper::merge(
            parent::behaviors(),
            [
                'fields' => [
                    'class' => Behavior::class,
                    'plugins' => \yii::$app->getModule('menu')->getItemFieldsPlugins(),
                    'fields' => $this->getStandardFields(null, [
                        [
                            'class' => HasOneSelect2::class,
                            'attribute' => 'menu_menu_id',
                            'relation' => 'menuMenu',
                            'url' => [
                                '/menu/menus'
                            ],
                            'defaultValue' => Menu::getDefaultId(),
                        ],
                        [
                            'required' => true,
                            'attribute' => 'sort',
                        ],
                        [
                            'class' => HasOneSelect2::class,
                            'attribute' => 'menu_item_id',
                            'relation' => 'menuItem',
                            'url' => [
                                '/menu/items'
                            ],
                        ],
                    ]),
                ],
                [
                    'class' => TimestampBehavior::className(),
                    'createdAtAttribute' => 'created',
                    'updatedAtAttribute' => 'updated',
                    'value' => new Expression('NOW()'),
                ],
                # custom behaviors
            ]
        );
    }

    public static function getMenuItems($position) {
        $q = self::find()->isVisible()->orderBySort()->byPositionKey($position);
        \yii::$app->getModule('menu')->applyItemsScopes($q);
        $items = $q->all();

        $result = self::getItemItems($items);

        return $result;
    }

    public function getUrl() {
        $plugins = \yii::$app->getModule('menu')->getPlugins();
        foreach ($plugins as $plugin) {
            $url = $plugin->getUrlByItem($this);
            if ($url) {
                return $url;
            }
        }

        return false;
    }

    public static function getItemItems(&$items, $parentId = null) {
        $result = [];
        foreach ($items as $key => $item) {
            if ($item->menu_item_id === $parentId) {
                unset($items[$key]);
                $result[] = [
                    'label' => $item->name,
                    'url' => $item->getUrl(),
                    'items' => self::getItemItems($items, $item->id),
                    'sort' => $item->sort,
                ];
            }
        }

        if ($parentId !== null) {
            uasort($result, function ($a, $b) {
                return $a['sort'] > $b['sort'];
            });
        }

        return $result;
    }

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'menu_items';
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getMenuItem()
    {
        return $this->hasOne(\execut\menu\models\Item::className(), ['id' => 'menu_item_id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getItems()
    {
        return $this->hasMany(\execut\menu\models\Item::className(), ['menu_item_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getMenuMenu()
    {
        return $this->hasOne(\execut\menu\models\Menu::className(), ['id' => 'menu_menu_id']);
    }

    /**
     * @inheritdoc
     * @return \execut\menu\models\queries\ItemQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new \execut\menu\models\queries\ItemQuery(get_called_class());
    }
}


<?php

/*
 * This file is part of the Valkyrja framework.
 *
 * (c) Melech Mizrachi
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Valkyrja\HttpMessage;

use RuntimeException;
use Valkyrja\HttpMessage\Exceptions\InvalidStream;

/**
 * Describes a data stream.
 *
 * Typically, an instance will wrap a PHP stream; this interface provides
 * a wrapper around the most common operations, including serialization of
 * the entire stream to a string.
 *
 * @author Melech Mizrachi
 */
class NativeStream implements Stream
{
    /**
     * The stream.
     *
     * @var resource
     */
    protected $stream;

    /**
     * StreamImpl constructor.
     *
     * @param string $stream The stream
     * @param string $mode   [optional] The mode
     *
     * @throws \Valkyrja\HttpMessage\Exceptions\InvalidStream
     */
    public function __construct(string $stream, string $mode = null)
    {
        $this->setStream($stream, $mode);
    }

    /**
     * Reads all data from the stream into a string, from the beginning to end.
     *
     * This method MUST attempt to seek to the beginning of the stream before
     * reading data and read the stream until the end is reached.
     *
     * Warning: This could attempt to load a large amount of data into memory.
     *
     * This method MUST NOT raise an exception in order to conform with PHP's
     * string casting operations.
     *
     * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
     *
     * @return string
     */
    public function __toString()
    {
        // If the stream is not readable
        if (! $this->isReadable()) {
            // Return an empty string
            return '';
        }

        try {
            // Rewind the stream to the start
            $this->rewind();

            // Get the stream's contents
            return $this->getContents();
        } // On a runtime exception
        catch (RuntimeException $e) {
            // Return a string
            return '';
        }
    }

    /**
     * Closes the stream and any underlying resources.
     *
     * @return void
     */
    public function close(): void
    {
        // If there is no stream
        if (null === $this->stream) {
            // Don't do anything
            return;
        }

        // Detach the stream
        $resource = $this->detach();

        // Close the stream
        fclose($resource);
    }

    /**
     * Separates any underlying resources from the stream.
     *
     * After the stream has been detached, the stream is in an unusable state.
     *
     * @return resource|null Underlying PHP stream, if any
     */
    public function detach()
    {
        $resource     = $this->stream;
        $this->stream = null;

        return $resource;
    }

    /**
     * Attaches a new stream.
     *
     * @param string $stream The stream
     * @param string $mode   [optional] The mode
     *
     * @throws \Valkyrja\HttpMessage\Exceptions\InvalidStream
     *
     * @return void
     */
    public function attach(string $stream, string $mode = null): void
    {
        $this->setStream($stream, $mode);
    }

    /**
     * Get the size of the stream if known.
     *
     * @return int|null Returns the size in bytes if known, or null if unknown.
     */
    public function getSize(): ? int
    {
        $fstat = null;

        // If the stream isn't set
        if (null === $this->stream) {
            // Return without attempting to get the fstat
            return $fstat;
        }

        // Get the stream's fstat
        $fstat = fstat($this->stream);

        return $fstat['size'];
    }

    /**
     * Returns the current position of the file read/write pointer.
     *
     * @throws \RuntimeException on error.
     *
     * @return int Position of the file pointer
     */
    public function tell(): int
    {
        // If there is no stream available
        if (null === $this->stream) {
            // Throw a runtime exception
            throw new RuntimeException(
                'No resource available; cannot tell position'
            );
        }

        // Get the tell for the stream
        $result = ftell($this->stream);

        // If the tell is not an int
        if (! \is_int($result)) {
            // Throw a runtime exception
            throw new RuntimeException(
                'Error occurred during tell operation'
            );
        }

        return $result;
    }

    /**
     * Returns true if the stream is at the end of the stream.
     *
     * @return bool
     */
    public function eof(): bool
    {
        // If there is no stream
        if (null === $this->stream) {
            // Don't do anything
            return true;
        }

        return feof($this->stream);
    }

    /**
     * Returns whether or not the stream is seekable.
     *
     * @return bool
     */
    public function isSeekable(): bool
    {
        // If there is no stream
        if (null === $this->stream) {
            // Don't do anything
            return false;
        }

        return $this->getMetadata('seekable');
    }

    /**
     * Seek to a position in the stream.
     *
     * @link http://www.php.net/manual/en/function.fseek.php
     *
     * @param int $offset Stream offset
     * @param int $whence Specifies how the cursor position will be calculated
     *                    based on the seek offset. Valid values are identical
     *                    to the built-in PHP $whence values for `fseek()`.
     *                    SEEK_SET: Set position equal to offset bytes
     *                    SEEK_CUR: Set position to current location plus
     *                    offset SEEK_END: Set position to end-of-stream plus
     *                    offset.
     *
     * @throws \RuntimeException on failure.
     *
     * @return void
     */
    public function seek(int $offset, int $whence = SEEK_SET): void
    {
        // If there is no stream
        if (null === $this->stream) {
            // Throw a new runtime exception
            throw new RuntimeException(
                'No resource available; cannot seek position'
            );
        }

        // If the stream isn't seekable
        if (! $this->isSeekable()) {
            // Throw a new runtime exception
            throw new RuntimeException(
                'Stream is not seekable'
            );
        }

        // Get the results of the seek attempt
        $result = fseek($this->stream, $offset, $whence);

        // If the result was not a 0, denoting an error occurred
        if (0 !== $result) {
            // Throw a new runtime exception
            throw new RuntimeException(
                'Error seeking within stream'
            );
        }
    }

    /**
     * Seek to the beginning of the stream.
     *
     * If the stream is not seekable, this method will raise an exception;
     * otherwise, it will perform a seek(0).
     *
     * @see  seek()
     * @link http://www.php.net/manual/en/function.fseek.php
     *
     * @throws \RuntimeException on failure.
     *
     * @return void
     */
    public function rewind(): void
    {
        $this->seek(0);
    }

    /**
     * Returns whether or not the stream is writable.
     *
     * @return bool
     */
    public function isWritable(): bool
    {
        // If there is no stream
        if (null === $this->stream) {
            // The stream is definitely not writable
            return false;
        }

        // Get the stream's mode
        $mode = $this->getMetadata('mode');

        return
            false !== strpos($mode, 'x')
            || false !== strpos($mode, 'w')
            || false !== strpos($mode, 'c')
            || false !== strpos($mode, 'a')
            || false !== strpos($mode, '+');
    }

    /**
     * Write data to the stream.
     *
     * @param string $string The string that is to be written.
     *
     * @throws \RuntimeException on failure.
     *
     * @return int Returns the number of bytes written to the stream.
     */
    public function write(string $string): int
    {
        // If there is no stream
        if (null === $this->stream) {
            // Throw a new runtime exception
            throw new RuntimeException(
                'No resource available; cannot write'
            );
        }

        // If the stream isn't seekable
        if (! $this->isSeekable()) {
            // Throw a new runtime exception
            throw new RuntimeException(
                'Stream is not writable'
            );
        }

        // Attempt to write to the stream
        $result = fwrite($this->stream, $string);

        // If the write was not successful
        if (false === $result) {
            // Throw a runtime exception
            throw new RuntimeException(
                'Error writing to stream'
            );
        }

        return $result;
    }

    /**
     * Returns whether or not the stream is readable.
     *
     * @return bool
     */
    public function isReadable(): bool
    {
        // If there is no stream
        if (null === $this->stream) {
            // It's not readable
            return false;
        }

        // Get the stream's mode
        $mode = $this->getMetadata('mode');

        return false !== strpos($mode, 'r') || false !== strpos($mode, '+');
    }

    /**
     * Read data from the stream.
     *
     * @param int $length Read up to $length bytes from the object and return
     *                    them. Fewer than $length bytes may be returned if
     *                    underlying stream call returns fewer bytes.
     *
     * @throws \RuntimeException if an error occurs.
     *
     * @return string Returns the data read from the stream, or an empty string
     *          if no bytes are available.
     */
    public function read(int $length): string
    {
        // If there is no stream
        if (null === $this->stream) {
            // Throw a runtime exception
            throw new RuntimeException(
                'No resource available; cannot read'
            );
        }

        // If the stream is not readable
        if (! $this->isReadable()) {
            // Throw a runtime exception
            throw new RuntimeException(
                'Stream is not readable'
            );
        }

        // Read the stream
        $result = fread($this->stream, $length);

        // If there was a failure in reading the stream
        if (false === $result) {
            // Throw a runtime exception
            throw new RuntimeException(
                'Error reading stream'
            );
        }

        return $result;
    }

    /**
     * Returns the remaining contents in a string.
     *
     * @throws \RuntimeException
     *          if unable to read or an error occurs while reading.
     *
     * @return string
     */
    public function getContents(): string
    {
        // If the stream isn't readable
        if (! $this->isReadable()) {
            // Throw a runtime exception
            throw new RuntimeException('Stream is not readable');
        }

        // Get the stream contents
        $result = stream_get_contents($this->stream);

        // If there was a failure in getting the stream contents
        if (false === $result) {
            // Throw a runtime exception
            throw new RuntimeException('Error reading from stream');
        }

        return $result;
    }

    /**
     * Get stream metadata as an associative array or retrieve a specific key.
     *
     * The keys returned are identical to the keys returned from PHP's
     * stream_get_meta_data() function.
     *
     * @link http://php.net/manual/en/function.stream-get-meta-data.php
     *
     * @param string $key Specific metadata to retrieve.
     *
     * @return array|mixed|null Returns an associative array if no key is
     *          provided. Returns a specific key value if a key is provided
     *          and the value is found, or null if the key is not found.
     */
    public function getMetadata(string $key = null)
    {
        // If no key was specified
        if (null === $key) {
            // Return all the meta data
            return stream_get_meta_data($this->stream);
        }

        // Get the meta data
        $metadata = stream_get_meta_data($this->stream);

        return $metadata[$key] ?? null;
    }

    /**
     * Set the stream.
     *
     * @param string $stream The stream
     * @param string $mode   [optional] The mode
     *
     * @throws \Valkyrja\HttpMessage\Exceptions\InvalidStream
     *
     * @return void
     */
    protected function setStream(string $stream, string $mode = null): void
    {
        // Set the mode
        $mode = $mode ?? 'r';

        // Open a new resource stream
        $resource = fopen($stream, $mode);

        // If the resource isn't a resource or a stream resource type
        if (! \is_resource($resource) || 'stream' !== get_resource_type(
                $resource
            )
        ) {
            // Throw a new invalid stream exception
            throw new InvalidStream(
                'Invalid stream provided; must be a string stream identifier or stream resource'
            );
        }

        // Set the stream
        $this->stream = $resource;
    }
}


<?php

/*
 * This file is part of the frenzy-framework package.
 *
 * (c) Gustavo Falco <comfortablynumb84@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace IronEdge\Component\Config\Writer;

/*
 * @author Gustavo Falco <comfortablynumb84@gmail.com>
 */
use IronEdge\Component\FileUtils\File\Factory;

class FileWriter implements WriterInterface
{
    /**
     * Field _factory.
     *
     * @var
     */
    private $_factory;

    /**
     * Constructor.
     *
     * @param Factory|null $factory - Factory.
     */
    public function __construct(Factory $factory = null)
    {
        $this->_factory = $factory ?
            $factory :
            new Factory();
    }

    /**
     * This method writes the configuration to a file.
     *
     * @param array $data    - Data.
     * @param array $options - Options.
     *
     * @throws \InvalidArgumentException
     *
     * @return array
     */
    public function write(array $data, array $options)
    {
        if (!isset($options['file'])) {
            throw new \InvalidArgumentException(
                'Parameter "file" is mandatory.'
            );
        }

        if (!is_string($options['file'])) {
            throw new \InvalidArgumentException(
                'Parameter "file" must be a string.'
            );
        }

        $file = $this->_factory->createInstance($options['file'], null, $options);

        $file->setContents($data)
            ->save($options);
    }

}


<?php
namespace Li;

class Log
{
    private static $_log;

    private $_name = 'default';
    private $_config = [];

    private $_defaultConf = array(
        'format'  => 'YmdH', //按天分文件
        'level' => [
            'debug',
            'warning',
            'trace',
            'fatal',
        ],
    );

    public static function log($name='default')
    {
        if (!(self::$_log instanceof self)) {
            self::$_log = new self($name);
        }

        $trace = debug_backtrace();
        self::$_log->file = $trace[0]['file'];
        self::$_log->line = $trace[0]['line'];

        self::$_log->_init($name);

        return self::$_log;
    }

    private function _init($name=null)
    {
        if(empty($name)) {
            $name = 'default';
        }

        $this->_name = $name;

        if(isset(App::app()->config['log'][$name])) {
            $this->_config[$name] = array_merge($this->_defaultConf, App::app()->config['log'][$name]);
        } else {
            $this->_config[$name] = $this->_defaultConf;
        }
    }

    public function __construct($name=null)
    {
        $this->_config = App::app()->config['log'];
        $this->_init($name);
    }

    /**
     * @return string the log file name
     */
    private function _getFileName($level)
    {
        $filename = 'log';
        if($level == 'warning' || $level == 'fatal') {
            $filename .= '.wf';
        }

        return $this->_name . '.' . $filename.'.'.date($this->_config[$this->_name]['format'], NOW);
    }

    /**
     * 如果框架debug为true，返回true
     * 如果框架debug为false，根据日志配置的debug返回
     * if li global config debug is false,
     * @return boolean if write return true, otherwise false
     */
    private function _checkLevel($level)
    {
        if(in_array($level, $this->_config[$this->_name]['level'])) {
            return true;
        }

        return false;
    }

    private function _write($message, $level)
    {
        if (!$this->_checkLevel($level)) {
            return false;
        }

        $fileName = $this->_getFileName($level);
        $filePath = PATH_APP.'runtime'.DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR;

        if($message instanceof \Exception) {
            $log = date('Y-m-d H:i:s', NOW).' '.'['.$level.'] '.$message->getMessage(). ' [' . $message->getFile().':'.$message->getLine() . "]\r\n";
        } else {
            $log = date('Y-m-d H:i:s', NOW).' '.'['.$level.'] '.$message. ' [' . $this->file.':'.$this->line . "]\r\n";
        }

        if(!is_dir($filePath)) {
            mkdir($filePath);
        }

        if($message instanceof \Exception) {
            $log = date('Y-m-d H:i:s', NOW).' '.'['.$level.'] '.$message->getMessage(). ' [' . $message->getFile().':'.$message->getLine() . "]\r\n";
        } else {
            $log = date('Y-m-d H:i:s', NOW).' '.'['.$level.'] '.$message. ' [' . $this->file.':'.$this->line . "]\r\n";
        }

        if(App::app()->config['debug']) {
            echo $log . PHP_EOL;
        } else {
            error_log($log, 3, $filePath.$fileName);
        }

        $this->_configIndex=null;
    }

    /**
     * trace日志内容
     */
    public function debug($message)
    {
        $this->_write($message, __FUNCTION__);
    }

    /**
     * trace日志内容
     */
    public function trace($message)
    {
        $this->_write($message, __FUNCTION__);
    }

    /**
     * error日志内容
     */
    public function warning($message)
    {
        $this->_write($message, __FUNCTION__);
    }

    /**
     * fatal日志内容
     */
    public function fatal($message)
    {
        $this->_write($message, __FUNCTION__);
    }
}