<?php

namespace Dhii\Data\Object;

use Dhii\Util\String\StringableInterface as Stringable;
use InvalidArgumentException;
use Exception as RootException;
use OutOfRangeException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Container\ContainerInterface;
use ArrayAccess;
use stdClass;

/**
 * Functionality for data retrieval.
 *
 * @since [*next-version*]
 */
trait GetDataCapableTrait
{
    /**
     * Retrieve data, all or by key.
     *
     * @since [*next-version*]
     *
     * @param string|int|float|bool|Stringable $key The key, for which to get the data.
     *                                              Unless an integer is given, this will be normalized to string.
     *
     * @throws InvalidArgumentException    If key is invalid.
     * @throws ContainerExceptionInterface If an error occurred while reading from the container.
     * @throws NotFoundExceptionInterface  If the key was not found in the container.
     *
     * @return mixed The value for the specified key.
     */
    protected function _getData($key)
    {
        $store = $this->_getDataStore();

        try {
            $result = $this->_containerGet($store, $key);
        } catch (OutOfRangeException $e) {
            throw $this->_createInvalidArgumentException($this->__('Invalid key'), null, $e, $key);
        }

        return $result;
    }

    /**
     * Retrieves a pointer to the data store.
     *
     * @since [*next-version*]
     *
     * @return array|ArrayAccess|stdClass|ContainerInterface The data store.
     */
    abstract protected function _getDataStore();

    /**
     * Retrieves a value from a container or data set.
     *
     * @since [*next-version*]
     *
     * @param array|ArrayAccess|stdClass|ContainerInterface $container The container to read from.
     * @param string|int|float|bool|Stringable              $key       The key of the value to retrieve.
     *
     * @throws ContainerExceptionInterface If an error occurred while reading from the container.
     * @throws NotFoundExceptionInterface  If the key was not found in the container.
     *
     * @return mixed The value mapped to the given key.
     */
    abstract protected function _containerGet($container, $key);

    /**
     * Creates a new Dhii invalid argument exception.
     *
     * @since [*next-version*]
     *
     * @param string|Stringable|null $message  The error message, if any.
     * @param int|null               $code     The error code, if any.
     * @param RootException|null     $previous The inner exception for chaining, if any.
     * @param mixed|null             $argument The invalid argument, if any.
     *
     * @return InvalidArgumentException The new exception.
     */
    abstract protected function _createInvalidArgumentException(
        $message = null,
        $code = null,
        RootException $previous = null,
        $argument = null
    );

    /**
     * Translates a string, and replaces placeholders.
     *
     * @since [*next-version*]
     * @see   sprintf()
     *
     * @param string $string  The format string to translate.
     * @param array  $args    Placeholder values to replace in the string.
     * @param mixed  $context The context for translation.
     *
     * @return string The translated string.
     */
    abstract protected function __($string, $args = [], $context = null);
}


<?php
namespace jeyroik\extas\components\systems\states\machines\extensions;

use jeyroik\extas\components\systems\Extension;
use jeyroik\extas\components\systems\extensions\TExtendable;
use jeyroik\extas\interfaces\systems\states\machines\extensions\IStatesRoute;
use jeyroik\extas\interfaces\systems\states\IStateMachine;

/**
 * Class StatesRoute
 *
 * @package jeyroik\extas\components\systems\states\machines
 * @author Funcraft <me@funcraft.ru>
 */
class ExtensionStatesRoute extends Extension implements IStatesRoute
{
    use TExtendable;

    /**
     * @var array
     */
    protected $config = [];

    public $subject = IStateMachine::SUBJECT;
    public $methods = [
        'from' => IStatesRoute::class,
        'to' => IStatesRoute::class,
        'getRoute' => IStatesRoute::class,
        'setRoute' => IStatesRoute::class,
        'getCurrentFrom' => IStatesRoute::class,
        'getCurrentTo' => IStatesRoute::class
    ];

    /**
     * @param $stateId
     * @param $machine
     *
     * @return IStatesRoute
     */
    public function from($stateId, IStateMachine $machine = null): IStatesRoute
    {
        $this->extractFromMachine($machine);

        $route = $this[static::FIELD__ROUTE];

        foreach ($this->getPluginsByStage(static::STAGE__FROM) as $plugin) {
            $stateId = $plugin($this, $stateId);
        }

        if (!isset($route[$stateId])) {
            $route[$stateId] = [];
        }

        $this[static::FIELD__CURRENT_FROM] = $stateId;
        $this[static::FIELD__ROUTE] = $route;

        $this->packToMachine($machine);

        return $this;
    }

    /**
     * @param $stateId
     * @param $machine
     *
     * @return IStatesRoute
     */
    public function to($stateId, IStateMachine $machine = null): IStatesRoute
    {
        $this->extractFromMachine($machine);

        foreach ($this->getPluginsByStage(static::STAGE__TO) as $plugin) {
            $stateId = $plugin($this, $stateId);
        }

        $route = $this[static::FIELD__ROUTE];

        $route[$this[static::FIELD__CURRENT_FROM]][] = $stateId;
        $this[static::FIELD__ROUTE] = $route;
        $this[static::FIELD__CURRENT_TO] = $stateId;

        $this->packToMachine($machine);

        return $this;
    }

    /**
     * @param $machine
     *
     * @return array
     */
    public function getRoute(IStateMachine $machine = null)
    {
        $this->extractFromMachine($machine);

        return $this[static::FIELD__ROUTE];
    }

    /**
     * @param array|IStatesRoute $route
     * @param $machine
     *
     * @return $this
     * @throws \Exception
     */
    public function setRoute($route, IStateMachine $machine = null)
    {
        if (is_array($route)) {
            $this[static::FIELD__ROUTE] = $route;
        } elseif (is_object($route) && ($route instanceof IStatesRoute)) {
            $this[static::FIELD__ROUTE] = $route[static::FIELD__ROUTE];
        } else {
            throw new \Exception('Unsupported route type "' . gettype($route) . '".');
        }

        $this->packToMachine($machine);

        return $this;
    }

    /**
     * @param $machine
     *
     * @return string
     */
    public function getCurrentFrom(IStateMachine $machine = null): string
    {
        $this->extractFromMachine($machine);

        return $this[static::FIELD__CURRENT_FROM];
    }

    /**
     * @return string
     */
    public function getCurrentTo()
    {
        $this->extractFromMachine($machine);

        return $this[static::FIELD__CURRENT_TO];
    }

    /**
     * @param IStateMachine $machine
     *
     * @return $this
     */
    protected function extractFromMachine(IStateMachine &$machine)
    {
        if (!isset($machine[IStatesRoute::class])) {
            $this[static::FIELD__ROUTE] = [];
            $this[static::FIELD__CURRENT_FROM] = '';
            $this[static::FIELD__CURRENT_TO] = null;

            $machine[IStatesRoute::class] = $this->__toArray();
        }

        $this->setConfig($machine[IStatesRoute::class]);

        return $this;
    }

    /**
     * @param IStateMachine $machine
     *
     * @return $this
     */
    protected function packToMachine(IStateMachine &$machine)
    {
        $machine[IStatesRoute::class] = $this->__toArray();

        return $this;
    }

    /**
     * @return string
     */
    protected function getSubjectForExtension(): string
    {
        return IStatesRoute::SUBJECT;
    }
}


<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\filters;

use Yii;
use yii\base\ActionFilter;
use yii\web\Request;
use yii\web\Response;

/**
 * Cors filter implements [Cross Origin Resource Sharing](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing).
 * Make sure to read carefully what CORS does and does not. CORS do not secure your API,
 * but allow the developer to grant access to third party code (ajax calls from external domain)
 *
 * You may use CORS filter by attaching it as a behavior to a controller or module, like the following,
 *
 * ```php
 * public function behaviors()
 * {
 *     return [
 *         'corsFilter' => [
 *             'class' => \yii\filters\Cors::className(),
 *         ],
 *     ];
 * }
 * ```
 *
 * The CORS filter can be specialized to restrict parameters, like this,
 * [MDN CORS Information](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
 *
 * ```php
 * public function behaviors()
 * {
 *     return [
 *         'corsFilter' => [
 *             'class' => \yii\filters\Cors::className(),
 *             'cors' => [
 *                 // restrict access to
 *                 'Origin' => ['http://www.myserver.com', 'https://www.myserver.com'],
 *                 'Access-Control-Request-Method' => ['POST', 'PUT'],
 *                 // Allow only POST and PUT methods
 *                 'Access-Control-Request-Headers' => ['X-Wsse'],
 *                 // Allow only headers 'X-Wsse'
 *                 'Access-Control-Allow-Credentials' => true,
 *                 // Allow OPTIONS caching
 *                 'Access-Control-Max-Age' => 3600,
 *                 // Allow the X-Pagination-Current-Page header to be exposed to the browser.
 *                 'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
 *             ],
 *
 *         ],
 *     ];
 * }
 * ```
 *
 * @author Philippe Gaultier <pgaultier@gmail.com>
 * @since 2.0
 */
class Cors extends ActionFilter
{
    /**
     * @var Request the current request. If not set, the `request` application component will be used.
     */
    public $request;
    /**
     * @var Response the response to be sent. If not set, the `response` application component will be used.
     */
    public $response;
    /**
     * @var array define specific CORS rules for specific actions
     */
    public $actions = [];
    /**
     * @var array Basic headers handled for the CORS requests.
     */
    public $cors = [
        'Origin' => ['*'],
        'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
        'Access-Control-Request-Headers' => ['*'],
        'Access-Control-Allow-Credentials' => null,
        'Access-Control-Max-Age' => 86400,
        'Access-Control-Expose-Headers' => [],
    ];

    /**
     * @inheritdoc
     */
    public function beforeAction($action)
    {
        $this->request = $this->request ?: Yii::$app->getRequest();
        $this->response = $this->response ?: Yii::$app->getResponse();

        $this->overrideDefaultSettings($action);

        $requestCorsHeaders = $this->extractHeaders();
        $responseCorsHeaders = $this->prepareHeaders($requestCorsHeaders);
        $this->addCorsHeaders($this->response, $responseCorsHeaders);

        return true;
    }

    /**
     * Override settings for specific action
     * @param \yii\base\Action $action the action settings to override
     */
    public function overrideDefaultSettings($action)
    {
        if (isset($this->actions[$action->id])) {
            $actionParams = $this->actions[$action->id];
            $actionParamsKeys = array_keys($actionParams);
            foreach ($this->cors as $headerField => $headerValue) {
                if (in_array($headerField, $actionParamsKeys)) {
                    $this->cors[$headerField] = $actionParams[$headerField];
                }
            }
        }
    }

    /**
     * Extract CORS headers from the request
     * @return array CORS headers to handle
     */
    public function extractHeaders()
    {
        $headers = [];
        $requestHeaders = array_keys($this->cors);
        foreach ($requestHeaders as $headerField) {
            $serverField = $this->headerizeToPhp($headerField);
            $headerData = isset($_SERVER[$serverField]) ? $_SERVER[$serverField] : null;
            if ($headerData !== null) {
                $headers[$headerField] = $headerData;
            }
        }
        return $headers;
    }

