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

/**
 * @see Zend_Filter_Interface
 */

/**
 * @category   Zend
 * @package    Zend_Filter
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Filter_StringToLower implements Zend_Filter_Interface
{
    /**
     * Encoding for the input string
     *
     * @var string
     */
    protected $_encoding = null;

    /**
     * Constructor
     *
     * @param string|array|Zend_Config $options OPTIONAL
     */
    public function __construct($options = null)
    {
        if ($options instanceof Zend_Config) {
            $options = $options->toArray();
        } else if (!is_array($options)) {
            $options = func_get_args();
            $temp    = array();
            if (!empty($options)) {
                $temp['encoding'] = array_shift($options);
            }
            $options = $temp;
        }

        if (!array_key_exists('encoding', $options) && function_exists('mb_internal_encoding')) {
            $options['encoding'] = mb_internal_encoding();
        }

        if (array_key_exists('encoding', $options)) {
            $this->setEncoding($options['encoding']);
        }
    }

    /**
     * Returns the set encoding
     *
     * @return string
     */
    public function getEncoding()
    {
        return $this->_encoding;
    }

    /**
     * Set the input encoding for the given string
     *
     * @param  string $encoding
     * @return Zend_Filter_StringToLower Provides a fluent interface
     * @throws Zend_Filter_Exception
     */
    public function setEncoding($encoding = null)
    {
        if ($encoding !== null) {
            if (!function_exists('mb_strtolower')) {

                throw new Zend_Filter_Exception('mbstring is required for this feature');
            }

            $encoding = (string) $encoding;
            if (!in_array(strtolower($encoding), array_map('strtolower', mb_list_encodings()))) {

                throw new Zend_Filter_Exception("The given encoding '$encoding' is not supported by mbstring");
            }
        }

        $this->_encoding = $encoding;
        return $this;
    }

    /**
     * Defined by Zend_Filter_Interface
     *
     * Returns the string $value, converting characters to lowercase as necessary
     *
     * @param  string $value
     * @return string
     */
    public function filter($value)
    {
        if ($this->_encoding !== null) {
            return mb_strtolower((string) $value, $this->_encoding);
        }

        return strtolower((string) $value);
    }
}


<?php

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

namespace Valkyrja\Path;

use InvalidArgumentException;
use Valkyrja\Application;
use Valkyrja\Support\Providers\Provides;

/**
 * Class PathParser.
 *
 * @author Melech Mizrachi
 */
class NativePathParser implements PathParser
{
    use Provides;

    /**
     * The variable regex.
     *
     * @var string
     */
    protected const VARIABLE_REGEX = <<<'REGEX'
\{
    \s* ([a-zA-Z_][a-zA-Z0-9_-]*) \s*
    (?:
        : \s* ([^{}]*(?:\{(?-1)\}[^{}]*)*)
    )?
\}
REGEX;

    /**
     * Parse a path and get its parts.
     *
     * @param string $path The path
     *
     * @throws \InvalidArgumentException
     *
     * @return array
     */
    public function parse(string $path): array
    {
        // Validate the path for opening and closing tags
        $this->validatePath($path);

        // Split on [ while skipping placeholders
        $segments = $this->getSegments($path);

        // The current path
        $current = '';

        // Iterate through the segments
        foreach ($segments as $key => $segment) {
            // If this is not the first segment then its an optional group
            if ($key > 0) {
                // Add a non capturing group around this segment
                // NOTE: Since the path was originally split into segments on [
                // it is safe to do this as there SHOULD be a closing bracket
                // before another required group and so there shouldn't
                // be any conflicts in mismatching opening  and closing
                // regex non-capture groups. This assumes the
                // developer did their job correctly in
                // the amount of opening required
                // and optional groups
                $segment = '(?:' . $segment;
            }

            // Check for any non-capturing groups within <> or <*>
            // < > groups are normal non-capturing groups
            // < *> groups are repeatable non-capturing groups
            // NOTE: have to use an alias to avoid breaking @Annotations() usage
            // Replace any end brackets with the appropriate group close
            // NOTE: This will take care of missing end brackets in
            // previous groups because the only way that occurs
            // is when a group is nested within another
            $segment = str_replace(
                [
                    // Opening non-capture required group
                    '<',
                    // Close non-capture repeatable required group
                    '*>',
                    // Close non-capture required group
                    '>',
                    // Close non-capture repeatable optional group
                    '*]',
                    // Close non-capture optional group
                    ']',
                ],
                [
                    // Non-capture required group regex open
                    '(?:',
                    // Non-capture required repeatable group regex close
                    ')*',
                    // Non-capture required group regex close
                    ')',
                    // Non-capture repeatable optional group regex close
                    ')*?',
                    // Non-capture optional group regex close
                    ')?',
                ],
                $segment
            );

            $current .= $segment;
        }

        return $this->parsePath($current, $segments);
    }