    /**
     * For each CORS headers create the specific response
     * @param array $requestHeaders CORS headers we have detected
     * @return array CORS headers ready to be sent
     */
    public function prepareHeaders($requestHeaders)
    {
        $responseHeaders = [];
        // handle Origin
        if (isset($requestHeaders['Origin'], $this->cors['Origin'])) {
            if (in_array('*', $this->cors['Origin']) || in_array($requestHeaders['Origin'], $this->cors['Origin'])) {
                $responseHeaders['Access-Control-Allow-Origin'] = $requestHeaders['Origin'];
            }
        }

        $this->prepareAllowHeaders('Headers', $requestHeaders, $responseHeaders);

        if (isset($requestHeaders['Access-Control-Request-Method'])) {
            $responseHeaders['Access-Control-Allow-Methods'] = implode(', ', $this->cors['Access-Control-Request-Method']);
        }

        if (isset($this->cors['Access-Control-Allow-Credentials'])) {
            $responseHeaders['Access-Control-Allow-Credentials'] = $this->cors['Access-Control-Allow-Credentials'] ? 'true' : 'false';
        }

        if (isset($this->cors['Access-Control-Max-Age']) && Yii::$app->getRequest()->getIsOptions()) {
            $responseHeaders['Access-Control-Max-Age'] = $this->cors['Access-Control-Max-Age'];
        }

        if (isset($this->cors['Access-Control-Expose-Headers'])) {
            $responseHeaders['Access-Control-Expose-Headers'] = implode(', ', $this->cors['Access-Control-Expose-Headers']);
        }

        return $responseHeaders;
    }

    /**
     * Handle classic CORS request to avoid duplicate code
     * @param string $type the kind of headers we would handle
     * @param array $requestHeaders CORS headers request by client
     * @param array $responseHeaders CORS response headers sent to the client
     */
    protected function prepareAllowHeaders($type, $requestHeaders, &$responseHeaders)
    {
        $requestHeaderField = 'Access-Control-Request-' . $type;
        $responseHeaderField = 'Access-Control-Allow-' . $type;
        if (!isset($requestHeaders[$requestHeaderField], $this->cors[$requestHeaderField])) {
            return;
        }
        if (in_array('*', $this->cors[$requestHeaderField])) {
            $responseHeaders[$responseHeaderField] = $this->headerize($requestHeaders[$requestHeaderField]);
        } else {
            $requestedData = preg_split("/[\\s,]+/", $requestHeaders[$requestHeaderField], -1, PREG_SPLIT_NO_EMPTY);
            $acceptedData = array_uintersect($requestedData, $this->cors[$requestHeaderField], 'strcasecmp');
            if (!empty($acceptedData)) {
                $responseHeaders[$responseHeaderField] = implode(', ', $acceptedData);
            }
        }
    }

    /**
     * Adds the CORS headers to the response
     * @param Response $response
     * @param array CORS headers which have been computed
     */
    public function addCorsHeaders($response, $headers)
    {
        if (empty($headers) === false) {
            $responseHeaders = $response->getHeaders();
            foreach ($headers as $field => $value) {
                $responseHeaders->set($field, $value);
            }
        }
    }

    /**
     * Convert any string (including php headers with HTTP prefix) to header format like :
     *  * X-PINGOTHER -> X-Pingother
     *  * X_PINGOTHER -> X-Pingother
     * @param string $string string to convert
     * @return string the result in "header" format
     */
    protected function headerize($string)
    {
        $headers = preg_split("/[\\s,]+/", $string, -1, PREG_SPLIT_NO_EMPTY);
        $headers = array_map(function ($element) {
            return str_replace(' ', '-', ucwords(strtolower(str_replace(['_', '-'], [' ', ' '], $element))));
        }, $headers);
        return implode(', ', $headers);
    }

    /**
     * Convert any string (including php headers with HTTP prefix) to header format like :
     *  * X-Pingother -> HTTP_X_PINGOTHER
     *  * X PINGOTHER -> HTTP_X_PINGOTHER
     * @param string $string string to convert
     * @return string the result in "php $_SERVER header" format
     */
    protected function headerizeToPhp($string)
    {
        return 'HTTP_' . strtoupper(str_replace([' ', '-'], ['_', '_'], $string));
    }
}


<?php
//
// +---------------------------------------------------------------------+
// | CODE INC. SOURCE CODE                                               |
// +---------------------------------------------------------------------+
// | Copyright (c) 2017 - Code Inc. SAS - All Rights Reserved.           |
// | Visit https://www.codeinc.fr for more information about licensing.  |
// +---------------------------------------------------------------------+
// | NOTICE:  All information contained herein is, and remains the       |
// | property of Code Inc. SAS. The intellectual and technical concepts  |
// | contained herein are proprietary to Code Inc. SAS are protected by  |
// | trade secret or copyright law. Dissemination of this information or |
// | reproduction of this material  is strictly forbidden unless prior   |
// | written permission is obtained from Code Inc. SAS.                  |
// +---------------------------------------------------------------------+
//
// Author:   Joan Fabrégat <joan@codeinc.fr>
// Date:     07/03/2018
// Time:     01:47
// Project:  Psr15Middlewares
//
declare(strict_types = 1);
namespace CodeInc\Psr15Middlewares\HttpHeaders\Security;
use CodeInc\Psr15Middlewares\HttpHeaders\AbstractHttpHeaderMiddleware;
use CodeInc\Psr15Middlewares\MiddlewareException;
use CodeInc\Psr15Middlewares\Tests\HttpHeaders\Security\FrameOptionsMiddlewareTest;

/**
 * Class FrameOptionsMiddleware
 *
 * @link https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options
 * @see FrameOptionsMiddlewareTest
 * @package CodeInc\Psr15Middlewares\HttpHeaders\Security
 * @author Joan Fabrégat <joan@codeinc.fr>
 */
class FrameOptionsMiddleware extends AbstractHttpHeaderMiddleware
{
    public const VALUE_DENY = 'DENY';
    public const VALUE_SAMEORIGIN = 'SAMEORIGIN';
    public const VALUE_ALLOW_FROM= 'ALLOW-FROM %s';

    /**
     * @var string
     */
	private $value;

    /**
     * FrameOptionsMiddleware constructor.
     *
     * @param string $value
     */
	public function __construct(string $value)
    {
        parent::__construct('X-Frame-Options');
        $this->value = $value;
    }

    /**
     * @return string
     */
    public function getValue():string
    {
        return $this->value;
    }

    /**
     * @param string $value
     */
    public function setValue(string $value):void
    {
        $this->value = $value;
    }

    /**
     * Deny frames.
     *
     * @return self
     */
    public static function denyFrames():self
    {
        return new self(self::VALUE_DENY);
    }

    /**
     * Allow frames from the same origin.
     *
     * @return self
     */
    public static function allowFromSameOrigin():self
    {
        return new self(self::VALUE_SAMEORIGIN);
    }

    /**
     * Allow frame from a given URL.
     *
     * @param string $allowFromUrl
     * @return self
     * @throws MiddlewareException
     */
    public static function allowFrom(string $allowFromUrl):self
    {
        $middleware = new self(sprintf(self::VALUE_ALLOW_FROM, $allowFromUrl));

        if (!filter_var($allowFromUrl, FILTER_VALIDATE_URL)) {
            throw new MiddlewareException(
                $middleware,
                sprintf("'%s' is not a valid URL", $allowFromUrl)
            );
        }

        return $middleware;
    }

    /**
     * @inheritdoc
     * @return string
     */
    public function getHeaderValue():string
    {
        return $this->value;
    }
}


<?php
/*
 * Copyright (c) 2014 @trashtoy
 * https://github.com/trashtoy/
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/**
 * PHP class file.
 * @auhtor trashtoy
 * @since  2.0.0
 */
namespace Peach\Markup;

/**
 * デフォルトの改行ルールです.
 */
class DefaultBreakControl implements BreakControl
{
    /**
     * 外部からインスタンス化できません.
     */
    private function __construct() {}

    /**
     * 指定された要素の開始タグの後ろに改行を付けるかどうかを決定します.
     * 条件は以下の通りです.
     *
     * - もしも指定された要素に子要素がない場合は改行なし
     * - 子要素を一つだけ含み, それが整形済テキストの場合は改行あり
     * - 子要素を一つだけ含み, それがコンテナ要素の場合, 再帰的にチェックした結果
     * - 子要素を一つだけ含み, 上記以外のノードの場合は改行なし
     * - 子要素が二つ以上の場合は改行あり
     *
     * @param  ContainerElement $node
     * @return bool
     */
    public function breaks(ContainerElement $node)
    {
        $size = $node->size();
        switch ($size) {
        case 0:
            return false;
        case 1:
            $childNodes = $node->getChildNodes();
            $child      = $childNodes[0];
            if ($child instanceof Code) {
                return true;
            }
            if ($child instanceof ContainerElement) {
                return $this->breaks($child);
            }
            return false;
        default:
            return true;
        }
    }

    /**
     * 唯一のインスタンスを取得します.
     *
     * @return DefaultBreakControl
     * @codeCoverageIgnore
     */
    public static function getInstance()
    {
        static $instance = null;
        if ($instance === null) {
            $instance = new self();
        }
        return $instance;
    }
}


<?php
/*
 * Copyright (c) 2015 @trashtoy
 * https://github.com/trashtoy/
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/**
 * PHP class file.
 * @auhtor trashtoy
 * @since  2.1.0
 */
namespace Peach\DF;

use InvalidArgumentException;
use Peach\DF\JsonCodec\Context;
use Peach\DF\JsonCodec\DecodeException;
use Peach\DF\JsonCodec\Root;
use Peach\Util\ArrayMap;
use Peach\Util\Strings;
use Peach\Util\Values;

/**
 * JSON 形式の文字列を扱う Codec です.
 * このクラスは {@link http://tools.ietf.org/html/rfc7159 RFC 7159}
 * の仕様に基いて JSON のデコード (JSON を値に変換) とエンコード (値を JSON に変換)
 * を行います.
 *
 * RFC 7159 によると JSON 文字列のエンコーディングは UTF-8, UTF-16, UTF-32
 * のいずれかであると定義されていますが, この実装は UTF-8 でエンコーディングされていることを前提とします.
 * UTF-8 以外の文字列をデコードした場合はエラーとなります.
 */
class JsonCodec implements Codec
{
    /**
     * 定数 JSON_HEX_TAG に相当するオプションです.
     * 文字 %x3c (LESS-THAN SIGN) および %x3e (GREATER-THAN SIGN)
     * をそれぞれ "\u003C" および "\u003E" にエンコードします
     *
     * @var int
     */
    const HEX_TAG  = 1;

    /**
     * 定数 JSON_HEX_AMP に相当するオプションです.
     * 文字 "&" を "\u0026" にエンコードします.
     *
     * @var int
     */
    const HEX_AMP  = 2;

    /**
     * 定数 JSON_HEX_APOS に相当するオプションです.
     * 文字 "'" を "\u0027" にエンコードします.
     *
     * @var int
     */
    const HEX_APOS = 4;

    /**
     * 定数 JSON_HEX_QUOT に相当するオプションです.
     * 文字 '"' を "\u0022" にエンコードします.
     *
     * @var int
     */
    const HEX_QUOT = 8;

    /**
     * 定数 JSON_FORCE_OBJECT に相当するオプションです.
     * 通常は array 形式でエンコードされる配列を object 形式でエンコードします.
     * 具体的には以下の配列の出力に影響します.
     *
     * - 空の配列
     * - 添字が 0 から始まる整数の連続 (0, 1, 2, ...) となっている配列
     *
     * @var int
     */
    const FORCE_OBJECT = 16;

    /**
     * 定数 JSON_NUMERIC_CHECK に相当するオプションです.
     * 数値表現の文字列を数値としてエンコードします.
     */
    const NUMERIC_CHECK = 32;

    /**
     * 定数 JSON_UNESCAPED_SLASHES に相当するオプションです.
     * エンコードの際に "/" をエスケープしないようにします.
     *
     * @var int
     */
    const UNESCAPED_SLASHES = 64;

    /**
     * 定数 JSON_PRETTY_PRINT に相当するオプションです.
     * object, array 形式の書式でエンコードする際に,
     * 半角スペース 4 個でインデントして整形します.
     *
     * @var int
     */
    const PRETTY_PRINT = 128;

    /**
     * 定数 JSON_UNESCAPED_UNICODE に相当するオプションです.
     * エンコードの際にマルチバイト文字を UTF-8 文字として表現します.
     *
     * @var int
     */
    const UNESCAPED_UNICODE = 256;

    /**
     * 定数 JSON_PRESERVE_ZERO_FRACTION に相当するオプションです.
     * float 型の値を常に float 値としてエンコードします.
     * このオプションが OFF の場合, 小数部が 0 の数値 (2.0 など) は
     * 整数としてエンコードされます.
     *
     * @var int
     */
    const PRESERVE_ZERO_FRACTION = 1024;

    /**
     * {@link http://php.net/manual/function.json-decode.php json_decode()}
     * の第 2 引数に相当する, このクラス独自のオプションです.
     * このオプションが ON の場合, object 形式の値をデコードする際に配列に変換します.
     * (デフォルトでは stdClass オブジェクトとなります)
     *
     * @var int
     */
    const OBJECT_AS_ARRAY = 1;

    /**
     * 定数 JSON_BIGINT_AS_STRING に相当するオプションです.
     * 巨大整数をデコードする際に, int の範囲に収まらない値を文字列に変換します.
     * (デフォルトでは float 型となります)
     *
     * @var int
     */
    const BIGINT_AS_STRING = 2;

    /**
     * encode() の出力内容をカスタマイズするオプションです.
     *
     * @var ArrayMap
     */
    private $encodeOptions;

    /**
     * decode() の出力内容をカスタマイズするオプションです.
     *
     * @var ArrayMap
     */
    private $decodeOptions;

    /**
     * 文字列をエンコードする際に使用する Utf8Codec です.
     *
     * @var Utf8Codec
     */
    private $utf8Codec;

    /**
     * 新しい JsonCodec を構築します.
     * 引数に encode() および decode() の出力のカスタマイズオプションを指定することが出来ます.
     * 引数は配列または整数を指定することが出来ます.
     *
     * - 配列の場合: キーにオプション定数, 値に true または false を指定してください.
     * - 整数の場合: 各オプションのビットマスクを指定してください. 例えば JsonCodec::HEX_TAG | JsonCodec::HEX_AMP のような形式となります.
     *
     * @param array|int $encodeOptions encode() のカスタマイズオプション
     * @param array|int $decodeOptions decode() のカスタマイズオプション
     */
    public function __construct($encodeOptions = null, $decodeOptions = null)
    {
        $this->encodeOptions = $this->initOptions($encodeOptions);
        $this->decodeOptions = $this->initOptions($decodeOptions);
        $this->utf8Codec     = new Utf8Codec();
    }

    /**
     * コンストラクタに指定された $encodeOptions および $decodeOptions
     * を初期化します.
     *
     * @param  array|int $options コンストラクタに指定されたオプション
     * @return ArrayMap           各オプションの ON/OFF をあらわす ArrayMap
     */
    private function initOptions($options)
    {
        $result = new ArrayMap();
        if (is_scalar($options)) {
            return $this->initOptionsByBitMask(Values::intValue($options, 0));
        }
        if (!is_array($options)) {
            return $result;
        }

        foreach ($options as $key => $value) {
            $result->put($key, \Peach\Util\Values::boolValue($value));
        }
        return $result;
    }

    /**
     * ビットマスクを配列に変換します.
     *
     * @param  int      $options オプションをあらわす整数
     * @return ArrayMap          変換後のオプション
     */
    private function initOptionsByBitMask($options)
    {
        $opt    = 1;
        $result = new ArrayMap();
        while ($options) {
            $result->put($opt, (bool) ($options % 2));
            $options >>= 1;
            $opt     <<= 1;
        }
        return $result;
    }

    /**
     * 指定されたエンコード用オプションが ON かどうかを調べます.
     *
     * @param  int $code オプション (定義されている定数)
     * @return bool      指定されたオプションが ON の場合は true, それ以外は false
     */
    public function getEncodeOption($code)
    {
        return $this->encodeOptions->get($code, false);
    }

    /**
     * 指定されたデコード用オプションが ON かどうかを調べます.
     *
     * @param  int $code オプション (定義されている定数)
     * @return bool      指定されたオプションが ON の場合は true, それ以外は false
     */
    public function getDecodeOption($code)
    {
        return $this->decodeOptions->get($code, false);
    }

    /**
     * 指定された JSON 文字列を値に変換します.
     *
     * 引数が空白文字列 (または null, false) の場合は null を返します.
     *
     * @param  string $text 変換対象の JSON 文字列
     * @return mixed        変換結果
     */
    public function decode($text)
    {
        if (Strings::isWhitespace($text)) {
            return null;
        }

        try {
            $root = new Root();
            $root->handle(new Context($text, $this->decodeOptions));
            return $root->getResult();
        } catch (DecodeException $e) {
            throw new InvalidArgumentException($e->getMessage());
        }
    }

    /**
     * 指定された値を JSON 文字列に変換します.
     *
     * @param  mixed  $var 変換対象の値
     * @return string      JSON 文字列
     */
    public function encode($var)
    {
        return $this->encodeValue($var);
    }

    /**
     * encode() の本体の処理です.
     * 指定された値がスカラー型 (null, 真偽値, 数値, 文字列), 配列, オブジェクトのいずれかにも該当しない場合,
     * 文字列にキャストした結果をエンコードします.
     *
     * @param  mixed  $var 変換対象の値
     * @return string      JSON 文字列
     * @ignore
     */
    public function encodeValue($var)
    {
        if ($var === null) {
            return "null";
        }
        if ($var === true) {
            return "true";
        }
        if ($var === false) {
            return "false";
        }
        if (is_float($var)) {
            return $this->encodeFloat($var);
        }
        if (is_integer($var)) {
            return strval($var);
        }
        if (is_string($var)) {
            return is_numeric($var) ? $this->encodeNumeric($var) : $this->encodeString($var);
        }
        if (is_array($var)) {
            return $this->checkKeySequence($var) ? $this->encodeArray($var) : $this->encodeObject($var);
        }
        if (is_object($var)) {
            $arr = (array) $var;
            return $this->encodeValue($arr);
        }

        return $this->encodeValue(Values::stringValue($var));
    }

    /**
     * 数値形式の文字列を数値としてエンコードします.
     *
     * @param string $var
     */
    private function encodeNumeric($var)
    {
        if (!$this->getEncodeOption(self::NUMERIC_CHECK)) {
            return $this->encodeString($var);
        }

        $num = preg_match("/^-?[0-9]+$/", $var) ? intval($var) : floatval($var);
        return $this->encodeValue($num);
    }

    /**
     * float 値を文字列に変換します.
     *
     * @param  float $var 変換対象の float 値
     * @return string     変換結果
     */
    private function encodeFloat($var)
    {
        $str = strval($var);
        if (!$this->getEncodeOption(self::PRESERVE_ZERO_FRACTION)) {
            return $str;
        }
        if (false !== strpos($str, "E")) {
            return $str;
        }
        return (floor($var) === $var) ? "{$str}.0" : $str;
    }

    /**
     * 配列のキーが 0, 1, 2, ……という具合に 0 から始まる整数の連続になっていた場合のみ true,
     * それ以外は false を返します.
     * ただし, オプション FORCE_OBJECT が ON の場合は常に false を返します.
     *
     * @param  array $arr 変換対象の配列
     * @return bool       配列のキーが整数の連続になっていた場合のみ true
     */
    private function checkKeySequence(array $arr) {
        if ($this->getEncodeOption(self::FORCE_OBJECT)) {
            return false;
        }

        $i = 0;
        foreach (array_keys($arr) as $key) {
            if ($i !== $key) {
                return false;
            }
            $i++;
        }
        return true;
    }

    /**
     * 文字列を JSON 文字列に変換します.
     *
     * @param  string $str 変換対象の文字列
     * @return string      JSON 文字列
     * @ignore
     */
    public function encodeString($str)
    {
        $self        = $this;
        $callback    = function ($num) use ($self) {
            return $self->encodeCodePoint($num);
        };
        $unicodeList = $this->utf8Codec->decode($str);
        return '"' . implode("", array_map($callback, $unicodeList)) . '"';
    }

    /**
     * 指定された Unicode 符号点を JSON 文字に変換します.
     *
     * @param  int $num Unicode 符号点
     * @return string   指定された Unicode 符号点に対応する文字列
     * @ignore
     */
    public function encodeCodePoint($num)
    {
        // @codeCoverageIgnoreStart
        static $hexList = array(
            0x3C => self::HEX_TAG,
            0x3E => self::HEX_TAG,
            0x26 => self::HEX_AMP,
            0x27 => self::HEX_APOS,
            0x22 => self::HEX_QUOT,
        );
        static $encodeList = array(
            0x22 => "\\\"",
            0x5C => "\\\\",
            0x08 => "\\b",
            0x0C => "\\f",
            0x0A => "\\n",
            0x0D => "\\r",
            0x09 => "\\t",
        );
        // @codeCoverageIgnoreEnd

        if (array_key_exists($num, $hexList) && $this->getEncodeOption($hexList[$num])) {
            return "\\u00" . strtoupper(dechex($num));
        }
        if (array_key_exists($num, $encodeList)) {
            return $encodeList[$num];
        }
        if ($num === 0x2F) {
            return $this->getEncodeOption(self::UNESCAPED_SLASHES) ? "/" : "\\/";
        }
        if (0x20 <= $num && $num < 0x80) {
            return chr($num);
        }
        if (0x80 <= $num && $this->getEncodeOption(self::UNESCAPED_UNICODE)) {
            return $this->utf8Codec->encode($num);
        }
        return "\\u" . str_pad(dechex($num), 4, "0", STR_PAD_LEFT);
    }

    /**
     * 指定された配列を JSON の array 表記に変換します.
     * オプション PRETTY_PRINT が有効化されている場合,
     * json_encode の JSON_PRETTY_PRINT と同様に半角スペース 4 個と改行文字で整形します.
     *
     * @param  array  $arr 変換対象
     * @return string      JSON 文字列
     */
    private function encodeArray(array $arr)
    {
        $prettyPrintEnabled = $this->getEncodeOption(self::PRETTY_PRINT);

        $indent   = $prettyPrintEnabled ? PHP_EOL . "    " : "";
        $start    = "[" . $indent;
        $end      = $prettyPrintEnabled ? PHP_EOL . "]" : "]";
        $self     = $this;
        $callback = function ($value) use ($self, $prettyPrintEnabled, $indent) {
            $valueResult = $self->encodeValue($value);
            return $prettyPrintEnabled ? str_replace(PHP_EOL, $indent, $valueResult) : $valueResult;
        };
        return $start . implode("," . $indent, array_map($callback, $arr)) . $end;
    }