    /**
     * Validate a path's opening and closing tags.
     *
     * @param string $path The path
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    protected function validatePath(string $path): void
    {
        // The number of opening required non-capture groups <
        $requiredGroupsOpen = substr_count($path, '<');
        // The number of closing required non-capture groups >
        $requiredGroupsClose = substr_count($path, '>');
        // The number of opening optional non-capture groups [
        $optionalGroupsOpen = substr_count($path, '[');
        // The number of closing optional non-capture groups ]
        $optionalGroupsClose = substr_count($path, ']');

        // If the count of required opening and closing tags doesn't match
        if ($requiredGroupsOpen !== $requiredGroupsClose) {
            // Throw an error letting the develop know they made a bad path
            throw new InvalidArgumentException(
                'Mismatch of required groups for path: ' . $path
            );
        }

        // If the count of optional opening and closing tags doesn't match
        if ($optionalGroupsOpen !== $optionalGroupsClose) {
            // Throw an error letting the develop know they made a bad path
            throw new InvalidArgumentException(
                'Mismatch of optional groups for path: ' . $path
            );
        }
    }

    /**
     * Get a path's segments.
     *
     * @param string $path The path
     *
     * @return array
     */
    protected function getSegments(string $path): array
    {
        return preg_split(
            '~' . static::VARIABLE_REGEX . '(*SKIP)(*F) | \[~x',
            $path
        );
    }

    /**
     * Split segments based on ending bracket within the segments.
     *
     * @param array  $segments    The segments
     * @param string $deliminator The deliminator
     *
     * @return array
     */
    protected function splitSegments(array $segments, string $deliminator): array
    {
        // The final segments to return
        $returnSegments = [];

        // Iterate through the segments once more
        foreach ($segments as $segment) {
            // If the segment has the deliminator
            if (strpos($segment, $deliminator) !== false) {
                $this->splitSegmentsDeliminator(
                    $returnSegments,
                    $segment,
                    $deliminator
                );

                continue;
            }

            // Otherwise set the segment normally
            $returnSegments[] = $segment;
        }

        return $returnSegments;
    }

    /**
     * Split a segment by deliminator (recursive).
     *
     * @param array  $segments    The segments
     * @param string $segment     The segment
     * @param string $deliminator The deliminator
     *
     * @return void
     */
    protected function splitSegmentsDeliminator(array &$segments, string $segment, string $deliminator): void
    {
        // Split the segment on that bracket
        $parts = explode($deliminator, $segment);

        // Iterate through the parts
        foreach ($parts as $part) {
            if (! $part) {
                continue;
            }

            // If the segment has the deliminator
            if (strpos($part, $deliminator) !== false) {
                $this->splitSegmentsDeliminator($segments, $part, $deliminator);

                continue;
            }

            // Setting each part individually
            $segments[] = $part;
        }
    }

    /**
     * Parse a path with no optionals.
     *
     * @param string $path     The path
     * @param array  $segments The segments
     *
     * @return array
     */
    protected function parsePath(string $path, array &$segments): array
    {
        /* @var array[] $params */
        // Get all matches for {paramName} and {paramName:regex} in the path
        preg_match_all(
            '/' . static::VARIABLE_REGEX . '/x',
            $path,
            $params
        );
        $regex        = $path;
        $paramsReturn = [];

        // Run through all matches
        foreach ($params[0] as $key => $param) {
            // Undo replacements made in parse foreach loop (see line 85)
            [$params[0][$key], $params[2][$key]] = str_replace(
                [')*?', ')?'],
                ['*]', ']'],
                [$params[0][$key], $params[2][$key]]
            );
            // Get the regex for this param
            $paramRegex = $this->getParamReplacement($key, $params);
            // Replace the matches with a regex
            $regex = str_replace($param, $paramRegex, $regex);
            // What to replace in the segment for this item
            $replace = '{' . $params[1][$key] . '}';

            // Set the param in the array of params to return
            $paramsReturn[$params[1][$key]] = [
                'replace' => $replace,
                'regex'   => $paramRegex,
            ];

            // Iterate through the segments
            foreach ($segments as $segmentKey => $segment) {
                // Replace this match with the replace text thus removing any regex
                // in the segment this fixes any regex with brackets from being
                // messed up in the splitSegments() method
                $segments[$segmentKey] = str_replace(
                    $params[0][$key],
                    $replace,
                    $segment
                );
            }
        }

        $regex = str_replace('/', '\/', $regex);
        $regex = '/^' . $regex . '$/';

        $segmentsReturn = $this->splitSegments($segments, ']');
        $segmentsReturn = $this->splitSegments($segmentsReturn, '<');
        $segmentsReturn = $this->splitSegments($segmentsReturn, '>');

        return [
            'regex'    => $regex,
            'params'   => $paramsReturn,
            'segments' => $segmentsReturn,
        ];
    }