    /**
     * 指定された配列を JSON の object 表記に変換します.
     * オプション PRETTY_PRINT が有効化されている場合,
     * json_encode の JSON_PRETTY_PRINT と同様に半角スペース 4 個と改行文字で整形します.
     *
     * @param  array  $arr 変換対象
     * @return string      JSON 文字列
     */
    private function encodeObject(array $arr)
    {
        $prettyPrintEnabled = $this->getEncodeOption(self::PRETTY_PRINT);

        $indent   = $prettyPrintEnabled ? PHP_EOL . "    " : "";
        $start    = "{" . $indent;
        $end      = $prettyPrintEnabled ? PHP_EOL . "}" : "}";
        $self     = $this;
        $callback = function ($key, $value) use ($self, $prettyPrintEnabled, $indent) {
            $coron       = $prettyPrintEnabled ? ": " : ":";
            $valueResult = $self->encodeValue($value);
            $valueJson   = $prettyPrintEnabled ? str_replace(PHP_EOL, $indent, $valueResult) : $valueResult;
            return $self->encodeString($key) . $coron . $valueJson;
        };
        return $start . implode("," . $indent, array_map($callback, array_keys($arr), array_values($arr))) . $end;
    }
}


<?php

namespace Dhii\Data\Object;

use ArrayAccess;
use OutOfRangeException;
use Psr\Container\ContainerExceptionInterface;
use stdClass;
use Traversable;
use Exception as RootException;
use InvalidArgumentException;
use Dhii\Util\String\StringableInterface as Stringable;

/**
 * Functionality for data assignment.
 *
 * @since [*next-version*]
 */
trait SetManyCapableTrait
{
    /**
     * Assign data.
     *
     * @since [*next-version*]
     *
     * @param array|stdClass|Traversable $data The data to set. Existing keys will be overwritten.
     *                                         The rest of the data remains unaltered.
     *
     * @throws InvalidArgumentException    If the data map is invalid.
     * @throws OutOfRangeException         If the internal data store one of the data keys to set is invalid.
     * @throws ContainerExceptionInterface If a problem with setting data occurs.
     */
    protected function _setMany($data)
    {
        $data  = $this->_normalizeIterable($data);
        $store = $this->_getDataStore();

        try {
            $this->_containerSetMany($store, $data);
        } catch (InvalidArgumentException $e) {
            throw $this->_createOutOfRangeException($this->__('Invalid store'), null, $e, $store);
        }
    }

    /**
     * Retrieves a pointer to the data store.
     *
     * @since [*next-version*]
     *
     * @return array|ArrayAccess|stdClass The data store.
     */
    abstract protected function _getDataStore();

    /**
     * Sets multiple values on the container.
     *
     * @since [*next-version*]
     *
     * @param array|ArrayAccess|stdClass $container The container to set data on.
     * @param array|Traversable|stdClass $data      The map of data to set on the container.
     *
     * @throws InvalidArgumentException    If the container or the data map is invalid.
     * @throws OutOfRangeException         If one of the data keys is invalid.
     * @throws ContainerExceptionInterface If a problem with setting data occurs.
     */
    abstract protected function _containerSetMany(&$container, $data);

    /**
     * Normalizes an iterable.
     *
     * Makes sure that the return value can be iterated over.
     *
     * @since [*next-version*]
     *
     * @param mixed $iterable The iterable to normalize.
     *
     * @throws InvalidArgumentException If the iterable could not be normalized.
     *
     * @return array|Traversable|stdClass The normalized iterable.
     */
    abstract protected function _normalizeIterable($iterable);

    /**
     * Creates a new Out Of Range exception.
     *
     * @since [*next-version*]
     *
     * @param string|Stringable|null $message  The error message, if any.
     * @param int|null               $code     The error code, if any.
     * @param RootException|null     $previous The inner exception for chaining, if any.
     * @param mixed|null             $argument The value that is out of range, if any.
     *
     * @return OutOfRangeException The new exception.
     */
    abstract protected function _createOutOfRangeException(
        $message = null,
        $code = null,
        RootException $previous = null,
        $argument = null
    );

    /**
     * Translates a string, and replaces placeholders.
     *
     * @since [*next-version*]
     * @see   sprintf()
     *
     * @param string $string  The format string to translate.
     * @param array  $args    Placeholder values to replace in the string.
     * @param mixed  $context The context for translation.
     *
     * @return string The translated string.
     */
    abstract protected function __($string, $args = [], $context = null);
}


<?php
/**
 * Phossa Project
 *
 * PHP version 5.4
 *
 * @category  Library
 * @package   Phossa\Query
 * @author    Hong Zhang <phossa@126.com>
 * @copyright 2015 phossa.com
 * @license   http://mit-license.org/ MIT License
 * @link      http://www.phossa.com/
 */
/*# declare(strict_types=1); */

namespace Phossa\Query\Dialect;

use Phossa\Query\Dialect\DataType;
use Phossa\Query\Dialect\Common\Select;
use Phossa\Query\Dialect\Common\Insert;
use Phossa\Query\Builder\BuilderInterface;
use Phossa\Query\Dialect\Common\SelectStatementInterface;
use Phossa\Query\Dialect\Common\InsertStatementInterface;

/**
 * Standard Query Language dialect
 *
 * @package Phossa\Query
 * @author  Hong Zhang <phossa@126.com>
 * @see     DialectInterface
 * @version 1.0.0
 * @since   1.0.0 added
 */
class Common implements DialectInterface
{
    /**
     * Current dialect string
     *
     * @var    string
     * @access protected
     */
    protected $dialect = 'Common';

    /**
     * quote prefix
     *
     * @var    string
     * @access protected
     */
    protected $quote_prefix = '"';

    /**
     * quote suffix
     *
     * @var    string
     * @access protected
     */
    protected $quote_suffix = '"';

    /**
     * data type conversion
     *
     * @var    array
     * @access protected
     * @staticvar
     */
    protected static $type_conversion = [];

    /**
     * {@inheritDoc}
     */
    public function select(BuilderInterface $builder)/*# : SelectStatementInterface */
    {
        $class = __NAMESPACE__ . '\\' . $this->dialect . '\\Select';
        return new $class($builder);
    }

    /**
     * {@inheritDoc}
     */
    public function insert(BuilderInterface $builder)/*# : InsertStatementInterface */
    {
        $class = __NAMESPACE__ . '\\' . $this->dialect . '\\Insert';
        return new $class($builder);
    }

    /**
     * {@inheritDoc}
     */
    public function update(BuilderInterface $builder)/*# : UpdateStatementInterface */
    {
        $class = __NAMESPACE__ . '\\' . $this->dialect . '\\Update';
        return new $class($builder);
    }

    /**
     * {@inheritDoc}
     */
    public function delete(BuilderInterface $builder)/*# : DeleteStatementInterface */
    {
        $class = __NAMESPACE__ . '\\' . $this->dialect . '\\Delete';
        return new $class($builder);
    }

    /**
     * {@inheritDoc}
     */
    public function create(BuilderInterface $builder)/*# : CreateInterface */
    {
        $class = __NAMESPACE__ . '\\' . $this->dialect . '\\Create';
        return new $class($builder);
    }

    /**
     * {@inheritDoc}
     */
    public function quote(
        /*# string */ $string,
        /*# bool */ $quote = DialectInterface::QUOTE_YES
    )/*# : string */ {
        $pref = $this->quote_prefix;
        $suff = $this->quote_suffix;

        // space found
        if (preg_match("/[ \n(),]/", $string)) {
            // quote it anyway
            if ($quote & DialectInterface::QUOTE_SPACE) {
                return sprintf('%s%s%s', $pref, $string, $suff);

            // abort
            } else {
                return $string;
            }
        }

        if ($quote & DialectInterface::QUOTE_YES) {
            $string = preg_replace_callback(
                '/\b([0-9a-zA-Z\$_]++)\b/',
                function($m) use ($pref, $suff) {
                    return sprintf('%s%s%s', $pref, $m[1], $suff);
                },
                $string
            );
        }
        return $string;
    }

    /**
     * {@inheritDoc}
     */
    public function getType(
        /*# string */ $typeName,
        $attributes = 0
    )/*# : string */ {
        // get type
        if (defined(DataType::getClass() . '::' . $typeName)) {
            $type = constant(DataType::getClass() . '::' . $typeName);
        } else {
            $type = $typeName;
        }

        // get conversion if any
        if (isset(static::$type_conversion[$type])) {
            $type = static::$type_conversion[$type];
        }

        // modify type
        if (0 !== $attributes) {
            $type = $this->typeModification($type, func_get_args());
        }

        return $type;
    }

    /**
     * modify the type
     *
     * @param  string $type
     * @param  array $args
     * @return string
     */
    protected function typeModification(
        /*# string */ $type, array $args
    )/*# : string */ {
        // data size
        if (is_int($args[1])) {
            $type .= '(' . $args[1];
            if (isset($args[2])) {
                $type .= ',' . $args[2];
            }
            $type .= ')';

        // size, zeroFill etc.
        } elseif (is_array($args[1])) {
            if (isset($args[1]['size'])) {
                $type .= '(' . $args[1]['size'] . ')';
            }
            foreach ($args[1] as $key => $val) {
                if ('size' === $key) {
                    continue;
                }
                $type .= ' ' . strtoupper($key);
            }
        } else {
            $type .= $args[1];
        }

        return $type;
    }
}


<?php
/*
 * Copyright (c) 2016 @trashtoy
 * https://github.com/trashtoy/
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/**
 * PHP class file.
 * @auhtor trashtoy
 * @since  2.2.0
 */
namespace Peach\Http\Header;

use InvalidArgumentException;
use Peach\DT\Timestamp;
use Peach\DT\Util;
use Peach\Util\Values;

/**
 * Set-Cookie ヘッダーの各種属性をあらわすクラスです.
 * このクラスのオブジェクトに対する変更は, 関連するすべての CookieItem オブジェクトに影響を与えます.
 */
class CookieOptions
{
    /**
     * expires 属性の時刻をあらわす Timestamp オブジェクトです.
     *
     * @var Timestamp
     */
    private $expires;

    /**
     * このプログラムが扱う時刻のタイムゾーンです.
     * この値が null の場合はデフォルトのタイムゾーンを適用します.
     *
     * @var int
     */
    private $timeZoneOffset;

    /**
     * max-age 属性をあらわす整数です.
     * @var int
     */
    private $maxAge;

    /**
     * domain 属性をあらわす文字列です.
     *
     * @var string
     */
    private $domain;

    /**
     * path 属性をあらわす文字列です.
     *
     * @var string
     */
    private $path;

    /**
     * secure 属性をあらわす論理値です.
     * true の場合のみ secure 属性が付与されます.
     *
     * @var bool
     */
    private $secure;