    /**
     * Get a param's replacement.
     *
     * @param string $key    The key
     * @param array  $params The params
     *
     * @return string
     */
    protected function getParamReplacement(string $key, array $params): string
    {
        return config()['app']['pathRegexMap'][$params[2][$key]]
            ?? '(' . ($params[2][$key] ?: $params[1][$key]) . ')';
    }

    /**
     * The items provided by this provider.
     *
     * @return array
     */
    public static function provides(): array
    {
        return [
            PathParser::class,
        ];
    }

    /**
     * Publish the provider.
     *
     * @param Application $app The application
     *
     * @return void
     */
    public static function publish(Application $app): void
    {
        $app->container()->singleton(
            PathParser::class,
            new static()
        );
    }
}


<?php

namespace Sinpe\Cache;

/**
 * Class CacheableTrait.
 *
 * @see   http://www.sinpe.com/
 *
 * @author Sinpe, Inc.
 * @author 18222544@qq.com
 */
trait CacheableTrait
{
    /**
     * 缓存管理器.
     *
     * @var ManagerInterface
     */
    protected static $cacheManager;

    /**
     * The number of seconds.
     *
     * @var null|false|int
     */
    protected $ttl = 60;

    /**
     * 设置缓存管理器，可选调用.
     */
    public static function setCacheManager(ManagerInterface $cache)
    {
        static::$cacheManager = $cache;
    }

    /**
     * 获取缓存管理器.
     */
    public function getCacheManager()
    {
        return static::$cacheManager;
    }

    /**
     * Cache a value in the model's cache collection.
     *
     * @param $key
     * @param Closure $value
     * @param $ttl
     *
     * @return mixed
     */
    public function cache($key, \Closure $value, $ttl = null)
    {
        // $value可以是callable或是值
        if (static::$cacheManager) {
            if (!static::$cacheManager->getAssistant()) {
                static::$cacheManager = static::$cacheManager->withTags(get_class($this));
            }

            return static::$cacheManager->remember(
                $key,
                $value,
                $ttl ?: $this->ttl
            );
        } else {
            return $value();
        }
    }

    /**
     * Flush the model's cache.
     *
     * @return $this
     */
    public static function flushCache()
    {
        // $value可以是callable或是值
        if (static::$cacheManager) {
            if (!static::$cacheManager->getAssistant()) {
                static::$cacheManager = static::$cacheManager->withTags(get_called_class());
            }

            static::$cacheManager->getAssistant()->flushCache();
        }
    }
}


<?php

namespace Reaction\Db\Conditions;

use Reaction\Db\Expressions\ExpressionBuilderInterface;
use Reaction\Db\Expressions\ExpressionBuilderTrait;
use Reaction\Db\Expressions\ExpressionInterface;
use Reaction\Db\Query;
use Reaction\Helpers\ArrayHelper;

/**
 * Class HashConditionBuilder builds objects of [[HashCondition]]
 */
class HashConditionBuilder implements ExpressionBuilderInterface
{
    use ExpressionBuilderTrait;

    /**
     * Method builds the raw SQL from the $expression that will not be additionally
     * escaped or quoted.
     *
     * @param HashCondition $expression the expression to be built.
     * @param array $params the binding parameters.
     * @return string the raw SQL that will not be additionally escaped or quoted.
     */
    public function build($expression, array &$params = [])
    {
        $hash = $expression->getHash();
        $parts = [];
        foreach ($hash as $column => $value) {
            if (ArrayHelper::isTraversable($value) || $value instanceof Query) {
                // IN condition
                $parts[] = $this->queryBuilder->buildCondition(new InCondition($column, 'IN', $value), $params);
            } else {
                if (strpos($column, '(') === false) {
                    $column = $this->queryBuilder->db->quoteColumnName($column);
                }
                if ($value === null) {
                    $parts[] = "$column IS NULL";
                } elseif ($value instanceof ExpressionInterface) {
                    $parts[] = "$column=" . $this->queryBuilder->buildExpression($value, $params);
                } else {
                    $phName = $this->queryBuilder->bindParam($value, $params);
                    $parts[] = "$column=$phName";
                }
            }
        }

        return count($parts) === 1 ? $parts[0] : '(' . implode(') AND (', $parts) . ')';
    }
}


<?php namespace RestGalleries\Http\Guzzle;

use RestGalleries\Http\Response;

/**
 * Specific http client (as response object) based on Guzzle Client.
 */
class GuzzleResponse extends Response
{
    /**
     * Receives the Http client response, it is processed and stores it into the object properties.
     *
     * @param  \Guzzle\Http\Client $raw
     * @return void
     */
    protected function processResponseData($raw)
    {
        $this->body = $raw->getBody()->__toString();
        $rawHeaders = $raw->getHeaders();

        foreach ($rawHeaders as $key => $value) {
            $this->headers[$key] = implode(', ', $value);
        }

        $this->statusCode = $raw->getStatusCode();

    }

}


<?php namespace Vaccuum\Dispatcher\Traits;

use ReflectionMethod;
use Vaccuum\Contracts\Dispatcher\DispatcherException;

trait TMethodInvocation
{
    /**
     * Invoke object method using arguments.
     *
     * @param array  $arguments
     * @param string $action
     * @param object $object
     *
     * @throws DispatcherException
     * @return mixed
     */
    protected function invokeMethod(array $arguments, $action, $object)
    {
        if (!method_exists($object, $action))
        {
            $message = get_class($object) . " object has no {$action} method.";
            throw new DispatcherException($message);
        }

        $reflection = new ReflectionMethod($object, $action);
        $parameters = [];

        foreach ($reflection->getParameters() as $parameter)
        {
            if (isset($arguments[$parameter->name]))
            {
                $parameters[] = $arguments[$parameter->name];
            }
            elseif ($parameter->isDefaultValueAvailable())
            {
                $parameters[] = $parameter->getDefaultValue();
            }
            else
            {
                $message = "{$parameter->name} argument cannot be resolved.";
                throw new DispatcherException($message, $arguments, $action, $object);
            }
        }

        return $reflection->invokeArgs($object, $parameters);
    }
}


<?php
namespace Core\Toolbox\IO;

/**
 * Sendfile.php
 *
 * @author Michael "Tekkla" Zorn <tekkla@tekkla.de>
 * @copyright 2016-2017
 * @license MIT
 */
class Sendfile extends AbstractFile
{
    use GetMimeTypeTrait;

    /**
     * Files content type
     *
     * @var string
     */
    private $content_type = '';

    /**
     * Send inline flag
     *
     * @var bool
     */
    private $inline = false;

    /**
     * Optional name of file to send
     *
     * @var string
     */
    private $name = '';

    /**
     * Download rate limiter
     *
     * @var int
     */
    private $download_rate = 0;

    /**
     * Header stack
     *
     * @var array
     */
    private $headers = [];

    /**
     * Returns content type of file
     *
     * Tries to autodetect content type when no type is set.
     *
     * @return string
     */
    public function getContentType(): string
    {
        if (empty($this->content_type) && !empty($this->file)) {
            $this->content_type = $this->getMimeType($this->file);
        }

        return $this->content_type;
    }

    /**
     * Sets content type of file
     *
     * @param string $content_type
     *            The content type of file
     */
    public function setContentType(string $content_type)
    {
        $this->content_type = $content_type;
    }

    /**
     * Returns files content disposition flag
     *
     * @return bool
     */
    public function getInline(): bool
    {
        return $this->inline;
    }

    /**
     * Set files content disposition flag
     *
     * @param bool $inline
     *            Flags file disposal type
     */
    public function setInline(bool $inline)
    {
        $this->inline = $inline;
    }

    /**
     * Returns set invidual filename
     *
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * Set name of download
     *
     * @param string $name
     */
    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * Returns donwload rate of the file
     *
     * @return int
     */
    public function getDownloadRate(): int
    {
        return $this->download_rate;
    }

    /**
     * Sets the download rate for this file
     *
     * @param int $download_rate
     *            Positive int as download rate for this file
     */
    public function setDownloadRate(int $download_rate)
    {
        if ($download_rate > 0) {
            $this->download_rate = $download_rate;
        }
    }

    /**
     * Adds a header
     *
     * @param string $header
     */
    public function addHeader(string $header)
    {
        $this->headers[] = $header;
    }

    /**
     * Adds a stack of headers
     *
     * @param array $headers
     */
    public function addHeaders(array $headers)
    {
        foreach ($headers as $header) {
            $this->addHeader($header);
        }
    }