    /**
     * 属性を何も持たない, 新しい CookieOptions オブジェクトを構築します.
     */
    public function __construct()
    {
        $this->secure = false;
        $this->httpOnly = false;
    }

    /**
     * expires 属性の時刻を設定します.
     * 引数に null を設定した場合は expires 属性を削除します.
     *
     * @param Timestamp $expires Set-Cookie の expires 属性として表現される時刻
     */
    public function setExpires(Timestamp $expires = null)
    {
        $this->expires = $expires;
    }

    /**
     * expires 属性の時刻を返します.
     * expires 属性が設定されていない場合は null を返します.
     *
     * @return Timestamp expires 属性の時刻
     */
    public function getExpires()
    {
        return $this->expires;
    }

    /**
     * このオブジェクトが取り扱う Timestamp オブジェクトの時差を分単位でセットします.
     * このメソッドは expires 属性の出力に影響します.
     * PHP の date.timezone 設定がシステムの時差と異なる場合に使用してください.
     * 通常はこのメソッドを使用する必要はありません.
     *
     * もしも引数に -23:45 (1425) 以上または +23:45 (-1425) 未満の値を指定した場合は
     * -23:45 または +23:45 に丸めた結果を返します.
     *
     * @param int $offset 時差
     * @see   Util::cleanTimeZoneOffset()
     */
    public function setTimeZoneOffset($offset)
    {
        $this->timeZoneOffset = ($offset === null) ? null : Util::cleanTimeZoneOffset($offset);
    }

    /**
     * このオブジェクトが取り扱う Timestamp オブジェクトの時差を返します.
     * このメソッドはデフォルトで null を返します.
     *
     * @return int 時差. ただしデフォルトの場合は null
     */
    public function getTimeZoneOffset()
    {
        return $this->timeZoneOffset;
    }

    /**
     * max-age 属性の値をセットします.
     * 引数に 0 をセットした場合は対象の Cookie がブラウザから削除されます.
     * 引数が 0 未満の値の場合は 0 として扱われます.
     *
     * @param int $maxAge max-age 属性の値
     */
    public function setMaxAge($maxAge)
    {
        $this->maxAge = ($maxAge === null) ? null : Values::intValue($maxAge, 0);
    }

    /**
     * max-age 属性の値を返します.
     * もしも max-age 属性がセットされていない場合は null を返します.
     *
     * @return int max-age 属性の値. セットされていない場合は null
     */
    public function getMaxAge()
    {
        return $this->maxAge;
    }

    /**
     * domain 属性の値をセットします.
     * 引数に null をセットした場合は domain 属性を削除します.
     *
     * @param string $domain domain 属性の値
     */
    public function setDomain($domain)
    {
        if (!$this->validateDomain($domain)) {
            throw new InvalidArgumentException("Invalid domain: '{$domain}'");
        }
        $this->domain = $domain;
    }

    /**
     * 指定された文字列が, ドメイン名として妥当かどうかを確認します.
     * RFC 1035 に基づいて, 引数の文字列が以下の BNF 記法を満たすかどうかを調べます.
     * 妥当な場合は true, そうでない場合は false を返します.
     *
     * ただし, 本来は Invalid にも関わらず実際に使われているドメイン名に対応するため
     * label の先頭の数字文字列を敢えて許す実装となっています.
     *
     *

     * {domain} ::= {subdomain} | " "
     * {subdomain} ::= {label} | {subdomain} "." {label}
     * {label} ::= {letter} [ [ {ldh-str} ] {let-dig} ]
     * {ldh-str} ::= {let-dig-hyp} | {let-dig-hyp} {ldh-str}
     * {let-dig-hyp} ::= {let-dig} | "-"
     * {let-dig} ::= {letter} | {digit}
     *

     *
     * @param  string $domain 検査対象のドメイン名
     * @return bool           引数がドメイン名として妥当な場合のみ true
     */
    private function validateDomain($domain)
    {
        if ($domain === null) {
            return true;
        }
        $letter    = "[a-zA-Z0-9]";
        $letDigHyp = "(-|{$letter})";
        $label     = "{$letter}({$letDigHyp}*{$letter})*";
        $pattern   = "{$label}(\\.{$label})*";
        return preg_match("/\\A{$pattern}\\z/", $domain);
    }

    /**
     * domain 属性の値を返します.
     * domain 属性がセットされていない場合は null を返します.
     *
     * @return string
     */
    public function getDomain()
    {
        return $this->domain;
    }

    /**
     * path 属性の値をセットします.
     * 引数に null をセットした場合は path 属性を削除します.
     *
     * @param string $path
     */
    public function setPath($path)
    {
        if (!$this->validatePath($path)) {
            throw new InvalidArgumentException("Invalid path: '{$path}'");
        }
        $this->path = $path;
    }

    /**
     * 指定された文字列が RFC 3986 にて定義される URI のパス文字列として妥当かどうかを検証します.
     * フォーマットは以下の BNF 記法に基づきます.
     *
     *

     * path-absolute = "/" [ segment-nz *( "/" segment ) ]
     * segment       = *pchar
     * segment-nz    = 1*pchar
     * pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
     * unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
     * pct-encoded   = "%" HEXDIG HEXDIG
     * sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
     *

     *
     * @param  string $path 検査対象のパス
     * @return bool         引数がパスとして妥当な場合のみ true
     */
    private function validatePath($path)
    {
        if ($path === null) {
            return true;
        }

        $classUnreserved = "a-zA-Z0-9\\-\\._~";
        $classSubDelims  = "!\$&'\\(\\)";
        $classOthers     = ":@";
        $validChars      = "[{$classUnreserved}{$classSubDelims}{$classOthers}]";
        $pctEncoded      = "%[0-9a-fA-F]{2}";
        $pchar           = "{$validChars}|{$pctEncoded}";
        $segment         = "({$pchar})*";
        $segmentNz       = "({$pchar})+";
        $pathAbsolute    = "\\/({$segmentNz}(\\/{$segment})*)?";
        return preg_match("/\\A{$pathAbsolute}\\z/", $path);
    }

    /**
     * path 属性の値を返します.
     * もしも path 属性がセットされていない場合は null を返します.
     *
     * @return string path 属性の値. セットされていない場合は null
     */
    public function getPath()
    {
        return $this->path;
    }

    /**
     * secure 属性をセットします.
     * もしも引数が true の場合は secure 属性を有効化, false の場合は無効化します.
     *
     * @param bool $secure secure 属性を有効化する場合は true, 無効化する場合は false
     */
    public function setSecure($secure)
    {
        $this->secure = (bool) $secure;
    }

    /**
     * secure 属性が有効かどうかを判定します.
     * secure 属性が有効な場合は true, そうでない場合は false を返します.
     * もしもこのオブジェクトの setSecure() を一度も実行していない場合,
     * secure 属性は無効となるため false を返します.
     *
     * @return bool secure 属性が有効な場合は true, そうでない場合は false
     */
    public function hasSecure()
    {
        return $this->secure;
    }

    /**
     * httponly 属性をセットします.
     * もしも引数が true の場合は httponly 属性を有効化, false の場合は無効化します.
     *
     * @param bool $httpOnly httponly 属性を有効化する場合は true, 無効化する場合は false
     */
    public function setHttpOnly($httpOnly)
    {
        $this->httpOnly = (bool) $httpOnly;
    }

    /**
     * httponly 属性が有効かどうかを判定します.
     * httponly 属性が有効な場合は true, そうでない場合は false を返します.
     * もしもこのオブジェクトの setHttpOnly() を一度も実行していない場合,
     * httponly 属性は無効となるため false を返します.
     *
     * @return bool httponly 属性が有効な場合は true, そうでない場合は false
     */
    public function hasHttpOnly()
    {
        return $this->httpOnly;
    }

    /**
     * このオブジェクトが持つ各属性を書式化し, 結果を配列で返します.
     *
     * @return array 各属性を書式化した結果の配列
     * @ignore
     * @todo 複数の Set-Cookie ヘッダーで同じオプションを適用することを想定し, 返り値をキャッシュできるようにする
     */
    public function formatOptions()
    {
        $result = array();
        if ($this->expires !== null) {
            $result[] = $this->formatExpires();
        }
        if ($this->maxAge !== null) {
            $result[] = "max-age={$this->maxAge}";
        }
        if ($this->domain !== null) {
            $result[] = "domain={$this->domain}";
        }
        if ($this->path !== null) {
            $result[] = "path={$this->path}";
        }
        if ($this->secure) {
            $result[] = "secure";
        }
        if ($this->httpOnly) {
            $result[] = "httponly";
        }
        return $result;
    }

    /**
     * expires 属性を書式化します.
     *
     * @return string "expires=Wdy, DD-Mon-YY HH:MM:SS GMT" 形式の文字列
     */
    private function formatExpires()
    {
        $format = CookieExpiresFormat::getInstance();
        $offset = Util::cleanTimeZoneOffset($this->timeZoneOffset);
        $date   = $format->format($this->expires, $offset);
        return "expires={$date}";
    }
}


<?php
/**
 * Created by PhpStorm.
 * User: miky
 * Date: 21/08/16
 * Time: 22:40
 */

namespace Miky\Bundle\UserBundle\Controller\Admin;