    /**
     * Sends file to browser
     */
    public function send()
    {
        if (!file_exists($this->filename)) {

            $error = sprintf('File "%s" not found.');

            if (isset($this->logger)) {
                $this->logger->critical($error);
            }

            Throw new FileException($error);
        }

        // No content type provided?
        if (empty($this->content_type)) {
            $this->content_type = $this->getMimeType($this->filename);
        }

        // Do we have to find out the filename by our own?
        if (empty($this->name)) {
            $this->name = basename($this->filename);
        }

        // Send headers
        $this->addHeaders([
            'Content-type: ' . $this->content_type,
            'Content-Disposition: ' . $this->inline ? 'inline' : 'attachement' . '; filename="' . $this->name . '"',
            'Content-Transfer-Encoding: binary',
            'Content-Length: ' . filesize($this->filename),
            'Accept-Ranges: bytes'
        ]);

        foreach ($this->headers as $header) {
            header($header);
        }

        // Clean buffer!
        ob_clean();
        flush();

        if ($this->download_rate > 0) {

            // Open file
            $stream = fopen($this->filename, "r");

            while (!feof($stream)) {

                // Send current file part to the browser
                print fread($stream, round($this->download_rate * 1024));

                // Flush content to the browser
                flush();

                // Sleep one second
                sleep(1);
            }
            fclose($this->filename);
        }
        else {
            readfile($this->filename);
        }

        exit();
    }
}


<?php

namespace Reaction\Web\Sessions;

use React\EventLoop\LoopInterface;
use React\EventLoop\Timer\TimerInterface;
use Reaction\Helpers\VarDumper;
use Reaction\Promise\ExtendedPromiseInterface;
use Reaction\Base\Component;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Exceptions\SessionException;
use Reaction\RequestApplicationInterface;
use function Reaction\Promise\resolve;

/**
 * Class SessionHandlerAbstract
 * @package Reaction\Web\Sessions
 */
abstract class SessionHandlerAbstract extends Component implements SessionHandlerInterface
{
    /**
     * @var LoopInterface Event loop instance
     */
    public $loop;
    /**
     * @var integer Session lifetime in seconds for garbage collector.
     * After that time GC will remove data from storage and archive it for '$sessionLifetime' seconds
     * @see $gcArchiveLifetime
     */
    public $gcLifetime = 3600;
    /**
     * @var integer Session lifetime in seconds (default 1 day).
     * Time for archive session life from where it can be restored
     */
    public $gcArchiveLifetime = 86400;
    /**
     * @var integer GC timer interval in seconds
     */
    public $timerInterval = 30;
    /**
     * @var bool Whenever do not use internal garbage collector
     */
    public $useExternalGc = false;
    /**
     * @var SessionArchiveInterface|array|string
     */
    public $archive;

    /** @var TimerInterface Timer for GC */
    protected $_timer;
    /** @var bool Flag that garbage collector not finished his work */
    protected $_gcIsRunning = false;

    /**
     * @inheritdoc
     * @throws InvalidConfigException
     * @throws SessionException
     */
    public function init()
    {
        if (is_string($this->archive) || is_array($this->archive)) {
            $this->archive = \Reaction::create($this->archive);
        } elseif (!$this->archive instanceof SessionArchiveInterface) {
            $message = sprintf("Property `archive` must be set with instance of `%s` or configuration array|string", SessionArchiveInterface::class);
            throw new SessionException($message);
        }
        if (!$this->useExternalGc) {
            $this->createGcTimer();
        }
        parent::init();
    }

    /**
     * Read session data and returns serialized|encoded data
     * @param string $id
     * @return ExtendedPromiseInterface  with session data
     */
    abstract public function read($id);

    /**
     * Write session data to storage
     * @param string $id
     * @param array  $data
     * @return ExtendedPromiseInterface  with session data
     */
    abstract public function write($id, $data);

    /**
     * Destroy a session
     * @param string $id The session ID being destroyed.
     * @param bool   $archiveRemove Remove data from archive or no
     * @return ExtendedPromiseInterface  with bool when finished
     */
    abstract public function destroy($id, $archiveRemove = false);

    /**
     * Regenerate session id
     * @param string                      $idOld
     * @param RequestApplicationInterface $app
     * @param bool                        $deleteOldSession
     * @return ExtendedPromiseInterface  with new session ID (string)
     */
    public function regenerateId($idOld, RequestApplicationInterface $app, $deleteOldSession = false)
    {
        $self = $this;
        $dataOld = [];
        $promise = $this->read($idOld)->then(
            function($data) { return $data; },
            function() { return []; }
        )->then(function($data) use ($idOld, &$dataOld) {
            $dataOld = $data;
            return $this->destroy($idOld)->then(null, function() { return true; });
        })->then(
            function() use ($self, &$app) {
                return $self->createId($app);
            }
        )->then(
            function($newId) use ($self, &$dataOld, $deleteOldSession) {
                $retCallback = function() use ($newId) { return $newId; };
                $dataNew = $deleteOldSession ? [] : $dataOld;
                return $self->write($newId, $dataNew)->then($retCallback, $retCallback);
            },
            function() use ($idOld) {
                $message = sprintf('Failed to regenerate session ID for session "%s"', $idOld);
                throw new SessionException($message);
            }
        );
        return $promise;
    }

    /**
     * Cleanup old sessions. Timer callback.
     * Sessions that have not updated for the last '$this->gcLifetime' seconds will be archived.
     * Sessions in archive with age bigger than '$this->sessionLifetime' seconds will be removed.
     * @see $gcLifetime
     * @see $gcArchiveLifetime
     * @return void
     */
    abstract public function gc();

    /**
     * Return a new session ID
     * @param RequestApplicationInterface $app
     * @return ExtendedPromiseInterface  with session ID valid for session handler
     */
    public function createId(RequestApplicationInterface $app)
    {
        $ip = $app->reqHelper->getRemoteIP();
        if (empty($ip)) {
            $ip = '127.0.0.1';
        }
        $time = microtime();
        try {
            $rand = \Reaction::$app->security->generateRandomString(16);
        } catch (\Exception $exception) {
            $rand = mt_rand(11111, 99999);
        }
        $id = md5($ip . ':' . $time . ':' . $rand);
        $self = $this;
        return $this->checkSessionId($id)->then(
            function() use($id) { return $id; },
            function() use ($self, &$app) { return $self->createId($app); }
        );
    }

    /**
     * Update timestamp of a session
     * @param string $id The session id
     * @param string $data
     * The encoded session data. This data is the
     * result of the PHP internally encoding
     * the $_SESSION superglobal to a serialized
     * string and passing it as this parameter.
     * @return ExtendedPromiseInterface  with bool when finished
     */
    abstract public function updateTimestamp($id, $data);

    /**
     * Check session id for uniqueness
     * @param string $sessionId
     * @return ExtendedPromiseInterface
     */
    public function checkSessionId($sessionId)
    {
        return resolve(true);
    }

    /**
     * Serialize session data to string
     * @param array $data
     * @return string
     */
    public function serializeData($data)
    {
        return VarDumper::serialize($data);
    }

    /**
     * Unserialize session data from string
     * @param string $dataSerialized
     * @return array
     */
    public function unserializeData($dataSerialized)
    {
        return VarDumper::unserialize($dataSerialized);
    }

    /**
     * Create GC periodic timer
     */
    protected function createGcTimer()
    {
        if (isset($this->_timer) && $this->_timer instanceof TimerInterface) {
            $this->loop->cancelTimer($this->_timer);
        }
        $this->_timer = $this->loop->addPeriodicTimer($this->timerInterval, [$this, 'gc']);
    }
}


<?php

namespace Ekyna\Bundle\CoreBundle\Modal;

use Ekyna\Component\Table\TableView;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Class Modal
 * @package Ekyna\Bundle\CoreBundle\Modal
 * @author Étienne Dauvergne <contact@ekyna.com>
 * @see http://nakupanda.github.io/bootstrap3-dialog/#available-options
 */
class Modal
{
    const TYPE_DEFAULT = 'type-default';
    const TYPE_INFO    = 'type-info';
    const TYPE_PRIMARY = 'type-primary';
    const TYPE_SUCCESS = 'type-success';
    const TYPE_WARNING = 'type-warning';
    const TYPE_DANGER  = 'type-danger';

    const SIZE_NORMAL  = 'size-normal';
    const SIZE_SMALL   = 'size-small';
    const SIZE_WIDE    = 'size-wide';    // size-wide is equal to modal-lg
    const SIZE_LARGE   = 'size-large';

    /**
     * @var OptionsResolver
     */
    static protected $buttonOptionsResolver;

    /**
     * @var string
     */
    protected $type = self::TYPE_DEFAULT;

    /**
     * @var string
     */
    protected $size = self::SIZE_WIDE;

    /**
     * @var string
     */
    protected $title;

    /**
     * @var mixed
     */
    protected $content;

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

    /**
     * @var string
     */
    protected $contentType;

    /**
     * @var array
     */
    protected $buttons;

    /**
     * Constructor.
     *
     * @param string $title
     * @param mixed  $content
     * @param array  $buttons
     */
    public function __construct($title = null, $content = null, array $buttons = [])
    {
        $this->setTitle($title);
        $this->setContent($content);
        $this->setButtons($buttons);
    }

    /**
     * Sets the type.
     *
     * @param string $type
     * @return Modal
     */
    public function setType($type)
    {
        static::validateType($type);

        $this->type = $type;
        return $this;
    }