class ResettingController extends \Sonata\UserBundle\Controller\AdminResettingController
{
    /**
     * {@inheritdoc}
     */
    public function requestAction()
    {
        if ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')) {
            return new RedirectResponse($this->container->get('router')->generate('sonata_admin_dashboard'));
        }
        return $this->container->get('templating')->renderResponse('SonataUserBundle:Admin:Security/Resetting/request.html.' . $this->getEngine(), array(
            'base_template' => $this->container->get('sonata.admin.pool')->getTemplate('layout'),
            'admin_pool' => $this->container->get('sonata.admin.pool'),
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function sendEmailAction()
    {
        $username = $this->container->get('request')->request->get('username');
        /** @var $user UserInterface */
        $user = $this->container->get('fos_user.user_manager')->findUserByUsernameOrEmail($username);
        if (null === $user) {
            return $this->container->get('templating')->renderResponse('SonataUserBundle:Admin:Security/Resetting/request.html.' . $this->getEngine(), array(
                'invalid_username' => $username,
                'base_template' => $this->container->get('sonata.admin.pool')->getTemplate('layout'),
                'admin_pool' => $this->container->get('sonata.admin.pool'),
            ));
        }
        if ($user->isPasswordRequestNonExpired($this->container->getParameter('fos_user.resetting.token_ttl'))) {
            return $this->container->get('templating')->renderResponse('SonataUserBundle:Admin:Security/Resetting/passwordAlreadyRequested.html.' . $this->getEngine(), array(
                'base_template' => $this->container->get('sonata.admin.pool')->getTemplate('layout'),
                'admin_pool' => $this->container->get('sonata.admin.pool'),
            ));
        }
        if (null === $user->getConfirmationToken()) {
            /** @var $tokenGenerator TokenGeneratorInterface */
            $tokenGenerator = $this->container->get('fos_user.util.token_generator');
            $user->setConfirmationToken($tokenGenerator->generateToken());
        }
        $this->container->get('session')->set(static::SESSION_EMAIL, $this->getObfuscatedEmail($user));
        $this->container->get('fos_user.mailer')->sendResettingEmailMessage($user);
        $user->setPasswordRequestedAt(new \DateTime());
        $this->container->get('fos_user.user_manager')->updateUser($user);
        return new RedirectResponse($this->container->get('router')->generate('sonata_user_admin_resetting_check_email'));
    }

    /**
     * {@inheritdoc}
     */
    public function checkEmailAction()
    {
        $session = $this->container->get('session');
        $email = $session->get(static::SESSION_EMAIL);
        $session->remove(static::SESSION_EMAIL);
        if (empty($email)) {
            // the user does not come from the sendEmail action
            return new RedirectResponse($this->container->get('router')->generate('sonata_user_admin_resetting_check_email'));
        }
        return $this->container->get('templating')->renderResponse('SonataUserBundle:Admin:Security/Resetting/checkEmail.html.' . $this->getEngine(), array(
            'email' => $email,
            'base_template' => $this->container->get('sonata.admin.pool')->getTemplate('layout'),
            'admin_pool' => $this->container->get('sonata.admin.pool'),
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function resetAction($token)
    {
        if ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')) {
            return new RedirectResponse($this->container->get('router')->generate('sonata_admin_dashboard'));
        }
        $user = $this->container->get('fos_user.user_manager')->findUserByConfirmationToken($token);
        if (null === $user) {
            throw new NotFoundHttpException(sprintf('The user with "confirmation token" does not exist for value "%s"', $token));
        }
        if (!$user->isPasswordRequestNonExpired($this->container->getParameter('fos_user.resetting.token_ttl'))) {
            return new RedirectResponse($this->container->get('router')->generate('sonata_user_admin_resetting_request'));
        }
        $form = $this->container->get('fos_user.resetting.form');
        $formHandler = $this->container->get('fos_user.resetting.form.handler');
        $process = $formHandler->process($user);
        if ($process) {
            $this->setFlash('fos_user_success', 'resetting.flash.success');
            $response = new RedirectResponse($this->container->get('router')->generate('sonata_admin_dashboard'));
            $this->authenticateUser($user, $response);
            return $response;
        }
        return $this->container->get('templating')->renderResponse('SonataUserBundle:Admin:Security/Resetting/reset.html.' . $this->getEngine(), array(
            'token' => $token,
            'form' => $form->createView(),
            'base_template' => $this->container->get('sonata.admin.pool')->getTemplate('layout'),
            'admin_pool' => $this->container->get('sonata.admin.pool'),
        ));
    }
}


<?php

namespace Asoc\Dadatata\Filter\Jpegoptim;

use Asoc\Dadatata\Exception\ProcessingFailedException;
use Asoc\Dadatata\Filter\FilterInterface;
use Asoc\Dadatata\Filter\OptionsInterface;
use Asoc\Dadatata\Model\ImageInterface;
use Asoc\Dadatata\Model\ThingInterface;
use Symfony\Component\Process\ProcessBuilder;

class Optimize implements FilterInterface
{
    /**
     * @var
     */
    private $bin;
    /**
     * @var OptimizeOptions
     */
    private $defaults;

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

    /**
     * @param OptionsInterface $options
     */
    public function setOptions(OptionsInterface $options)
    {
        if (!($options instanceof OptimizeOptions)) {
            $options = new OptimizeOptions($options->all());
        }
        $this->defaults = $options;
    }

    /**
     * @param ThingInterface                              $thing
     * @param string                                      $sourcePath
     * @param \Asoc\Dadatata\Filter\OptionsInterface|null $options
     *
     * @return array Paths to generated files
     */
    public function process(ThingInterface $thing, $sourcePath, OptionsInterface $options = null)
    {
        // jpegoptim wants a directory
        $tmpPath = sys_get_temp_dir();

        /** @var OptimizeOptions $options */
        $options = $this->defaults->merge($options);

        $pb = new ProcessBuilder([$this->bin]);
        $pb->add('--dest')->add($tmpPath);
        $pb->add('--max')->add($options->getQuality());
        $pb->add('--strip-'.$options->getStrip());

        if ($options->has(OptimizeOptions::OPTION_THRESHOLD)) {
            $pb->add('--threshold')->add($options->getThreshold());
        }

        $pb->add($sourcePath);
        $process = $pb->getProcess();

        $code = $process->run();
        if ($code !== 0) {
            throw ProcessingFailedException::create(
                'Failed to optimize JPEG',
                $code,
                $process->getOutput(),
                $process->getErrorOutput()
            );
        }

        // output directory + name of file
        return [sprintf('%s/%s', $tmpPath, basename($sourcePath))];
    }

    /**
     * @param ThingInterface $thing
     *
     * @return boolean
     */
    public function canHandle(ThingInterface $thing)
    {
        return $thing instanceof ImageInterface;
    }
}


<?php
/**
 * Created by PhpStorm.
 * User: claudio
 * Date: 18-02-16
 * Time: 16:03
 */

namespace AscensoDigital\PerfilBundle\Configuration;

/**
 * Expone configuracion completa o por filtro
 *
 * Class Configurator
 * @package AscensoDigital\ComponentBundle\Configuration
 */
class Configurator
{
    private $config;

    public function __construct(array $config)
    {
        $this->config = $config;
    }

    /**
     * Returns the entire configuration.
     *
     * @return array
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * @param $key
     * @return mixed valor del parametro de configuracion solicitado
     * @throws \InvalidArgumentException cuando no se encuentra definida el parametro solicitado.
     */
    public function getConfiguration($key){
        if(!isset($this->config[$key])) {
            throw new \InvalidArgumentException(sprintf('Parámetro de Configuración "%s" no esta definido',$key));
        }
        return $this->config[$key];
    }

    /**
     * Returns the configuration for the given filtro name.
     *
     * @param string $filtroName
     *
     * @return array The full filtro configuration
     *
     * @throws \InvalidArgumentException when the filtro isn't config
     */
    public function getFiltroConfiguration($filtroName)
    {
        if (!isset($this->config['filtros'][$filtroName])) {
            throw new \InvalidArgumentException(sprintf('Filtro "%s" is not managed.', $filtroName));
        }

        return $this->config['filtros'][$filtroName];
    }

    public function getNavegacionConfiguration($navegacionField){
        if (!isset($this->config['navegacion'][$navegacionField])) {
            throw new \InvalidArgumentException(sprintf('Parametro "%s" no esta definido dentro de la configuración de navegacioó.', $navegacionField));
        }

        return $this->config['navegacion'][$navegacionField];
    }
}


<?php

namespace Peyote;

/**
 * An abstract starting class for the WHERE and HAVING classes.
 *
 * @package    Peyote
 * @author     Dave Widmer <dave@davewidmer.net>
 */
abstract class Condition implements \Peyote\Builder
{
	/**
	 * @var array  The order clauses.
	 */
	protected $clauses = array();

	/**
	 * @var array  A list of bound parameters.
	 */
	protected $params = array();

	/**
	 * Gets the type of sorting query we are running.
	 *
	 * @return string
	 */
	abstract public function getType();

	/**
	 * Gets the list of bound parameters.
	 *
	 * @return array
	 */
	public function getParams()
	{
		return $this->params;
	}

	/**
	 * Compiles the query into raw SQL
	 *
	 * @return  string
	 */
	public function compile()
	{
		if (empty($this->clauses))
		{
			return "";
		}

		$sql = array();
		foreach ($this->clauses as $clause)
		{
			list($type, $column, $op, $value, $isParam) = $clause;
			$sql[] = $type;
			$sql[] = "{$column} {$op}";

			$sql[] = $isParam ? "?" : $value;

			$this->params[] = $value;
		}

		array_shift($sql);

		return $this->getType()." ".join(" ", $sql);
	}

}


<?php
namespace T3v\T3vNavigations\Controller\ContentElements;

use TYPO3\CMS\Core\Utility\GeneralUtility;

use T3v\T3vContent\Controller\ContentElements\ContentElementController;

use T3v\T3vNavigations\Domain\Repository\QuickNavigationItemRepository;

/**
 * The quick navigation content element controller class.
 *
 * @package T3v\T3vNavigations\Controller\ContentElements
 */
class QuickNavigationContentElementController extends ContentElementController {
  /**
   * The quick navigation item repository.
   *
   * @var \T3v\T3vNavigations\Domain\Repository\QuickNavigationItemRepository
   * @inject
   */
  protected $quickNavigationItemRepository;

  /**
   * The index action.
   */
  public function indexAction() {
    $settings = $this->settings;

    $primaryItems     = [];
    $primaryItemsUids = GeneralUtility::intExplode(',', $settings['primaryItems'], true);

    foreach($primaryItemsUids as $uid) {
      $primaryItems[] = $this->quickNavigationItemRepository->findByUid($uid);
    }

    $secondaryItems     = [];
    $secondaryItemsUids = GeneralUtility::intExplode(',', $settings['secondaryItems'], true);

    foreach($secondaryItemsUids as $uid) {
      $secondaryItems[] = $this->quickNavigationItemRepository->findByUid($uid);
    }

    $this->view->assign('settings', $settings);
    $this->view->assign('primaryItems', $primaryItems);
    $this->view->assign('secondaryItems', $secondaryItems);
  }
}


<?php
/*
This is part of Wedeto, the WEb DEvelopment TOolkit.
It is published under the MIT Open Source License.

Copyright 2017, Egbert van der Wal

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

namespace Wedeto\Application\Dispatch;

use Throwable;
use DateTime;

use Wedeto\Util\LoggerAwareStaticTrait;

use Wedeto\Log\MemLogger;

use Wedeto\Resolve\Resolver;

use Wedeto\Util\Hook;
use Wedeto\Util\Dictionary;
use Wedeto\Util\DI\DI;
use Wedeto\Util\Validation\Type;
use Wedeto\Util\Functions as WF;

use Wedeto\HTTP\Accept;
use Wedeto\HTTP\Request;
use Wedeto\HTTP\Processor;
use Wedeto\HTTP\Result;
use Wedeto\HTTP\Responder;
use Wedeto\HTTP\Response\{Response, DataResponse, StringResponse, RedirectRequest};
use Wedeto\HTTP\Response\Error as HTTPError;
use Wedeto\HTTP\StatusCode;
use Wedeto\HTTP\URL;

use Wedeto\HTML\Template;
use Wedeto\HTML\AssetManager;

use Wedeto\IO\FileType;

use Wedeto\I18n\Locale;

use Wedeto\FileFormats\WriterFactory;

use Wedeto\Application\Application;
use Wedeto\Application\FlashMessage;

/**
 * Dispatcher dispatches a HTTP Request to the correct route.
 *
 * It will dispatch the request to the correct app by resolving the route in
 * the configured paths.
 *
 * @generator createFromApplication
 */
class Dispatcher implements Processor
{
    use LoggerAwareStaticTrait;

    /** The site configuration */
    protected $config;

    /** The arguments after the selected route */
    protected $arguments;

    /** The configured sites */
    protected $sites = array();

    /** The selected VirtualHost for this request */
    protected $vhost = null;

    /** The file / asset resolver */
    protected $resolver = null;

    /** The template render engine */
    protected $template = null;

    /** The request being served */
    protected $request;

    /** The resolved route */
    protected $route;

    /** The resolved app */
    protected $app;

    /** The suffix of the resolved route - file extension */
    protected $suffix;

    /** The variables to pass to the app */
    protected $variables = [];

    /**
     * Create the dispatcher.
     *
     * @param Request $request The request to dispatch
     * @param Resolver $resolver The resolve manager able to resolve assets, templates and routes
     * @param Dictionary $config The configuration used for setting up Site and VirtualHost instances
     */
    public function __construct(Request $request, Resolver $resolver, $config = [])
    {
        self::getLogger();

        if (!($config instanceof Dictionary))
            $config = new Dictionary($config);

        $this->setRequest($request);
        $this->setResolver($resolver);
        $this->setConfig($config);
        //$this->getTemplate();
    }

    public function process(Request $request, Result $result)
    {
        $this->setRequest($request);
        $result->setResponse($this->dispatch());

        $session_cookie = $request->session !== null ? $request->session->getCookie() : null;
        if ($session_cookie)
            $result->addCookie($session_cookie);
    }

    /**
     * Create a new dispatcher using an application object
     * @param Application $app The Application object from which to get the required variables
     * @return Dispatcher The dispatcher instance
     */
    public static function createFromApplication(Application $app)
    {
        $dispatch = new static($app->request, $app->resolver, $app->config);
        $dispatch->setApplication($app);
        return $dispatch;
    }

    /**
     * @return Dictionary The configuration used
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Set the configuration dictionary used for config
     * @param Dictionary $config The configuration
     * @return Dispatcher Provides fluent interface
     */
    public function setConfig(Dictionary $config)
    {
        $this->config = $config;
        $this->configureSites();
        $this->setVariable('config', $config);
        return $this;
    }

    /**
     * Configure the sites based on the provided configuration
     *
     * @return Dispatcher Provides fluent interface
     */
    public function configureSites()
    {
        $this->setSites(Site::setupSites($this->config->getSection('site')));
        return $this;
    }

    /**
     * @return array The list of sites
     */
    public function getSites()
    {
        return $this->sites;
    }

    /**
     * Set the list of available sites
     *
     * @param array $sites The list of sites
     * @return Dispatcher Provides fluent interface
     */
    public function setSites(array $sites)
    {
        $this->sites = array();
        foreach ($sites as $site)
            $this->addSite($site);
        return $this;
    }

    /**
     * Add a Site to the dispatcher configuration.
     * @param Site $site The site to add
     * @return Dispatcher Provides fluent interface
     */
    public function addSite(Site $site)
    {
        $this->sites[] = $site;
        return $this;
    }

    /**
     * Set the VirtualHost for this request
     *
     * @param VirtualHost $vhost The VirtualHost matching the request
     * @return Dispatcher Provides fluent interface
     */
    public function setVirtualHost(VirtualHost $vhost)
    {
        $this->vhost = $vhost;
        $this->setVariable('vhost', $vhost);
        return $this;
    }

    /**
     * @return VirtualHost the virtual host matching the request
     */
    public function getVirtualHost()
    {
        if ($this->vhost === null)
            $this->determineVirtualHost();
        return $this->vhost;
    }

    /**
     * @return Dictionary the arguments passed to the script
     */
    public function getArguments()
    {
        return $this->arguments;
    }

    /**
     * @return Wedeto\HTTP\Request the request being served
     */
    public function getRequest()
    {
        return $this->request;
    }

    /**
     * Set the request being handled
     * @param Request $request The request instance
     * @return Dispatcher Provides fluent interface
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;
        $this->app = null;
        $this->vhost = null;
        $this->route = null;
        $this->setVariable('request', $request);
        return $this;
    }

    /**
     * Set the value for a variable
     * @param string $name The name of the variable
     * @param object $value The value to reference to
     * @return Dispatch Provides fluent interface
     */
    public function setVariable(string $name, $value)
    {
        $this->variables[$name] = $value;
        return $this;
    }

    /**
     * @return mixed The value for the variable
     */
    public function getVariable(string $name)
    {
        return $this->variables[$name];
    }

    /**
     * @return Wedeto\Autoload\Resolver The app, template and asset resolver
     */
    public function getResolver()
    {
        return $this->resolver;
    }

    /**
     * Set the resolver used for resolving apps
     * @param Wedeto\Resolve\Resolver The resolver
     * @return Wedeto\HTTP\Request Provides fluent interface
     */
    public function setResolver(Resolver $resolver)
    {
        $this->resolver = $resolver;
        $this->setVariable('resolver', $resolver);
        return $this;
    }

    /**
     * @return Template The template instance
     */
    public function getTemplate()
    {
        if ($this->template === null)
        {
            $asset_manager = new AssetManager($this->resolver->getResolver('assets'));
            $asset_manager->setTidy($this->config->dget('site', 'tidy', false));
            $template = new Template($this->resolver->getResolver('template'), $asset_manager);
            Hook::subscribe('Wedeto.HTTP.Responder.Respond', array($asset_manager, 'executeHook'));

            $vhost = $this->getVirtualHost();
            $template
                ->setAssetManager($asset_manager)
                ->setURLPrefix($vhost->getHost()->path)
                ->assign('request', $this->request)
                ->assign('config', $this->config)
                ->assign('dev', $this->config->dget('site', 'dev', true));

            $this->setTemplate($template);
        }

        return $this->template;
    }

    /**
     * Set the template instance to have apps use.
     * @param Template $template The template to use
     * @return Dispatcher Provides fluent interface
     */
    public function setTemplate(Template $template)
    {
        $this->template = $template;
        $this->setVariable('template', $template);
        $this->setVariable('tpl', $template);
        return $this;
    }

    /**
     * @return string The path to the app to execute
     */
    public function getApp()
    {
        return $this->app;
    }

    /**
     * @return Application The application for which the request is dispatched. Null if none available
     */
    public function getApplication()
    {
        if (!array_key_exists('app', $this->variables['app']))
        {
            $ij = DI::getInjector();
            $app = $ij->hasInstance(Application::class) ? $ij->getInstance(Application::class) : null;
            $this->variables['app'] = $app;
        }
        return $this->variables['app'];
    }

    /**
     * Set the application instance
     * @param Application $app The Application instance
     * @return Dispatcher Provides fluent interface
     */
    public function setApplication(Application $app)
    {
        $this
            ->setVariable('app', $app)
            ->setVariable('path_config', $app->pathConfig)
            ->setVariable('i18n', $app->i18n);

        try
        {
            $this->setVariable('db', $app->db);
        }
        catch (\Wedeto\DB\Exception\ConfigurationException $db)
        {}
        return $this;
    }

    /**
     * @return string The resolved route
     */
    public function getRoute()
    {
        return $this->route;
    }

    /**
     * Run the selected application
     *
     * @return Response The response of the executed script
     */
    public function dispatch()
    {
        $response = null;
        try
        {
            $this->resolveApp();
            $this->getTemplate();
            $this->request->startSession($this->vhost->getHost(), $this->config);
            FlashMessage::setStorage($this->request->session);

            $this->setupLocale();

            if ($this->route === null)
                throw new HTTPError(404, 'Could not resolve ' . $this->url);

            $app = new AppRunner($this->app, $this->arguments);
            $app->setVariables($this->variables);
            $app->setVariable('dispatcher', $this);

            $app->execute();
        }
        catch (Throwable $e)
        {
            if (!($e instanceof Response))
                $e = new HTTPError(500, "Exception of type " . get_class($e) . " thrown: " . $e->getMessage(), null, $e);

            if ($e instanceof HTTPError)
                $this->prepareErrorResponse($e);

            $response = $e;
        }
        return $response;
    }

    /**
     * Prepare error response: to give a better error output,
     * a template must be executed or it must be wrapped in a
     * DataResponse to that it will be JSON or XML-formatted.
     *
     * @param HTTPError $error The error to prepare
     */
    protected function prepareErrorResponse(HTTPError $error)
    {
        $writers = WriterFactory::getAvailableWriters();
        $mime_types = array_keys($writers);

        array_unshift($mime_types, 'text/plain');
        array_unshift($mime_types, 'text/html');
        $preferred_type = $this->request->accept->getBestResponseType($mime_types);

        if ($preferred_type === 'text/html')
        {
            $ex = $error->getPrevious() ?: $error;
            $template = $this->getTemplate();
            $template->assign('exception', $ex);

            $template->setExceptionTemplate($ex);

            $response = $template->renderReturn();

            if ($response instanceof HTTPError)
                $error->setResponse(new StringResponse(WF::str($response), "text/plain"));
            else
                $error->setResponse($response);
        }
        elseif ($preferred_type !== 'text/plain')
        {
            $ex = $error->getPrevious() ?: $error;
            $status = $error->getStatusCode();
            $status_msg = isset(StatusCode::$CODES[$status]) ? StatusCode::$CODES[$status] : "Internal Server Error";
            $exception_str = WF::str($ex);
            $exception_list = explode("\n", $exception_str);
            $data = array(
                'message' => $ex->getMessage(),
                'status_code' => $status,
                'exception' => $exception_list,
                'status' => $status_msg
            );

            $dict = new Dictionary($data);
            $error->setResponse(new DataResponse($dict));
        }
        // text/plain is handled by Error directly
    }

    /**
     * Find out which VirtualHost was targeted and redirect if configuration
     * requests so.
     *
     * @return Dispatcher Provides fluent interface
     * @throws Throwable Various exceptions depending on the configuration -
     *                   Error(404) when the configuration says to prohibit use of
     *                   unknown hosts, RedirectRequest when a redirect to a different
     *                   host is requested, RuntimeException when unexpected things happen.
     */
    public function determineVirtualHost()
    {
        // Determine the proper VirtualHost
        $cfg = $this->config->getSection('site');
        $vhost = self::findVirtualHost($this->request->webroot, $this->sites);
        if ($vhost === null)
        {
            $result = $this->handleUnknownHost($this->request->webroot, $this->request->url, $this->sites, $cfg);

            // Handle according to the outcome
            if ($result === null)
                throw new HTTPError(404, "Not found: " . $this->url);

            if ($result instanceof URL)
                throw new RedirectRequest($result, 301);

            if ($result instanceof VirtualHost)
            {
                $vhost = $result;
                $site = $vhost->getSite();
                if (isset($this->sites[$site->getName()]))
                    $this->sites[$site->getName()] = $site;
            }
            else
                throw \RuntimeException("Unexpected response from handleUnknownWebsite");
        }
        else
        {
            // Check if the VirtualHost we matched wants to redirect somewhere else
            $target = $vhost->getRedirect($this->request->url);
            if ($target)
                throw new RedirectRequest($target, 301);

        }
        $this->setVirtualHost($vhost);
        return $this;
    }

    /**
     * Set up the language / locale based on the users preferences and the
     * provided locales by the virtual host.
     *
     * When neither the user or the virtual host specifies any locale,
     * the default is maintained.
     */
    public function setupLocale()
    {
        // The virtual host may prescribe a language
        if (isset($this->variables['i18n']))
        {
            $vhost = $this->vhost;
            $locales = $vhost->getLocales();
            $session = $this->request->session;
            $locale = null;

            if ($session !== null && $session->has('locale', Type::STRING))
            {
                $locval = $session['locale'];
                foreach ($locales as $supported_locale)
                {
                    if ($locval === $supported_locale->getLocale())
                    {
                        $locale = $locval;
                        self::$logger->debug("Set language based on session variable to {0}", [$locale]);
                        break;
                    }
                }
            }

            if ($locale === null && !empty($locales))
            {
                $accept = $this->request->accept_language;
                $locale = $vhost->selectLocaleFromAcceptHeader($accept);

                if ($locale === null)
                {
                    $locale = reset($locales);
                    self::$logger->debug("Set language based on default locale {0}", [$locale]);
                }
                else
                {
                    self::$logger->debug("Set language based on HTTP request headers to {0}", [$locale]);
                }

                if ($session !== null)
                    $session->set('locale', $locale);
            }

            if (!empty($locale))
                $this->variables['i18n']->setLocale($locale);
        }
    }

    /**
     * Resolve the app to run based on the incoming URL
     */
    public function resolveApp()
    {
        // Determine the correct vhost first
        $this->determineVirtualHost();

        // Resolve the application to start
        $path = $this->vhost->getPath($this->request->url);

        $resolved = $this->resolver->resolve("app", $path);

        if ($resolved !== null)
        {
            if ($resolved['ext'])
            {
                $mime = new FileType($resolved['ext'], "");
                if (!empty($mime))
                {
                    $str = $mime->getMimeType() . ";q=1.5," . (string)$this->request->accept;
                    $this->request->setAccept(new Accept($str));
                }
                $this->suffix = $resolved['ext'];
            }
            $this->route = $resolved['route'];
            $this->app = $resolved['path'];
            $this->arguments = new Dictionary($resolved['remainder']);
        }
        else
        {
            $this->route = null;
            $this->app = null;
            $this->arguments = new Dictionary();
        }
    }

    /**
     * Find the VirtualHost matching the provided URL.
     * @param URL $url The URL to match
     * @param array $sites A list of Site objects from which the correct
     *                     VirtualHost should be extracted.
     * @return VirtualHost The correct VirtualHost. Null if not found.
     */
    public static function findVirtualHost(URL $url, array $sites)
    {
        foreach ($sites as $site)
        {
            $vhost = $site->match($url);
            if ($vhost !== null)
                return $vhost;
        }
        return null;
    }

    /**
     * Determine what to do when a request was made to an unknown host.
     *
     * The default configuration is IGNORE, which means that a new vhost will be
     * generated on the fly and attached to the site of the closest matching VirtualHost.
     * If no site is configured either, a new Site named 'defaul't is created and the new
     * VirtualHost is attached to that site. This makes configuration non-required for
     * simple sites with one site and one hostname.
     *
     * @param URL $webroot The webroot where a request was made
     * @param URL $url The URL that was requested
     * @param array $sites The configured sites
     * @param Dictionary $cfg The configuration to get the policy from
     * @return mixed One of:
     *               * null: if the policy is to error out on unknown hosts
     *               * URI: if the policy is to redirect to the closest matching host
     *               * VirtualHost: if the policy is to ignore / accept unknown hosts
     */
    public static function handleUnknownHost(URL $webroot, URL $request, array $sites, Dictionary $cfg)
    {
        // Determine behaviour on unknown host
        $on_unknown = strtoupper($cfg->dget('unknown_host_policy', "IGNORE"));
        $best_matching = self::findBestMatching($webroot, $sites);

        if ($on_unknown === "ERROR" || ($best_matching === null && $on_unknown === "REDIRECT"))
            return null;

        if ($on_unknown === "REDIRECT")
        {
            $redir = $best_matching->URL($request->path);
            return $redir;
        }

        // Generate a proper VirtualHost on the fly
        $url = new URL($webroot);
        $url->fragment = null;
        $url->query = null;
        $lang = $cfg->dget('default_language', 'en');
        $vhost = new VirtualHost($url, $lang);

        // Add the new virtualhost to a site.
        if ($best_matching === null)
        {
            // If no site has been defined, create a new one
            $site = new Site();
            $site->addVirtualHost($vhost);
        }
        else
            $best_matching->getSite()->addVirtualHost($vhost);

        return $vhost;
    }

    /**
     * Find the best matching VirtualHost. In case the URL used does not
     * match any defined VirtualHost, this function will find the VirtualHost
     * that matches the URL as close as possible, in an attempt to guess at
     * which information the visitor is interested.
     *
     * @param URL $url The URL that was requested
     * @param array $sites The configured sites
     * @return VirtualHost The best matching VirtualHost in text similarity.
     */
    public static function findBestMatching(URL $url, array $sites)
    {
        $vhosts = array();
        foreach ($sites as $site)
            foreach ($site->getVirtualHosts() as $vhost)
                $vhosts[] = $vhost;

        // Remove query and fragments from the URL in use
        $my_url = new URL($url);
        $my_url->set('query', null)->set('fragment', null)->toString();

        // Match the visited URL with all vhosts and calcualte their textual similarity
        $best_percentage = 0;
        $best_idx = null;
        foreach ($vhosts as $idx => $vhost)
        {
            $host = $vhost->getHost()->toString();
            similar_text($my_url, $host, $percentage);
            if ($best_idx === null || $percentage > $best_percentage)
            {
                $best_idx = $idx;
                $best_percentage = $percentage;
            }
        }

        // Return the best match, or null if none was found.
        if ($best_idx === null)
            return null;
        return $vhosts[$best_idx];
    }

    /**
     * Return a value
     * @param string $key The name of the variable
     * @return mixed The value, or null if not existent
     */
    public function __get(string $key)
    {
        return property_exists($this, $key) ? $this->$key : null;
    }
}


<?php

namespace Orchid\Log\Utilities;

use Illuminate\Contracts\Config\Repository as ConfigContract;
use Orchid\Log\Contracts\Utilities\LogMenu as LogMenuContract;
use Orchid\Log\Contracts\Utilities\LogStyler as LogStylerContract;
use Orchid\Log\Entities\Log;

class LogMenu implements LogMenuContract
{
    /**
     * The config repository instance.
     *
     * @var \Illuminate\Contracts\Config\Repository
     */
    protected $config;

    /**
     * The log styler instance.
     *
     * @var \Orchid\Log\Contracts\Utilities\LogStyler
     */
    private $styler;

    /**
     * LogMenu constructor.
     *
     * @param \Illuminate\Contracts\Config\Repository   $config
     * @param \Orchid\Log\Contracts\Utilities\LogStyler $styler
     */
    public function __construct(ConfigContract $config, LogStylerContract $styler)
    {
        $this->setConfig($config);
        $this->setLogStyler($styler);
    }

    /**
     * Set the config instance.
     *
     * @param \Illuminate\Contracts\Config\Repository $config
     *
     * @return \Orchid\Log\Utilities\LogMenu
     */
    public function setConfig(ConfigContract $config)
    {
        $this->config = $config;

        return $this;
    }

    /**
     * Set the log styler instance.
     *
     * @param \Orchid\Log\Contracts\Utilities\LogStyler $styler
     *
     * @return \Orchid\Log\Utilities\LogMenu
     */
    public function setLogStyler(LogStylerContract $styler)
    {
        $this->styler = $styler;

        return $this;
    }

    /**
     * Make log menu.
     *
     * @param \Orchid\Log\Entities\Log $log
     * @param bool                     $trans
     *
     * @return array
     */
    public function make(Log $log, $trans = true)
    {
        $items = [];
        $route = 'dashboard.systems.logs.show'; //$this->config('menu.filter-route');

        foreach ($log->tree($trans) as $level => $item) {
            $items[$level] = array_merge($item, [
                'url'  => route($route, [$log->date, $level]),
                'icon' => $this->styler->icon($level) ?: '',
            ]);
        }

        return $items;
    }
}


<?php

namespace Sirius\Bus\Traits;

use Sirius\Bus\PendingDispatch;
use function Sirius\Support\collect;
use function Sirius\Support\tap;

trait Queueable
{
    /**
     * The name of the connection the job should be sent to.
     *
     * @var string|null
     */
    public $connection;

    /**
     * The name of the queue the job should be sent to.
     *
     * @var string|null
     */
    public $queue;

    /**
     * The number of seconds before the job should be made available.
     *
     * @var \DateTimeInterface|\DateInterval|int|null
     */
    public $delay;

    /**
     * The jobs that should run if this job is successful.
     *
     * @var array
     */
    public $chained = [];

    /**
     * Set the desired connection for the job.
     *
     * @param  string|null  $connection
     * @return $this
     */
    public function onConnection($connection)
    {
        $this->connection = $connection;

        return $this;
    }

    /**
     * Set the desired queue for the job.
     *
     * @param  string|null  $queue
     * @return $this
     */
    public function onQueue($queue)
    {
        $this->queue = $queue;

        return $this;
    }

    /**
     * Set the desired delay for the job.
     *
     * @param  \DateTimeInterface|\DateInterval|int|null  $delay
     * @return $this
     */
    public function delay($delay)
    {
        $this->delay = $delay;

        return $this;
    }

    /**
     * Set the jobs that should run if this job is successful.
     *
     * @param  array  $chain
     * @return $this
     */
    public function chain($chain)
    {
        $this->chained = collect($chain)->map(function ($job) {
            return serialize($job);
        })->all();

        return $this;
    }

    /**
     * Dispatch the next job on the chain.
     *
     * @return void
     */
    public function dispatchNextJobInChain()
    {
        if (! empty($this->chained)) {
          new PendingDispatch(tap(unserialize(array_shift($this->chained)), function ($next) {
                $next->chained = $this->chained;
            }));
        }
    }
}


<?php
/*
This is part of Wedeto, the WEb DEvelopment TOolkit.
It is published under the MIT Open Source License.

Copyright 2018, Egbert van der Wal

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

namespace Wedeto\Application\Plugins;

use Wedeto\Util\DI\BasicFactory;

use Wedeto\Application\Application;

use Wedeto\Log\Logger;

use Wedeto\I18n\I18n;
use Wedeto\I18n\I18nShortcut;
use Wedeto\I18n\Translator\TranslationLogger;

/**
 * Plugin that enables I18n setup for Wedeto
 */
class I18nPlugin implements WedetoPlugin
{
    private $app;

    public function initialize(Application $app)
    {
        $this->app = $app;
        $app->injector->registerFactory(I18n::class, new BasicFactory([$this, "createI18n"]));
    }

    /**
     * Factory method to create the I18n instance. Registered with Wedeto\DI to
     * make sure that new instances are created here.
     */
    public function createI18n(array $args)
    {
        $i18n = new I18n;
        I18nShortcut::setInstance($i18n);

        // Add all module paths to the I18n object
        $modules = $this->app->resolver->getResolver("language");
        $log = \Wedeto\Log\Logger::getLogger(I18nPlugin::class);

        $search_path = $modules->getSearchPath();
        foreach ($search_path as $name => $path)
        {
            $i18n->registerTextDomain($name, $path);
        }

        // Set a language
        $site_language = $this->app->config->dget('site', 'default_language', 'en');
        $locale = $args['locale'] ?? $site_language;
        $i18n->setLocale($locale);

        $this->setupTranslateLog();

        return $i18n;
    }

    /**
     * Set up a logger that stores untranslated messages to a separate pot file.
     */
    private function setupTranslateLog()
    {
        $logger = Logger::getLogger('Wedeto.I18n.Translator.Translator');
        $writer = new TranslationLogger($this->app->pathConfig->log . '/translate-%s-%s.pot');
        $logger->addLogWriter($writer);
    }
}