    /**
     * Sets the size.
     *
     * @param string $size
     * @return Modal
     */
    public function setSize($size)
    {
        static::validateSize($size);

        $this->size = $size;
        return $this;
    }

    /**
     * Sets the title.
     *
     * @param string $title
     * @return Modal
     */
    public function setTitle($title)
    {
        $this->title = $title;
        return $this;
    }

    /**
     * Returns the title.
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * Sets the content.
     *
     * @param mixed $content
     * @return Modal
     */
    public function setContent($content)
    {
        if ($content instanceof FormView) {
            $this->contentType = 'form';
        } elseif ($content instanceof TableView) {
            $this->contentType = 'table';
        } elseif (is_array($content)) {
            $this->contentType = 'data';
        } else {
            $this->contentType = 'html';
        }
        $this->content = $content;
        return $this;
    }

    /**
     * Returns the content.
     *
     * @return mixed
     */
    public function getContent()
    {
        return $this->content;
    }

    /**
     * Sets the vars.
     *
     * @param array $vars
     * @return Modal
     */
    public function setVars(array $vars)
    {
        $this->vars = $vars;
        return $this;
    }

    /**
     * Returns the vars.
     *
     * @return array
     */
    public function getVars()
    {
        return $this->vars;
    }

    /**
     * Returns the contentType.
     *
     * @return string
     */
    public function getContentType()
    {
        return $this->contentType;
    }

    /**
     * Sets the buttons.
     *
     * @param array $buttons
     * @return Modal
     */
    public function setButtons(array $buttons)
    {
        $resolver = static::getButtonOptionsResolver();
        $tmp = [];
        foreach ($buttons as $options) {
            $tmp[] = $resolver->resolve($options);
        }
        $this->buttons = $tmp;
        return $this;
    }

    /**
     * Adds the button.
     *
     * @param array $options
     * @param bool $prepend
     * @return Modal
     */
    public function addButton(array $options, $prepend = false)
    {
        $resolver = static::getButtonOptionsResolver();
        $options = $resolver->resolve($options);
        if ($prepend) {
            array_unshift($this->buttons, $options);
        } else {
            array_push($this->buttons, $options);
        }
        return $this;
    }

    /**
     * Returns the buttons.
     *
     * @return array
     */
    public function getButtons()
    {
        return $this->buttons;
    }

    /**
     * Returns the buttons.
     *
     * @return array
     */
    public function getConfig()
    {
        return [
            'size' => $this->size,
            'type' => $this->type,
        ];
    }

    /**
     * Returns the button options resolver.
     *
     * @return OptionsResolver
     */
    static protected function getButtonOptionsResolver()
    {
        if (null === static::$buttonOptionsResolver) {
            static::$buttonOptionsResolver = new OptionsResolver();
            static::$buttonOptionsResolver
                ->setDefaults([
                    'id'       => null,
                    'icon'     => null,
                    'label'    => null,
                    'autospin' => null,
                    'cssClass' => 'btn-default',
                    'hotkey'   => null,
                ])
                ->setAllowedTypes('id',       'string')
                ->setAllowedTypes('icon',     ['null', 'string'])
                ->setAllowedTypes('label',    'string')
                ->setAllowedTypes('autospin', ['null', 'bool'])
                ->setAllowedTypes('cssClass', 'string')
                ->setAllowedTypes('hotkey',   ['null', 'int'])
            ;
        }
        return static::$buttonOptionsResolver;
    }

    /**
     * Validates the modal type.
     *
     * @param string $type
     * @param bool $throwException
     * @return bool
     * @throws \InvalidArgumentException
     */
    static public function validateType($type, $throwException = true)
    {
        if (in_array($type, [
            self::TYPE_DEFAULT,
            self::TYPE_INFO,
            self::TYPE_PRIMARY,
            self::TYPE_SUCCESS,
            self::TYPE_WARNING,
            self::TYPE_DANGER,
        ])) {
            return true;
        }

        if ($throwException) {
            throw new \InvalidArgumentException(sprintf('Invalid modal type "%s".', $type));
        }

        return false;
    }

    /**
     * Validates the modal size.
     *
     * @param string $size
     * @param bool $throwException
     * @return bool
     * @throws \InvalidArgumentException
     */
    static public function validateSize($size, $throwException = true)
    {
        if (in_array($size, [
            self::SIZE_NORMAL,
            self::SIZE_SMALL,
            self::SIZE_WIDE,
            self::SIZE_LARGE,
        ])) {
            return true;
        }

        if ($throwException) {
            throw new \InvalidArgumentException(sprintf('Invalid modal size "%s".', $size));
        }

        return false;
    }
}


<?php

/**
 * Jin Framework
 * Diatem
 */

namespace Jin2\Form\Components;

/**
 * Composant <input type="radio">
 */
class Radio extends AbstractComponent
{

  /**
   * @var array   Valeurs des cases.
   */
  protected $values = array();

  /**
   * Implémente la fonction AbstractComponent::getType()
   *
   * @return string
   */
  public static function getType()
  {
    return 'radio';
  }

  /**
   * Rendu du composant
   *
   * @return type
   */
  public function render()
  {
    $itemHtml = static::getAssetContent('radioitem');

    $addContent = '';
    foreach ($this->values as $v) {
      $ac = $itemHtml;
      $ac = str_replace('%name%', $this->getName().'', $ac);
      $ac = str_replace('%item_label%', $v['label'], $ac);
      $ac = str_replace('%item_value%', $v['value'], $ac);
      $ac = str_replace('%uid%', uniqid(), $ac);
      $selected = '';

      $val = $this->getValue();
      if ($val == $v['value']) {
        $selected = 'checked="checked" ';
      }

      $ac = str_replace('%item_selected%', $selected, $ac);
      $addContent .= $ac;
    }
    $addContent = parent::replaceMagicFields($addContent);

    $html = parent::render();
    $html = str_replace('%items%', $addContent, $html);
    return $html;
  }

  /**
   * Ajoute une case à cocher
   *
   * @param string $value Valeur du choix
   * @param string $label (optional) Label affiché (Par défaut la valeur)
   */
  public function addValue($value, $label = null)
  {
    if (!$label) {
      $label = $value;
    }
    $this->values[] = array('value' => $value, 'label' => $label);
  }

  /**
   * Définit l'ensemble des données des cases à cocher
   *
   * @param array $values  Tableau associatif de la forme array(array('label'=>'','value'=>''),...)
   * @throws \Exception
   */
  public function setValues($values)
  {
    $vc = count($values);
    for ($i = 0; $i < $vc; $i++) {
      if (!isset($values[$i]['value']) || !isset($values[$i]['label'])) {
        throw new \Exception('Tableau de données non correct. Les clés value et label doivent être définis pour chaque ligne du tableau de données');
      }
    }
    $this->values = $values;
  }

  /**
   * Définit une datasource permettant de définir des valeurs au radio
   *
   * @param type $queryResult
   * @param type $colNameForLabel
   * @param type $colNameForValue
   */
  public function setDataSource($queryResult, $colNameForLabel, $colNameForValue)
  {
    foreach ($queryResult as $v) {
      $this->values[] = array('value' => $v[$colNameForValue], 'label' => $v[$colNameForLabel]);
    }
  }

}


<?php

namespace Jjanvier\Library\Crowdin\Application;

use Jjanvier\Library\Crowdin\Command\Api\DirectoryAddCommand;
use Jjanvier\Library\Crowdin\Command\Api\DirectoryDeleteCommand;
use Jjanvier\Library\Crowdin\Command\Api\DownloadCommand;
use Jjanvier\Library\Crowdin\Command\Api\ExportCommand;
use Jjanvier\Library\Crowdin\Command\Api\FileAddCommand;
use Jjanvier\Library\Crowdin\Command\Api\FileDeleteCommand;
use Jjanvier\Library\Crowdin\Command\Api\FileUpdateCommand;
use Jjanvier\Library\Crowdin\Command\Api\StatusCommand;
use Jjanvier\Library\Crowdin\Command\Api\UploadTranslationCommand;
use Jjanvier\Library\Crowdin\Command\DownSyncCommand;
use Jjanvier\Library\Crowdin\Command\ExtractCommand;
use Jjanvier\Library\Crowdin\Command\UpSyncCommand;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class Application extends BaseApplication implements ContainerAwareInterface
{
    /** @var ContainerInterface */
    private $container;

    /**
     * {@inheritdoc]
     */
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    /**
     * @return ContainerInterface
     */
    public function getContainer()
    {
        return $this->container;
    }

    /**
     * Register crowdin commands in the application.
     */
    public function registerCommands()
    {
        $this->add(new DirectoryAddCommand());
        $this->add(new DirectoryDeleteCommand());
        $this->add(new DownloadCommand());
        $this->add(new ExportCommand());
        $this->add(new FileAddCommand());
        $this->add(new FileDeleteCommand());
        $this->add(new FileUpdateCommand());
        $this->add(new StatusCommand());
        $this->add(new UploadTranslationCommand());
        $this->add(new DownSyncCommand());
        $this->add(new ExtractCommand());
        $this->add(new UpSyncCommand());
    }
}