<?php
/**
 * This file is part of Berlioz framework.
 *
 * @license   https://opensource.org/licenses/MIT MIT License
 * @copyright 2017 Ronan GIRON
 * @author    Ronan GIRON <https://github.com/ElGigi>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code, to the root.
 */

declare(strict_types=1);

namespace Berlioz\Http\Message;

use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\StreamInterface;

abstract class Message implements MessageInterface
{
    /** @var string Protocol version */
    protected $protocolVersion;
    /** @var string[][] Headers */
    protected $headers;
    /** @var \Psr\Http\Message\StreamInterface Body */
    protected $body;
    /** @var null|array|object Parsed body */
    protected $parsedBody;
    /** @var callable[] Body parser */
    protected static $bodyParser = [];

    /**
     * Retrieves the HTTP protocol version as a string.
     *
     * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
     *
     * @return string HTTP protocol version.
     */
    public function getProtocolVersion()
    {
        return $this->protocolVersion ?? '1.1';
    }

    /**
     * Return an instance with the specified HTTP protocol version.
     *
     * The version string MUST contain only the HTTP version number (e.g.,
     * "1.1", "1.0").
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * new protocol version.
     *
     * @param string $version HTTP protocol version
     *
     * @return static
     */
    public function withProtocolVersion($version)
    {
        $clone = clone $this;
        $clone->protocolVersion = $version;

        return $clone;
    }

    /**
     * Retrieves all message header values.
     *
     * The keys represent the header name as it will be sent over the wire, and
     * each value is an array of strings associated with the header.
     *
     *     // Represent the headers as a string
     *     foreach ($message->getHeaders() as $name => $values) {
     *         echo $name . ": " . implode(", ", $values);
     *     }
     *
     *     // Emit headers iteratively:
     *     foreach ($message->getHeaders() as $name => $values) {
     *         foreach ($values as $value) {
     *             header(sprintf('%s: %s', $name, $value), false);
     *         }
     *     }
     *
     * While header names are not case-sensitive, getHeaders() will preserve the
     * exact case in which headers were originally specified.
     *
     * @return string[][] Returns an associative array of the message's headers. Each
     *     key MUST be a header name, and each value MUST be an array of strings
     *     for that header.
     */
    public function getHeaders()
    {
        return $this->headers ?? [];
    }

    /**
     * Checks if a header exists by the given case-insensitive name.
     *
     * @param string $name Case-insensitive header field name.
     *
     * @return bool Returns true if any header names match the given header
     *     name using a case-insensitive string comparison. Returns false if
     *     no matching header name is found in the message.
     */
    public function hasHeader($name)
    {
        $name = mb_convert_case($name, MB_CASE_TITLE);

        return isset($this->headers[$name]);
    }

    /**
     * Retrieves a message header value by the given case-insensitive name.
     *
     * This method returns an array of all the header values of the given
     * case-insensitive header name.
     *
     * If the header does not appear in the message, this method MUST return an
     * empty array.
     *
     * @param string $name Case-insensitive header field name.
     *
     * @return string[] An array of string values as provided for the given
     *    header. If the header does not appear in the message, this method MUST
     *    return an empty array.
     */
    public function getHeader($name)
    {
        $name = mb_convert_case($name, MB_CASE_TITLE);

        return $this->headers[$name] ?? [];
    }

    /**
     * Retrieves a comma-separated string of the values for a single header.
     *
     * This method returns all of the header values of the given
     * case-insensitive header name as a string concatenated together using
     * a comma.
     *
     * NOTE: Not all header values may be appropriately represented using
     * comma concatenation. For such headers, use getHeader() instead
     * and supply your own delimiter when concatenating.
     *
     * If the header does not appear in the message, this method MUST return
     * an empty string.
     *
     * @param string $name Case-insensitive header field name.
     *
     * @return string A string of values as provided for the given header
     *    concatenated together using a comma. If the header does not appear in
     *    the message, this method MUST return an empty string.
     */
    public function getHeaderLine($name)
    {
        $name = mb_convert_case($name, MB_CASE_TITLE);

        return isset($this->headers[$name]) ? implode(', ', $this->headers[$name]) : '';
    }

    /**
     * Return an instance with the provided value replacing the specified header.
     *
     * While header names are case-insensitive, the casing of the header will
     * be preserved by this function, and returned from getHeaders().
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * new and/or updated header and value.
     *
     * @param string          $name  Case-insensitive header field name.
     * @param string|string[] $value Header value(s).
     *
     * @return static
     * @throws \InvalidArgumentException for invalid header names or values.
     */
    public function withHeader($name, $value)
    {
        return $this->withHeaders([$name => $value]);
    }

    /**
     * Return an instance with the provided value replacing the specified headers.
     *
     * While header names are case-insensitive, the casing of the header will
     * be preserved by this function, and returned from getHeaders().
     *
     * @param string[] $headers Headers.
     *
     * @return static
     */
    public function withHeaders(array $headers)
    {
        $clone = clone $this;
        $clone->setHeaders($headers);

        return $clone;
    }

    /**
     * Set headers.
     *
     * @param string[] $headers Headers.
     *
     * @return static
     */
    protected function setHeaders(array $headers): MessageInterface
    {
        foreach ($headers as $name => $value) {
            $name = mb_convert_case($name, MB_CASE_TITLE);
            $this->headers[$name] = (array) $value;
        }

        return $this;
    }

    /**
     * Return an instance with the specified header appended with the given value.
     *
     * Existing values for the specified header will be maintained. The new
     * value(s) will be appended to the existing list. If the header did not
     * exist previously, it will be added.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * new header and/or value.
     *
     * @param string          $name  Case-insensitive header field name to add.
     * @param string|string[] $value Header value(s).
     *
     * @return static
     * @throws \InvalidArgumentException for invalid header names or values.
     */
    public function withAddedHeader($name, $value)
    {
        $clone = clone $this;
        $name = mb_convert_case($name, MB_CASE_TITLE);
        $clone->headers[$name] = array_merge($clone->headers[$name] ?? [], (array) $value);

        return $clone;
    }

    /**
     * Return an instance without the specified header.
     *
     * Header resolution MUST be done without case-sensitivity.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that removes
     * the named header.
     *
     * @param string $name Case-insensitive header field name to remove.
     *
     * @return static
     */
    public function withoutHeader($name)
    {
        $clone = clone $this;
        $name = mb_convert_case($name, MB_CASE_TITLE);
        unset($clone->headers[$name]);

        return $clone;
    }

    /**
     * Gets the body of the message.
     *
     * @return StreamInterface Returns the body as a stream.
     */
    public function getBody()
    {
        if (is_null($this->body)) {
            $this->body = new Stream();
        }

        return $this->body;
    }

    /**
     * Return an instance with the specified message body.
     *
     * The body MUST be a StreamInterface object.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return a new instance that has the
     * new body stream.
     *
     * @param StreamInterface $body Body.
     *
     * @return static
     * @throws \InvalidArgumentException When the body is not valid.
     */
    public function withBody(StreamInterface $body)
    {
        $clone = clone $this;
        $clone->body = $body;

        return $clone;
    }

    /**
     * Retrieve any parameters provided in the request body.
     *
     * If the request Content-Type is either application/x-www-form-urlencoded
     * or multipart/form-data, and the request method is POST, this method MUST
     * return the contents of $_POST.
     *
     * Otherwise, this method may return any results of deserializing
     * the request body content; as parsing returns structured content, the
     * potential types MUST be arrays or objects only. A null value indicates
     * the absence of body content.
     *
     * @return null|array|object The deserialized body parameters, if any.
     *     These will typically be an array or object.
     */
    public function getParsedBody()
    {
        if (is_null($this->parsedBody)) {
            $contentType = $this->getHeader('Content-Type');

            if (!empty($contentType)) {
                $contentType = explode(';', reset($contentType));
                $contentType = $contentType[0];
                $contentType = explode('/', $contentType, 2);
                $contentType[1] = explode('+', $contentType[1]);
                $contentType = $contentType[0] . '/' . $contentType[1][count($contentType[1]) - 1];

                if (isset(self::$bodyParser[$contentType]) && is_callable(self::$bodyParser[$contentType])) {
                    $bodyParser = self::$bodyParser[$contentType];
                    $parsedBody = $bodyParser((string) $this->getBody());
                } else {
                    switch ($contentType) {
                        case 'application/x-www-form-urlencoded':
                            $parsedBody = [];
                            parse_str((string) $this->getBody(), $parsedBody);
                            break;
                        case 'multipart/form-data':
                            $parsedBody = $_POST;
                            break;
                        case 'application/json':
                            $parsedBody = json_decode((string) $this->getBody());
                            break;
                        default:
                            $parsedBody = null;
                    }
                }

                if (!is_null($parsedBody) && !is_array($parsedBody) && !is_object($parsedBody)) {
                    throw new \RuntimeException('Parsed body must be an array or an object or must be null.');
                } else {
                    $this->parsedBody = $parsedBody;
                }
            }
        }

        return $this->parsedBody;
    }

    /**
     * Return an instance with the specified body parameters.
     *
     * These MAY be injected during instantiation.
     *
     * If the request Content-Type is either application/x-www-form-urlencoded
     * or multipart/form-data, and the request method is POST, use this method
     * ONLY to inject the contents of $_POST.
     *
     * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
     * deserializing the request body content. Deserialization/parsing returns
     * structured data, and, as such, this method ONLY accepts arrays or objects,
     * or a null value if nothing was available to parse.
     *
     * As an example, if content negotiation determines that the request data
     * is a JSON payload, this method could be used to create a request
     * instance with the deserialized parameters.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * updated body parameters.
     *
     * @param null|array|object $data The deserialized body data. This will
     *                                typically be in an array or object.
     *
     * @return static
     * @throws \InvalidArgumentException if an unsupported argument type is
     *     provided.
     */
    public function withParsedBody($data)
    {
        $clone = clone $this;
        $clone->parsedBody = $data;

        return $clone;
    }

    /**
     * Add body parser
     *
     * @param string|string[] $mime     Body     parser
     * @param callable        $callable Callable parser
     */
    public static function addBodyParser($mime, callable $callable)
    {
        foreach ((array) $mime as $aMime) {
            self::$bodyParser[$aMime] = $callable;
        }
    }
}


<?php

/**
 * This file is part of slick/http
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Slick\Http\Message\Server;

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use Slick\Http\Message\Exception\InvalidArgumentException;
use Slick\Http\Message\Request as HttpRequest;
use Slick\Http\Message\Stream\TextStream;
use Slick\Http\Message\Uri;

/**
 * Request
 *
 * @package Slick\Http\Message\Server
*/
class Request extends HttpRequest implements ServerRequestInterface
{

    /**
     * @var array
     */
    private $server;

    /**
     * @var array
     */
    private $cookies;

    /**
     * @var array
     */
    private $queryParams;

    /**
     * @var UploadedFile[]
     */
    private $uploadedFiles;

    /**
     * @var mixed
     */
    private $parsedBody;

    /**
     * @var array
     */
    private $attributes = [];

    /**
     * Creates an HTTP Server Request Message
     *
     * @param string                   $method
     * @param string|StreamInterface   $body
     * @param null|string|UriInterface $target
     * @param array                    $headers
     */
    public function __construct($method = null, $target = null, $body = null, array $headers = [])
    {
        $method = null === $method
            ? $this->getServerParams()['REQUEST_METHOD']
            : $method;

        $body = null === $body
            ? $this->getPhpInputStream()
            : $body;

        parent::__construct($method, $target, $body, $headers);
        $this->loadHeaders();

        $this->setUri(RequestUriFactory::create($this));
    }

    /**
     * Retrieve server parameters.
     *
     * Retrieves data related to the incoming request environment,
     * typically derived from PHP's $_SERVER super-global.
     *
     * @return array
     */
    public function getServerParams()
    {
        if (! $this->server) {
            $this->server = $_SERVER;
        }
        return $this->server;
    }

    /**
     * Retrieve cookies.
     *
     * Retrieves cookies sent by the client to the server.
     *
     * @return array
     */
    public function getCookieParams()
    {
        if (! $this->cookies) {
            $this->cookies = $_COOKIE;
        }
        return $this->cookies;
    }

    /**
     * Return an instance with the specified cookies.
     *
     * @param array $cookies Array of key/value pairs representing cookies.
     * @return Request
     */
    public function withCookieParams(array $cookies)
    {
        $request = clone $this;
        $request->cookies = $cookies;
        return $request;
    }

    /**
     * Retrieve query string arguments.
     *
     * Retrieves the deserialized query string arguments, if any.
     *
     * @return array
     */
    public function getQueryParams()
    {
        if (! $this->queryParams) {
            $this->queryParams = $this->detectQueryParams();
        }
        return $this->queryParams;
    }

    /**
     * Return an instance with the specified query string arguments.
     *
     * @param array $query Array of query string arguments, typically from
     *     $_GET.
     *
     * @return Request
     */
    public function withQueryParams(array $query)
    {
        $request = clone $this;
        $request->queryParams = $query;
        return $request;
    }

    /**
     * Retrieve normalized file upload data.
     *
     * @return UploadedFile[]
     */
    public function getUploadedFiles()
    {
        if (null === $this->uploadedFiles) {
            $this->uploadedFiles = UploadedFilesFactory::createFiles();
        }
        return $this->uploadedFiles;
    }

    /**
     * Create a new instance with the specified uploaded files.
     *
     * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
     * @return Request
     *
     * @throws InvalidArgumentException if an invalid structure is provided.
     */
    public function withUploadedFiles(array $uploadedFiles)
    {
        if (! $this->checkUploadedFiles($uploadedFiles)) {
            throw new InvalidArgumentException(
                "The uploaded files array given has at least one leaf that is not ".
                "an UploadedFile object."
            );
        }

        $request = clone $this;
        $request->uploadedFiles = $uploadedFiles;
        return $request;
    }

    /**
     * Detects the query params from server and/or request URI
     *
     * @return array
     */
    private function detectQueryParams()
    {
        $uri = new Uri('http://example.org'.$this->getRequestTarget());
        parse_str($uri->getQuery(), $params);
        return array_merge($_GET, $params);
    }

    /**
     * Creates a stream from php input stream
     *
     * @return StreamInterface
     */
    private function getPhpInputStream()
    {
        $stream = new TextStream(file_get_contents('php://input'));
        return $stream;
    }

    /**
     * Check if provided files array is valid
     *
     * @param array $files
     *
     * @return bool
     */
    private function checkUploadedFiles(array $files)
    {
        $valid = true;

        foreach ($files as $file) {
            if (is_array($file)) {
                $valid = $this->checkUploadedFiles($files);
                break;
            }

            if (! $file instanceof UploadedFile) {
                $valid = false;
                break;
            }
        }

        return $valid;
    }

    /**
     * Loads the headers form request
     */
    private function loadHeaders()
    {
        foreach ($_SERVER as $key => $value) {
            $subset = substr($key, 0, 5);
            if ($subset <> 'HTTP_' && $subset <> 'CONTE') {
                continue;
            }
            $header = str_replace(
                ' ',
                '-',
                ucwords(
                    str_replace(['http_', '_'], ['', ' '], strtolower($key))
                )
            );
            $this->headers[$this->headerKey($header)] = [$value];
        }
    }

    /**
     * Retrieve any parameters provided in the request body.
     *
     * @return null|array|object The deserialized body parameters, if any.
     *     These will typically be an array or object.
     */
    public function getParsedBody()
    {
        if (! $this->parsedBody) {
            $parser = new BodyParser($this->getHeaderLine('Content-Type'));
            $this->parsedBody = $parser->parse($this->getBody());
        }
        return $this->parsedBody;
    }

    /**
     * Return an instance with the specified body parameters.
     *
     * @param null|array|object $data The deserialized body data. This will
     *     typically be in an array or object.
     *
     * @return Request
     * @throws InvalidArgumentException if an unsupported argument type is
     *     provided.
     */
    public function withParsedBody($data)
    {
        if (! is_null($data) &&
            ! is_array($data) &&
            ! is_object($data)
        ) {
            throw new InvalidArgumentException(
                "Only NULL, array or Object types could be used to ".
                "create a new server request message with parsed body."
            );
        }

        $request = clone $this;
        $request->parsedBody = $data;
        return $request;
    }

    /**
     * Retrieve attributes derived from the request.
     *
     * The request "attributes" may be used to allow injection of any
     * parameters derived from the request: e.g., the results of path
     * match operations; the results of decrypting cookies; the results of
     * deserializing non-form-encoded message bodies; etc. Attributes
     * will be application and request specific, and CAN be mutable.
     *
     * @return mixed[] Attributes derived from the request.
     */
    public function getAttributes()
    {
        return $this->attributes;
    }

    /**
     * Return an instance with the specified derived request attribute.
     *
     * This method allows setting a single derived request attribute as
     * described in getAttributes().
     *
     * @see getAttributes()
     * @param string $name The attribute name.
     * @param mixed $value The value of the attribute.
     *
     * @return Request
     */
    public function withAttribute($name, $value)
    {
        $request = clone $this;
        $request->attributes[$name] = $value;
        return $request;
    }

    /**
     * Retrieve a single derived request attribute.
     *
     * Retrieves a single derived request attribute as described in
     * getAttributes(). If the attribute has not been previously set, returns
     * the default value as provided.
     *
     * @see getAttributes()
     * @param string $name The attribute name.
     * @param mixed $default Default value to return if the attribute does not exist.
     * @return mixed
     */
    public function getAttribute($name, $default = null)
    {
        if (array_key_exists($name, $this->attributes)) {
            $default = $this->attributes[$name];
        }
        return $default;
    }

    /**
     * Return an instance that removes the specified derived request attribute.
     *
     * This method allows removing a single derived request attribute as
     * described in getAttributes().
     *
     * @see getAttributes()
     * @param string $name The attribute name.
     *
     * @return Request
     */
    public function withoutAttribute($name)
    {
        $request = clone $this;
        if (array_key_exists($name, $request->attributes)) {
            unset($request->attributes[$name]);
        }
        return $request;
    }
}


<?php

/** This file is part of KCFinder project
  *
  *      @desc HTTP cache helper class
  *   @package KCFinder
  *   @version 3.12
  *    @author Pavel Tzonkov <sunhater@sunhater.com>
  * @copyright 2010-2014 KCFinder Project
  *   @license http://opensource.org/licenses/GPL-3.0 GPLv3
  *   @license http://opensource.org/licenses/LGPL-3.0 LGPLv3
  *      @link http://kcfinder.sunhater.com
  */

namespace kcfinder;

class httpCache {
    const DEFAULT_TYPE = "text/html";
    const DEFAULT_EXPIRE = 604800; // in seconds

/** Cache a file. The $type parameter might define the MIME type of the file
  * or path to magic file to autodetect the MIME type. If you skip $type
  * parameter the method will try with the default magic file. Autodetection
  * of MIME type requires Fileinfo PHP extension used in file::getMimeType()
  * @param string $file
  * @param string $type
  * @param integer $expire
  * @param array $headers */

    static function file($file, $type=null, $expire=null, array $headers=null) {
        $mtime = @filemtime($file);
        if ($mtime !== false) self::checkMTime($mtime);

        if ($type === null) {
            $magic = ((substr($type, 0, 1) == "/") || preg_match('/^[a-z]\:/i', $type))
                ? $type : null;
            $type = file::getMimeType($file, $magic);
            if (!$type) $type = null;
        }

        self::content(@file_get_contents($file), $mtime, $type, $expire, $headers, false);
    }

/** Cache the given $content with $mtime modification time.
  * @param binary $content
  * @param integer $mtime
  * @param string $type
  * @param integer $expire
  * @param array $headers
  * @param bool $checkMTime */

    static function content($content, $mtime, $type=null, $expire=null, array $headers=null, $checkMTime=true) {
        if ($checkMTime) self::checkMTime($mtime);
        if ($type === null) $type = self::DEFAULT_TYPE;
        if ($expire === null) $expire = self::DEFAULT_EXPIRE;
        $size = strlen($content);
        $expires = gmdate("D, d M Y H:i:s", time() + $expire) . " GMT";
        header("Content-Type: $type");
        header("Expires: $expires");
        header("Cache-Control: max-age=$expire");
        header("Pragma: !invalid");
        header("Content-Length: $size");
        if ($headers !== null) foreach ($headers as $header) header($header);
        echo $content;
    }

/** Check if given modification time is newer than client-side one. If not,
  * the method will tell the client to get the content from its own cache.
  * Afterwards the script process will be terminated. This feature requires
  * the PHP to be configured as Apache module.
  * @param integer $mtime
  * @param mixed $sendHeaders */

    static function checkMTime($mtime, $sendHeaders=null) {
        header("Last-Modified: " . gmdate("D, d M Y H:i:s", $mtime) . " GMT");

        $headers = function_exists("getallheaders")
            ? getallheaders()
            : (function_exists("apache_request_headers")
                ? apache_request_headers()
                : false);

        if (is_array($headers) && isset($headers['If-Modified-Since'])) {
            $client_mtime = explode(';', $headers['If-Modified-Since']);
            $client_mtime = @strtotime($client_mtime[0]);
            if ($client_mtime >= $mtime) {
                header('HTTP/1.1 304 Not Modified');
                if (is_array($sendHeaders) && count($sendHeaders))
                    foreach ($sendHeaders as $header)
                        header($header);
                elseif ($sendHeaders !== null)
                    header($sendHeaders);
                die;
            }
        }
    }

}

?>


<?php

/**
 * This file is part of slick/http
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Slick\Http\Message;

use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\StreamInterface;
use Slick\Http\Message\Stream\TextStream;

/**
 * Message
 *
 * @package Slick\Http\Message
*/
class Message implements MessageInterface
{

    /**
     * @var string
     */
    private $protocolVersion = '1.1';

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

    /**
     * @var StreamInterface
     */
    protected $body;

    /**
     * Creates an HTTP Message
     *
     * @param string $body
     */
    public function __construct($body = '')
    {
        $body = $body instanceof StreamInterface
            ? $body
            : new TextStream($body);
        $this->body = $body;
    }

    /**
     * Retrieves the HTTP protocol version as a string.
     *
     * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
     *
     * @return string HTTP protocol version.
     */
    public function getProtocolVersion()
    {
        return $this->protocolVersion;
    }

    /**
     * Return an instance with the specified HTTP protocol version.
     *
     * The version string MUST contain only the HTTP version number (e.g.,
     * "1.1", "1.0").
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * new protocol version.
     *
     * @param string $version HTTP protocol version
     * @return static
     */
    public function withProtocolVersion($version)
    {
        $message = clone $this;
        $message->protocolVersion = $version;
        return $message;
    }

    /**
     * Retrieves all message header values.
     *
     * The keys represent the header name as it will be sent over the wire, and
     * each value is an array of strings associated with the header.
     *
     *     // Represent the headers as a string
     *     foreach ($message->getHeaders() as $name => $values) {
     *         echo $name . ": " . implode(", ", $values);
     *     }
     *
     *     // Emit headers iteratively:
     *     foreach ($message->getHeaders() as $name => $values) {
     *         foreach ($values as $value) {
     *             header(sprintf('%s: %s', $name, $value), false);
     *         }
     *     }
     *
     * While header names are not case-sensitive, getHeaders() will preserve the
     * exact case in which headers were originally specified.
     *
     * @return string[][] Returns an associative array of the message's headers. Each
     *     key MUST be a header name, and each value MUST be an array of strings
     *     for that header.
     */
    public function getHeaders()
    {
        return $this->headers;
    }

    /**
     * Checks if a header exists by the given case-insensitive name.
     *
     * @param string $name Case-insensitive header field name.
     * @return bool Returns true if any header names match the given header
     *     name using a case-insensitive string comparison. Returns false if
     *     no matching header name is found in the message.
     */
    public function hasHeader($name)
    {
        $key = $this->headerKey($name);
        return array_key_exists($key, $this->headers);
    }

    /**
     * Retrieves a message header value by the given case-insensitive name.
     *
     * This method returns an array of all the header values of the given
     * case-insensitive header name.
     *
     * If the header does not appear in the message, this method MUST return an
     * empty array.
     *
     * @param string $name Case-insensitive header field name.
     * @return string[] An array of string values as provided for the given
     *    header. If the header does not appear in the message, this method MUST
     *    return an empty array.
     */
    public function getHeader($name)
    {
        $key = $this->headerKey($name);
        if (array_key_exists($key, $this->headers)) {
            return $this->headers[$key];
        }

        return [];
    }

    /**
     * Retrieves a comma-separated string of the values for a single header.
     *
     * This method returns all of the header values of the given
     * case-insensitive header name as a string concatenated together using
     * a comma.
     *
     * NOTE: Not all header values may be appropriately represented using
     * comma concatenation. For such headers, use getHeader() instead
     * and supply your own delimiter when concatenating.
     *
     * If the header does not appear in the message, this method MUST return
     * an empty string.
     *
     * @param string $name Case-insensitive header field name.
     * @return string A string of values as provided for the given header
     *    concatenated together using a comma. If the header does not appear in
     *    the message, this method MUST return an empty string.
     */
    public function getHeaderLine($name)
    {
        $header = $this->getHeader($name);
        return empty($header)
            ? ''
            : implode(',', $header);
    }

    /**
     * Return an instance with the provided value replacing the specified header.
     *
     * While header names are case-insensitive, the casing of the header will
     * be preserved by this function, and returned from getHeaders().
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * new and/or updated header and value.
     *
     * @param string $name Case-insensitive header field name.
     * @param string|string[] $value Header value(s).
     * @return static
     * @throws \InvalidArgumentException for invalid header names or values.
     */
    public function withHeader($name, $value)
    {
        $key = $this->headerKey($name);

        $message = clone $this;
        $message->headers[$key] = is_array($value) ? $value : [$value];
        return $message;
    }

    /**
     * Return an instance with the specified header appended with the given value.
     *
     * Existing values for the specified header will be maintained. The new
     * value(s) will be appended to the existing list. If the header did not
     * exist previously, it will be added.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * new header and/or value.
     *
     * @param string $name Case-insensitive header field name to add.
     * @param string|string[] $value Header value(s).
     * @return static
     * @throws \InvalidArgumentException for invalid header names or values.
     */
    public function withAddedHeader($name, $value)
    {
        $header = $this->getHeader($name);
        $values = is_array($value) ? $value : [$value];
        foreach ($values as $newValue) {
            $header[] = $newValue;
        }
        return $this->withHeader($name, $header);
    }

    /**
     * Return an instance without the specified header.
     *
     * Header resolution MUST be done without case-sensitivity.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that removes
     * the named header.
     *
     * @param string $name Case-insensitive header field name to remove.
     * @return static
     */
    public function withoutHeader($name)
    {
        $message = clone $this;
        $key = $this->headerKey($name);

        if (array_key_exists($key, $message->headers)) {
            unset($message->headers[$key]);
        }

        return $message;
    }

    /**
     * Gets the body of the message.
     *
     * @return StreamInterface Returns the body as a stream.
     */
    public function getBody()
    {
        return $this->body;
    }

    /**
     * Return an instance with the specified message body.
     *
     * The body MUST be a StreamInterface object.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return a new instance that has the
     * new body stream.
     *
     * @param StreamInterface $body Body.
     * @return static
     * @throws \InvalidArgumentException When the body is not valid.
     */
    public function withBody(StreamInterface $body)
    {
        $message = clone $this;
        $message->body = $body;
        return $message;
    }

    /**
     * Get the original (preserved) header name for provided name
     *
     * @param $name
     * @return mixed
     */
    protected function headerKey($name)
    {
        $key = $name;
        foreach (array_keys($this->headers) as $existingName) {
            if (strtolower($name) == strtolower($existingName)) {
                $key = $existingName;
                break;
            }
        }
        return $key;
    }
}


<?php
declare(strict_types=1);

namespace Clearhaus\HttpClient\Plugin;

use Http\Client\Common\Plugin;
use phpseclib\Crypt\RSA as Encrypter;
use Psr\Http\Message\RequestInterface;

class SignaturePlugin implements Plugin
{
    private $encrypter;
    private $apiKey;

    public function __construct(Encrypter $encrypter, string $apiKey)
    {
        $this->encrypter = $encrypter;
        $this->apiKey = $apiKey;
    }

    /**
     * {@inheritdoc}
     */
    public function handleRequest(RequestInterface $request, callable $next, callable $first)
    {
        $encryptedBody = $this->encrypter->encrypt($request->getBody()->getContents());
        $signature = sprintf('%s %s %s', $this->apiKey, 'RS256-hex', $encryptedBody);

        return $next(
            $request->withHeader('Signature', $signature)
        );
    }
}


<?php
/**
 * @copyright Bluz PHP Team
 * @link https://github.com/bluzphp/bluzman
 */

namespace Bluzman\Command;

use Application\CliBootstrap;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Class List command
 *
 * @package Bluzman\Command
 *
 * @author   Pavel Machekhin
 * @created  2013-03-28 14:03
 */
class RunCommand extends AbstractCommand
{
    /**
     * Command configuration
     */
    protected function configure()
    {
        $this
            // the name of the command (the part after "bin/bluzman")
            ->setName('run')
            // the short description shown while running "php bin/bluzman list"
            ->setDescription('Run controller')
            // the full command description shown when running the command with
            // the "--help" option
            ->setHelp('Run specified controller with options params')
        ;

        $uri = new InputArgument(
            'uri',
            InputArgument::REQUIRED,
            'URI to call'
        );

        $this->getDefinition()->addArgument($uri);

        $debug = new InputOption(
            '--debug',
            '-d',
            InputOption::VALUE_NONE,
            'Display debug information'
        );

        $this->getDefinition()->addOption($debug);
    }

    /**
     * @param InputInterface  $input
     * @param OutputInterface $output
     *
     * @return int|null|void
     * @throws \Bluz\Application\Exception\ApplicationException
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if ($input->getOption('debug')) {
            error_reporting(E_ALL);
            ini_set('display_errors', 1);
        }
        $app = CliBootstrap::getInstance();
        $app->setInput($input);
        $app->setOutput($output);
        $app->init($input->getOption('env'));
        $app->run();
    }
}


<?php

/**
 * This file is part of slick/http
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Slick\Http\Message;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;

/**
 * Response
 *
 * @package Slick\Http\Message
*/
class Response extends Message implements ResponseInterface
{
    /**
     * @var int
     */
    private $status;

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

    /**
     * Creates an HTTP Response message
     *
     * @param int                    $status
     * @param string|StreamInterface $body
     * @param array                  $headers
     */
    public function __construct($status, $body = '', array $headers = [])
    {
        parent::__construct($body);

        $this->setStatus($status);

        foreach ($headers as $name => $header) {
            $this->headers[$name] = [$header];
        }
    }

    /**
     * Gets the response status code.
     *
     * The status code is a 3-digit integer result code of the server's attempt
     * to understand and satisfy the request.
     *
     * @return int Status code.
     */
    public function getStatusCode()
    {
        return $this->status;
    }

    /**
     * Return an instance with the specified status code and, optionally, reason phrase.
     *
     * @link http://tools.ietf.org/html/rfc7231#section-6
     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
     * @param int $code The 3-digit integer result code to set.
     * @param string $reasonPhrase The reason phrase to use with the
     *     provided status code; if none is provided, implementations MAY
     *     use the defaults as suggested in the HTTP specification.
     * @return static
     * @throws \InvalidArgumentException For invalid status code arguments.
     */
    public function withStatus($code, $reasonPhrase = '')
    {
        $response = clone $this;
        $response->setStatus($code, $reasonPhrase);
        return $response;
    }

    /**
     * Gets the response reason phrase associated with the status code.
     *
     * @link http://tools.ietf.org/html/rfc7231#section-6
     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
     * @return string Reason phrase; must return an empty string if none present.
     */
    public function getReasonPhrase()
    {
        return $this->reasonPhrase;
    }

    /**
     * Sets the response status code
     *
     * @param int    $status
     * @param string $reasonPhrase
     */
    private function setStatus($status, $reasonPhrase = '')
    {
        HttpCodes::check($status);
        $this->status = intval($status, 10);
        if ($reasonPhrase === '') {
            $this->reasonPhrase = HttpCodes::reasonPhraseFor($this->status);
        }
    }
}


<?php
declare(strict_types=1);

namespace Clearhaus\HttpClient\Plugin;

use Clearhaus\Exception\ApiLimitExceedException;
use Clearhaus\Exception\RuntimeException;
use Clearhaus\Exception\UnauthorizedException;
use Clearhaus\Exception\ValidationFailedException;
use Clearhaus\HttpClient\Message\ResponseMediator;
use Http\Client\Common\Plugin;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class ErrorPlugin implements Plugin
{
    /**
     * {@inheritdoc}
     */
    public function handleRequest(RequestInterface $request, callable $next, callable $first)
    {
        return $next($request)->then(function (ResponseInterface $response) use ($request) {
            if ($response->getStatusCode() < 400 || $response->getStatusCode() > 600) {
                return $response;
            }

            if (401 === $response->getStatusCode()) {
                throw new UnauthorizedException();
            }

            $content = ResponseMediator::getContent($response);

            if (is_array($content) && isset($content['status'])) {
                if ($content['status']['code'] == 40415) {
                    throw new ApiLimitExceedException();
                }

                if ($content['status']['code'] >= 40000 && $content['status']['code'] < 40200) {
                    throw new ValidationFailedException($content['status']['message'], 422);
                }

                if ($content['status']['code'] >= 40200 && $content['status']['code'] <= 50000) {
                    throw new RuntimeException($content['status']['message'], 422);
                }
            }
        });
    }
}


<?php

/**
 * This file is part of slick/http
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Slick\Http\Server\Middleware;

use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slick\Http\Message\Response;
use Slick\Http\Message\Stream\TextStream;
use Slick\Http\Server\Exception\UnexpectedValueException;

/**
 * Callable Middleware
 *
 * @package Slick\Http\Server\Middleware
*/
class CallableMiddleware implements MiddlewareInterface
{
    /**
     * @var callable
     */
    private $callable;

    /**
     * Creates a callable Middleware
     *
     * @param callable $callable
     */
    public function __construct(callable $callable)
    {
        $this->callable = $callable;
    }

    /**
     * @param callable $callable
     * @param array    $arguments
     *
     * @return ResponseInterface
     */
    public static function execute(callable $callable, array $arguments)
    {
        $return = call_user_func_array($callable, $arguments);

        if ($return instanceof ResponseInterface) {
            return $return;
        }

        $canBeUsedAsText = is_null($return)
            || is_scalar($return)
            || (is_object($return) && method_exists($return, '__toString'));

        if (! $canBeUsedAsText) {
            throw new UnexpectedValueException(
                'The value returned must be scalar or an object with __toString method'
            );
        }

        return new Response(200, new TextStream((string) $return));
    }

    /**
     * Process an incoming server request and return a response, optionally delegating
     * response creation to an handler.
     *
     * @param ServerRequestInterface $request
     * @param RequestHandlerInterface $handler
     *
     * @return ResponseInterface
     */
    public function process(
        ServerRequestInterface $request,
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = self::execute($this->callable, [$request, $handler]);
        if (!$response instanceof ResponseInterface) {
            throw new UnexpectedValueException(
                sprintf('The middleware must return an instance of %s', ResponseInterface::class)
            );
        }
        return $response;
    }
}


<?php

class ToolBelt {

	/**
	 * Echo out a variable in a readable manner.
	 *
	 * @param mixed $var - The variable to echo.
	 */
	static function debug($var)
	{
		echo '<pre>';
		print_r($var);
		echo '</pre>';
	}

	/**
	 * Echo out all queries that have been executed thus far.
	 */
	static function print_queries()
	{
		static::debug(DB::getQueryLog());
	}

	/**
	 * Echo out the session.
	 */
	static function print_session()
	{
		static::debug(Session::all());
	}

	/**
	 * Convert dollars and cents to a number of pennies for Stripe usage.
	 * i.e.:  $1044.22 -> 104422
	 *
	 * @param float $dollars
	 * @return int - The number of pennies.
	 */
	static function pennies($dollars)
	{
		return (int) str_replace('.', '', number_format((float) $dollars, 2, '.', ''));
	}

	/**
	 * Get the MySQL version of the server.
	 *
	 * @return string - i.e.: '5.5.12'
	 */
	static function mysql_version()
	{
		$version = DB::select('SELECT VERSION() AS `version`');
		$version = explode('-', $version[0]->version);
		$version = $version[0];
		return $version;
	}

	/**
	 * Test if the MySQL version is greater than or equal to a given version number.
	 *
	 * @param string $than - The version number that we're comparing to, i.e. '5.5.12'
	 * @return boolean
	 */
	static function mysql_greater($than)
	{
		return version_compare(static::mysql_version(), $than, '>=');
	}

}


<?php namespace Angel\Core;

use App, Validator, Input;

abstract class AngelModel extends \Eloquent {

	/**
	 * The column from which to seed the slug.  (i.e.: 'name')
	 *
	 * @var string
	 */
	protected $slugSeed = null;

	/**
	 * Whether or not the *entire* table is to have the `order` column
	 * updated automatically on add/delete/etc.  (Don't use this if
	 * you cluster orders into subsets or categories, etc.)
	 *
	 * @var bool
	 */
	protected $reorderable = false;

	/**
	 * Whether to skip the model events, namely the assign() method
	 * that is called from the static::saving() in the boot() method
	 * of AngelModel to assign all user input to the columns.
	 *
	 * @var bool
	 */
	public $skipEvents = false;

	/**
	 * An array of columns to update from user input on each save.
	 *
	 * @return array
	 */
	public static function columns()
	{
		return array();
	}

	public function validate()
	{
		$errors = array();

		if (count($this->validate_rules())) {
			$validator = Validator::make(Input::all(), $this->validate_rules());
			if ($validator->fails()) {
				$errors = array_merge($errors, $validator->messages()->toArray());
			}
		}

		$errors = array_merge($errors, $this->validate_custom());

		return $errors;
	}
	public function validate_rules()
	{
		return array();
	}
	public function validate_custom()
	{
		return array();
	}

	///////////////////////////////////////////////
	//                  Events                   //
	///////////////////////////////////////////////
	public static function boot()
	{
		parent::boot();

		// Assign input to the columns()
		static::saving(function($model) {
			if ($model->skipEvents) return;
			$model->assign();
		});

		static::creating(function($model) {
			if ($model->reorderable) {
				$model->order = $model->count();
			}
		});

		// Fill in the `order` gap after deleting a model.
		static::deleted(function($model) {
			if (!$model->reorderable) return;
			$order = 0;
			foreach ($model->orderBy('order')->get() as $object) {
				$object->order = $order++;
				$object->save();
			}
		});
	}

	/**
	 * Assign input to the columns() and log changes (if updating).
	 */
	public function assign()
	{
		$changes = array();
		foreach (static::columns() as $column) {
			if (!Input::exists($column)) continue;
			if ($this->id && ($this->$column != Input::get($column))) {
				$changes[$column] = array(
					'old' => $this->$column,
					'new' => Input::get($column)
				);
			}
			$this->$column = Input::get($column);
		}
		if ($this->id) with(App::make('Change'))->log($this, $changes);
		if ($this->slugSeed) $this->slug = slug($this, $this->slugSeed);
	}

	public function changes()
	{
		return with(App::make('Change'))->where('fmodel', short_name($this))
			                            ->where('fid', $this->id)
			                            ->with('user')
			                            ->orderBy('created_at', 'DESC')
			                            ->get();
	}

}


<?php

namespace spec\im\Primitive\Object;

use im\Primitive\Container\Container;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class ObjectSpec extends ObjectBehavior
{
    protected $init;

    function let()
    {
        $this->init = ['name' => 'fooBar', 'surname' => 'Baz'];

        $this->beConstructedWith($this->init);
    }

    function it_is_initializable()
    {
        $this->shouldHaveType('im\Primitive\Object\Object');
    }

    /**
     * Construction and conversion
     */
    function it_should_construct_properly_from_array()
    {
        $initializer = ['foo', 'bar', 'name' => 'fooBar'];

        $this->fromArray($initializer)->get('name')->shouldBe('fooBar');

        $this->length()->shouldBe(count($this->init));
    }

    function it_should_construct_from_json()
    {
        $initializer = string('{"key": "value"}');

        $this->beConstructedWith($initializer);

        $this->has('key')->shouldBe(true);
    }

    function it_should_construct_from_file_with_json()
    {
        $initializer = string(__DIR__.DIRECTORY_SEPARATOR.
                                '..'.DIRECTORY_SEPARATOR.
                                    'Container'.DIRECTORY_SEPARATOR.
                                        'data.json');

        $this->beConstructedWith($initializer);

        $this->has('name')->shouldBe(true);
    }

    function it_should_constuct_from_file()
    {
        $initializer = string(__DIR__.DIRECTORY_SEPARATOR.
                                '..'.DIRECTORY_SEPARATOR.
                                    'Container'.DIRECTORY_SEPARATOR.
                                        'data.json');

        $this->fromFile($initializer)->has('name')->shouldBe(true);
    }

    function it_should_put_inner_contents_to_file()
    {
        $this->toFile(__DIR__.DIRECTORY_SEPARATOR.'object.im')->shouldBe(true);
    }

    function it_should_convert_to_Container_Type()
    {
        $this->toContainer()->shouldHaveType('im\Primitive\Container\Container');
    }

    function it_should_convert_to_String_Type()
    {
        $this->toString()->shouldHaveType('im\Primitive\String\String');
    }

    function it_should_dynamically_set_property()
    {
        $value = 'new field';

        $this->field = $value;

        $this->get('field')->shouldBe($value);
    }

    function it_should_dynamically_get_value()
    {
        $this->name->shouldBe($this->init['name']);
    }

    function it_should_set_and_get_value_with_dot_notation()
    {
        $value = 'new field';

        $this->set('field.array', $value)->get('field.array')->shouldBe($value);

        $this->{'array.key'} = $value;

        $this->get('array.key')->shouldBe($value);
    }

    function it_should_check_if_has_property_with_dot_notation()
    {
        $this->has('name')->shouldBe(true);

        $this->set('a.a', 'value')->has('a.a');
    }

    function it_should_forget_value_by_property_with_dot_notation()
    {
        $this->forget('name')->has('name')->shouldBe(false);

        $this->set('a.a', 'value')->has('a.a')->shouldBe(true);

        $this->forget('a.a')->has('a.a')->shouldBe(false);

        $this->has('a')->shouldBe(true);
    }

    function it_should_return_length()
    {
        $this->length()->shouldBe(count($this->init));
    }

    function it_should_return_inner_value()
    {
        $this->value()->shouldBe($this->init);
    }

    function it_should_auto_convert_to_string()
    {
        $this->__toString()->shouldBe(json_encode($this->init));
    }

    function it_should_convert_to_json()
    {
        $this->toJson()->shouldBe(json_encode($this->init));
    }

    function it_should_convert_to_array()
    {
        $this->toArray()->shouldBe($this->init);
    }

    /**
     * Abstract Type methods
     */

    function it_should_return_value_if_call_instance_like_function()
    {
        $this()->shouldBe($this->init);
    }

    function it_should_serialize()
    {
        $match = serialize($this->init);

        $this->serialize()->shouldBe($match);
    }

    function it_should_unserialize()
    {
        $serialized = serialize($this->init);

        $this->unserialize($serialized);
        $this->value()->shouldBe($this->init);
    }

    function it_should_make_new_instance()
    {
        $match = $this->init;

        $this->make($match)->value()->shouldBe($match);
    }

    function it_should_create_new_instance_statically()
    {
        $match = $this->init;

        static::create($match)->value()->shouldBe($match);
    }

    function it_should_have_helper_function_and_create_new_instance()
    {
        $property = 'object';
        $value = object();

        $this->set($property, $value)->get($property)->shouldBe($value);
    }
}


<?php

namespace spec\im\Primitive\Float;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class FloatSpec extends ObjectBehavior
{
    protected $init;

    function let()
    {
        $this->init = 10.5;

        $this->beConstructedWith($this->init);
    }

    function it_is_initializable()
    {
        $this->shouldHaveType('im\Primitive\Float\Float');
    }

    /**
     * Construction and conversion
     */

    function it_should_construct_from_int()
    {
        $init = 1;

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo((float) $init);
    }

    function it_should_construct_from_float()
    {
        $init = 1.1;

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo($init);
    }

    function it_should_construct_from_string()
    {
        $init = 'false';

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo((float) $init);
    }

    function it_should_construct_from_bool()
    {
        $init = true;

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo((float) $init);
    }

    function it_should_construct_from_String_Type()
    {
        $init = 'false';

        $this->beConstructedWith(string($init));

        $this->value()->shouldBeEqualTo((float) $init);
    }

    function it_should_construct_from_Int_Type()
    {
        $init = 13;

        $this->beConstructedWith(int($init));

        $this->value()->shouldBeEqualTo((float) $init);
    }

    function it_should_construct_from_Float_Type()
    {
        $init = 12.3;

        $this->beConstructedWith(float($init));

        $this->value()->shouldBeEqualTo($init);
    }

    function it_should_construct_from_Bool_Type()
    {
        $init = false;

        $this->beConstructedWith(bool($init));

        $this->value()->shouldBeEqualTo((float) $init);
    }

    function it_should_convert_to_Bool_Type()
    {
        $this->toBool()->shouldHaveType('im\Primitive\Bool\Bool');
    }

    function it_should_convert_to_Int_Type()
    {
        $this->toInt()->shouldHaveType('im\Primitive\Int\Int');
    }

    function it_should_convert_to_String_Type()
    {
        $this->toString()->shouldHaveType('im\Primitive\String\String');
    }

    function it_should_convert_to_Container_Type()
    {
        $this->toContainer()->shouldHaveType('im\Primitive\Container\Container');
    }

    function it_should_return_true_if_isTrue_called()
    {
        $result = (bool) $this->init ?: false;

        $this->isTrue()->shouldBe($result);
    }

    function it_should_return_false_if_isFalse_called()
    {
        $result = (bool) $this->init ? false: true;

        $this->isFalse()->shouldBe($result);
    }

    /**
     * Math
     */

    function it_should_plus_values()
    {
        $plus = 10.00;

        $this->plus($plus)->value()->shouldBe($this->init + $plus);
    }

    function it_should_minus_values()
    {
        $minus = 5.5;

        $this->minus($minus)->value()->shouldBe($this->init - $minus);
    }

    function it_should_multiply_values()
    {
        $multiply = 10.4;

        $this->multiply($multiply)->value()->shouldBe($this->init * $multiply);
    }

    function it_should_divide_values()
    {
        $divide = 10.3;

        $this->divide($divide)->value()->shouldBe($this->init / $divide);
    }

    function it_should_modulo_values()
    {
        $modulo = 2;

        $this->modulo($modulo)->value()->shouldBe($this->init % $modulo);
    }

    function it_should_power_by_value()
    {
        $power = 2;

        $this->power($power)->value()->shouldBe(pow($this->init, $power));
    }

    function it_should_sqrt_by_value()
    {
        $sqrt = 2;

        $this->sqrt($sqrt)->value()->shouldBe(sqrt($this->init));
    }

    function it_should_abs_value()
    {
        $init = -20.00;

        $this->set($init)->abs()->value()->shouldBe(abs($init));
    }

    function it_should_return_sin_of_value()
    {
        $this->sin()->value()->shouldBe(sin($this->init));
    }

    function it_should_return_cos_of_value()
    {
        $this->cos()->value()->shouldBe(cos($this->init));
    }

    function it_should_return_tan_of_value()
    {
        $this->tan()->value()->shouldBe(tan($this->init));
    }

    function it_should_return_Float_Type_with_PI_value()
    {
        $this->pi()->value->shouldBe(pi());
    }

    function it_should_return_factorial_of_value()
    {
        $this->factorial()->shouldBe(factorial($this->init));
    }

    function it_should_format_float_to_correct_float_string()
    {
        $init = 32.2249;

        $formatted = $this->set($init)->format();

        $formatted->shouldHaveType('im\Primitive\String\String');

        $formatted->value->shouldBe(number_format($init, 2, '.', ' '));
    }

    function it_should_return_length_of_value()
    {
        $this->length()->shouldBe(mb_strlen((string) $this->init));
    }

    function it_should_return_true_ifEqual()
    {
        $this->isEqual(float($this->init));
        $this->isEqual($this->init);
    }

    function it_should_check_ifNegative()
    {
        $this->isNegative()->shouldBe(false);

        $this->set(-10.00)->isNegative()->shouldBe(true);
    }

    function it_should_check_ifNotNegative()
    {
        $this->isNotNegative()->shouldBe(true);

        $this->set(-10)->isNotNegative()->shouldBe(false);
    }

    function it_should_check_if_isLowerThan()
    {
        $this->isLowerThan(float(20))->shouldBe(true);
        $this->isLowerThan(5)->shouldBe(false);
    }

    function it_should_check_if_isLowerThanOrEqual()
    {
        $this->isLowerThanOrEqual(float(12))->shouldBe(true);
        $this->isLowerThanOrEqual(5)->shouldBe(false);
    }

    function it_should_check_if_isGreaterThan()
    {
        $this->isGreaterThan(float(0))->shouldBe(true);
        $this->isGreaterThan(15)->shouldBe(false);
    }

    function it_should_check_if_isGreaterThanOrEqual()
    {
        $this->isGreaterThanOrEqual(float(10))->shouldBe(true);
        $this->isGreaterThanOrEqual(5)->shouldBe(true);
    }

    function it_should_ceil_value()
    {
        $this->ceil()->value()->shouldBe((float) 11);
    }

    function it_should_floor_value()
    {
        $this->floor()->value()->shouldBe((float) 10);
    }

    function it_should_round_value()
    {
        $this->round()->value()->shouldBe((float) 11);

        $this->round(0, PHP_ROUND_HALF_DOWN)->value()->shouldBe((float) 10);
    }

    /**
     * Abstract Type methods
     */

    function it_should_call_method_if_it_looks_like_variable()
    {
        $this->value->shouldBe($this->init);
    }

    function it_should_return_value_if_call_instance_like_function()
    {
        $this()->shouldBe($this->init);
    }

    function it_should_serialize()
    {
        $match = serialize($this->init);

        $this->serialize()->shouldBe($match);
    }

    function it_should_unserialize()
    {
        $serialized = serialize($this->init);

        $this->unserialize($serialized);
        $this->value()->shouldBe($this->init);
    }

    function it_should_make_new_instance()
    {
        $match = $this->init;

        $this->make($match)->value()->shouldBe($match);
    }

    function it_should_create_new_instance_statically()
    {
        $match = $this->init;

        static::create($match)->value()->shouldBe($match);
    }

    function it_should_have_helper_function_and_create_new_instance()
    {
        $match = $this->init;

        $this->set(float($match))->value()->shouldBe($match);
    }
}


<?php

namespace Sonic\Routes;

/**
 * TagRoute
 *
 * This route is executed when a ``/tag | /tags`` URL is matched
 *
 * @package    Sonic
 * @subpackage Route
 * @author     Hassan Khan <contact@hassankhan.me>
 * @link       https://github.com/hassankhan/Sonic
 * @license    MIT
 * @since      0.7
 */
class TagRoute extends ListRoute
{

    /**
     * Initializes the route by creating a regex pattern from the provided URL,
     * and assigns the callable function for this route
     *
     * @param string $url
     * @codeCoverageIgnore
     */
    public function __construct($url = '')
    {
        parent::__construct($url, array($this, 'build_route'));
    }

    /**
     * Method required by abstract class. Returns an array of posts
     * that match whatever requirements for this route.
     *
     * @return array
     */
    public function posts()
    {
        // Get tag name
        $params   = func_get_args();
        $tag_name = $params[0];

        // Get all files in path
        $contents = $this->sonic->app['filesystem']->listContents('content', TRUE);

        // Create array to hold tagged files
        $tagged_files = array();

        // Get tagged files
        foreach ($contents as $file) {
            if (
                isset($file['extension']) === TRUE
                && $file['extension'] === 'md'
            ) {

                $file_contents = $this->sonic->app['filesystem']->read($file['path']);

                // Grab meta section between '/* ... */' in the content file
                preg_match_all('#/\*(.*?)\*/#s', $file_contents, $meta);

                // Find tag field
                preg_match_all('#^[\t*\#@]*(Tags):(.*)$#m', $meta[1][0], $matches);

                // Retrieve tags
                $tags = isset($matches[2][0]) === TRUE ? trim($matches[2][0], ' ') : NULL;

                // Replace ', ' with ',' and then explode
                $tags = explode(',', str_replace(', ', ',', $tags));

                if (in_array($tag_name, $tags)) {
                    $tagged_files[] = $file['path'];
                }
            }
        }

        return $this->excerpts($tagged_files);
    }

}


<?php

namespace Bonnier\WP\Cxense\Models;

use Bonnier\Willow\MuPlugins\Helpers\LanguageProvider;
use Bonnier\WP\Cxense\Services\CxenseApi;
use Bonnier\WP\Cxense\Settings\SettingsPage;
use Bonnier\WP\Cxense\WpCxense;

class Post
{
    public static function watch_post_changes()
    {
        // Ping crawler when post is changed
        add_action('transition_post_status', [__CLASS__, 'post_status_changed'], 10, 3);
    }

    public static function post_status_changed($new_status, $old_status, $post)
    {
        if ($old_status === 'draft' && $new_status === 'trash') {
            return;
        }

        if ($new_status === 'publish') {
            self::update_post($post->ID);
        } elseif ($new_status === 'trash') {
            self::delete_post($post->ID);
        }
    }

    public static function update_post($postId)
    {

        // We have to set the current locale on the settings page in order to get the correct localized settings
        // for the current context.
        self::set_current_lang_from_post_id($postId);

        if (WpCxense::instance()->settings->getEnabled()) {
            return CxenseApi::pingCrawler($postId);
        }
    }

    public static function delete_post($postId)
    {
        return CxenseApi::pingCrawler($postId, true);
    }

    public static function is_published($postId)
    {
        return get_post_status($postId) === 'publish';
    }

    /**
     * Sets the locale on the settings page based upon to the locale of the post
     *
     * @param $postId
     */
    private static function set_current_lang_from_post_id($postId)
    {
        if (WpCxense::instance()->settings->languagesIsEnabled()) {
            WpCxense::instance()->settings->setCurrentLocale(LanguageProvider::getPostLanguage($postId));
        }
    }
}


<?php namespace im\Primitive\Support\Traits;

use JWT;
use Exception;
use im\Primitive\Support\Str;

/**
 * Class StringCheckerTrait
 *
 * @package im\Primitive\Support\Traits
 * @author Igor Krimerman <i.m.krimerman@gmail.com>
 */
trait StringCheckerTrait {

    /**
     * Check if string is encrypted Container
     *
     * @param string $encrypted
     * @param string $key
     * @return bool
     */
    public function isEncryptedContainer($encrypted, $key)
    {
        try
        {
            $data = JWT::decode($encrypted, $key);
        }
        catch(Exception $e)
        {
            return false;
        }

        return $this->isJson($data->container);
    }

    /**
     * Check if string is encrypted String
     *
     * @param string $encrypted
     * @param string $key
     * @return bool
     */
    public function isEncryptedString($encrypted, $key)
    {
        try
        {
            $data = JWT::decode($encrypted, $key);
        }
        catch(Exception $e)
        {
            return false;
        }

        return is_string($data->string);
    }

    /**
     * Check if string is readable file
     *
     * @param string $string
     * @return bool
     */
    public function isFile($string)
    {
        return Str::isFile($string);
    }

    /**
     * Checks if given string is Json
     *
     * @param string $string
     * @return bool
     */
    public function isJson($string)
    {
        return Str::isJson($string);
    }

    /**
     * Checks if given string is serialized
     *
     * @param string $string
     * @return bool
     */
    public function isSerialized($string)
    {
        return Str::isSerialized($string);
    }
}


<?php

/*
 * This file is part of Mandango.
 *
 * (c) Pablo Díez <pablodip@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Mandango\Mondator;

use Mandango\Mondator\Definition\Definition as BaseDefinition;

/**
 * The Mondator Dumper.
 *
 * @author Pablo Díez <pablodip@gmail.com>
 *
 * @api
 */
class Dumper
{
    private $definition;

    /**
     * Constructor.
     *
     * @param Mandango\Mondator\Definition\Definition $definition The definition.
     *
     * @api
     */
    public function __construct(BaseDefinition $definition)
    {
        $this->setDefinition($definition);
    }

    /**
     * Set the definition.
     *
     * @param Mandango\Mondator\Definition\Definition $definition The definition.
     *
     * @api
     */
    public function setDefinition(BaseDefinition $definition)
    {
        $this->definition = $definition;
    }

    /**
     * Returns the definition
     *
     * @return Mandango\Mondator\Definition\Definition The definition.
     *
     * @api
     */
    public function getDefinition()
    {
        return $this->definition;
    }

    /**
     * Dump the definition.
     *
     * @return string The PHP code of the definition.
     *
     * @api
     */
    public function dump()
    {
        return
            $this->startFile().
            $this->addNamespace().
            $this->startClass().
            $this->addProperties().
            $this->addMethods().
            $this->endClass()
        ;
    }

    /**
     * Export an array.
     *
     * Based on Symfony\Component\DependencyInjection\Dumper\PhpDumper::exportParameters
     * http://github.com/symfony/symfony
     *
     * @param array $array  The array.
     * @param int   $indent The indent.
     *
     * @return string The array exported.
     */
    static public function exportArray(array $array, $indent)
    {
        $code = array();
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $value = self::exportArray($value, $indent + 4);
            } else {
                $value = null === $value ? 'null' : var_export($value, true);
            }

            $code[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), var_export($key, true), $value);
        }

        return sprintf("array(\n%s\n%s)", implode("\n", $code), str_repeat(' ', $indent - 4));
    }

    private function startFile()
    {
        return <<<EOF
<?php

EOF;
    }

    private function addNamespace()
    {
        if (!$namespace = $this->definition->getNamespace()) {
            return '';
        }

        return <<<EOF

namespace $namespace;

EOF;
    }

    private function startClass()
    {
        $code = "\n";

        // doc comment
        if ($docComment = $this->definition->getDocComment()) {
            $code .= $docComment."\n";
        }

        /*
         * declaration
         */
        $declaration = '';

        // abstract
        if ($this->definition->isAbstract()) {
            $declaration .= 'abstract ';
        }

        // class
        $declaration .= 'class '.$this->definition->getClassName();

        // parent class
        if ($parentClass = $this->definition->getParentClass()) {
            $declaration .= ' extends '.$parentClass;
        }

        // interfaces
        if ($interfaces = $this->definition->getInterfaces()) {
            $declaration .= ' implements '.implode(', ', $interfaces);
        }

        $code .= <<<EOF
$declaration
{
EOF;

        return $code;
    }

    private function addProperties()
    {
        $code = '';

        $properties = $this->definition->getProperties();
        foreach ($properties as $property) {
            $code .= "\n";

            if ($docComment = $property->getDocComment()) {
                $code .= $docComment."\n";
            }
            $isStatic = $property->isStatic() ? 'static ' : '';

            $value = $property->getValue();
            if (null === $value) {
                $code .= <<<EOF
    $isStatic{$property->getVisibility()} \${$property->getName()};
EOF;
            } else {
                $value = is_array($property->getValue()) ? self::exportArray($property->getValue(), 8) : var_export($property->getValue(), true);

                $code .= <<<EOF
    $isStatic{$property->getVisibility()} \${$property->getName()} = $value;
EOF;
            }
        }
        if ($properties) {
            $code .= "\n";
        }

        return $code;
    }

    private function addMethods()
    {
        $code = '';

        foreach ($this->definition->getMethods() as $method) {
            $code .= "\n";

            // doc comment
            if ($docComment = $method->getDocComment()) {
                $code .= $docComment."\n";
            }

            // isFinal
            $isFinal = $method->isFinal() ? 'final ' : '';

            // isStatic
            $isStatic = $method->isStatic() ? 'static ' : '';

            // abstract
            if ($method->isAbstract()) {
                $code .= <<<EOF
    abstract $isStatic{$method->getVisibility()} function {$method->getName()}({$method->getArguments()});
EOF;
            } else {
                $methodCode = trim($method->getCode());
                if ($methodCode) {
                    $methodCode = '    '.$methodCode."\n    ";
                }
                $code .= <<<EOF
    $isFinal$isStatic{$method->getVisibility()} function {$method->getName()}({$method->getArguments()})
    {
    $methodCode}
EOF;
            }

            $code .= "\n";
        }

        return $code;
    }

    private function endClass()
    {
        $code = '';

        if (!$this->definition->getProperties() && !$this->definition->getMethods()) {
            $code .= "\n";
        }

        $code .= <<<EOF
}
EOF;

        return $code;
    }
}


<?php

/*
 * This file is part of Mandango.
 *
 * (c) Pablo Díez <pablodip@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Mandango\Mondator;

/**
 * Extension is the base class for extensions.
 *
 * @author Pablo Díez <pablodip@gmail.com>
 *
 * @api
 */
abstract class Extension extends ClassExtension
{
    /**
     * Pre global process of the extension.
     *
     * @param \ArrayObject                $configClasses The config classes.
     * @param Mandango\Mondator\Container $container     The global container.
     *
     * @api
     */
    public function preGlobalProcess(\ArrayObject $configClasses, Container $container)
    {
        $this->configClasses = $configClasses;
        $this->definitions = $container;

        $this->doPreGlobalProcess();

        $this->configClasses = null;
        $this->definitions = null;
    }

    /**
     * Do the pre global process.
     *
     * @api
     */
    protected function doPreGlobalProcess()
    {
    }

    /**
     * Post global process of the extension.
     *
     * @param \ArrayObject                $configClasses The config classes.
     * @param Mandango\Mondator\Container $container     The global container.
     *
     * @api
     */
    public function postGlobalProcess(\ArrayObject $configClasses, Container $container)
    {
        $this->configClasses = $configClasses;
        $this->definitions = $container;

        $this->doPostGlobalProcess();

        $this->configClasses = null;
        $this->definitions = null;
    }

    /**
     * Do the post global process.
     *
     * @api
     */
    protected function doPostGlobalProcess()
    {
    }
}


<?php

namespace spec\im\Primitive\String;

use im\Primitive\Container\Container;
use JWT;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Stringy\StaticStringy;

class StringSpec extends ObjectBehavior
{
    protected $init;

    function let()
    {
        $this->init = 'fooBar';

        $this->beConstructedWith($this->init);
    }

    function it_is_initializable()
    {
        $this->shouldHaveType('im\Primitive\String\String');
    }

    /**
     * Construction and conversion
     */

    function it_should_construct_from_int()
    {
        $init = 1;

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo((string) $init);
    }

    function it_should_construct_from_float()
    {
        $init = 1.1;

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo((string) $init);
    }

    function it_should_construct_from_string()
    {
        $init = 'false';

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo($init);
    }

    function it_should_construct_from_bool()
    {
        $init = true;

        $this->beConstructedWith($init);

        $this->value()->shouldBeEqualTo(($init ? 'true' : 'false'));
    }

    function it_should_construct_from_String_Type()
    {
        $init = 'false';

        $this->beConstructedWith(string($init));

        $this->value()->shouldBeEqualTo($init);
    }

    function it_should_construct_from_Int_Type()
    {
        $init = 13;

        $this->beConstructedWith(int($init));

        $this->value()->shouldBeEqualTo((string) $init);
    }

    function it_should_construct_from_Float_Type()
    {
        $init = 12.3;

        $this->beConstructedWith(float($init));

        $this->value()->shouldBeEqualTo((string) $init);
    }

    function it_should_construct_from_Bool_Type()
    {
        $init = false;

        $this->beConstructedWith(bool($init));

        $this->value()->shouldBeEqualTo(($init ? 'true' : 'false'));
    }

    function it_should_convert_to_Bool_Type()
    {
        $this->toBool()->shouldHaveType('im\Primitive\Bool\Bool');
    }

    function it_should_convert_to_Int_Type()
    {
        $this->toInt()->shouldHaveType('im\Primitive\Int\Int');
    }

    function it_should_convert_to_Float_Type()
    {
        $this->toFloat()->shouldHaveType('im\Primitive\Float\Float');
    }

    function it_should_convert_to_Container_Type()
    {
        $this->toContainer()->shouldHaveType('im\Primitive\Container\Container');
    }

    function it_should_return_value_with_get_method()
    {
        $this->get()->shouldBe($this->init);
    }

    function it_should_return_length()
    {
        $this->length()->shouldBe(mb_strlen($this->init));
    }

    function it_should_return_Container_with_all_chars()
    {
        $chars = $this->chars();

        $chars->shouldHaveType('im\Primitive\Container\Container');

        $chars->all()->shouldBe(StaticStringy::chars($this->init));
    }

    function it_should_append_any_type_to_inner_value()
    {
        $append = 'Baz';

        $this->append($append)->value()->shouldBe($this->init.$append);

        $this->set($this->init);
        $this->append(string($append))->value()->shouldBe($this->init.$append);

        $this->set($this->init);
        $this->append(bool(true))->value()->shouldBe($this->init.'true');

        $this->set($this->init);
        $this->append(container(['Bar', 'Baz']))->value()->shouldBe($this->init.'Bar'.'Baz');

        $this->set($this->init);
        $this->append(int(1))->value()->shouldBe($this->init.'1');

        $this->set($this->init);
        $this->append(float('1.04'))->value()->shouldBe($this->init.'1.04');
    }

    function it_should_prepend_any_type_to_inner_value()
    {
        $prepend = 'Baz';

        $this->prepend($prepend)->value()->shouldBe($prepend . $this->init);

        $this->set($this->init);
        $this->prepend(string($prepend))->value()->shouldBe($prepend . $this->init);

        $this->set($this->init);
        $this->prepend(bool(true))->value()->shouldBe('true' . $this->init);

        $this->set($this->init);
        $this->prepend(container(['Bar', 'Baz']))->value()->shouldBe('Bar' . 'Baz' . $this->init);

        $this->set($this->init);
        $this->prepend(int(1))->value()->shouldBe('1' . $this->init);

        $this->set($this->init);
        $this->prepend(float('1.04'))->value()->shouldBe('1.04' . $this->init);
    }

    function it_should_make_value_lower_case()
    {
        $this->lower()->value()->shouldBe(mb_strtolower($this->init));
    }

    function it_should_make_first_letter_lower_case()
    {
        $init = 'FooBar';

        $this->set($init)->lowerFirst()->value()->shouldBe(lcfirst($init));
    }

    function it_should_make_value_upper_case()
    {
        $this->upper()->value()->shouldBe(mb_strtoupper($this->init));
    }

    function it_should_make_first_letter_upper_case()
    {
        $init = 'fooBar';

        $this->set($init)->upperFirst()->value()->shouldBe(ucfirst($init));
    }

    function it_should_make_camel_case_and_upper_first_letter()
    {
        $init = 'foo bar';

        $this->set($init)->upperCamel()->value()->shouldBe('FooBar');
    }

    function it_should_make_title_case()
    {
        $init = 'foo bar';

        $this->set($init)->title()->value()->shouldBe('Foo Bar');
    }

    function it_should_make_came_case()
    {
        $init = 'foo bar';

        $this->set($init)->camel()->value()->shouldBe('fooBar');
    }

    function it_should_make_dashed_case()
    {
        $init = 'foo bar';

        $this->set($init)->dashed()->value()->shouldBe('foo-bar');
    }

    function it_should_make_snake_case()
    {
        $init = 'Foo bar';

        $this->set($init)->snake()->value()->shouldBe('foo_bar');
    }

    function it_should_make_studly_case()
    {
        $init = 'foo bar';

        $this->set($init)->studly()->value()->shouldBe('FooBar');
    }

    function it_should_swap_case()
    {
        $init = 'foo bar';

        $this->set($init)->swapCase()->value()->shouldBe('FOO BAR');

        $init = 'Foo Bar';

        $this->set($init)->swapCase()->value()->shouldBe('fOO bAR');
    }

    function it_should_make_human_readable_text()
    {
        $init = 'foo bar_id_baz';

        $this->set($init)->humanize()->value()->shouldBe('Foo bar baz');
    }

    function it_should_make_title_case_and_ignore_given_values()
    {
        $init = 'foo bar_baz ignore';

        $this->set($init)->titleize(['ignore'])->value()->shouldBe('Foo Bar_baz ignore');
    }

    function it_should_return_true_if_value_has_given_string()
    {
        $this->has('oB')->shouldBe(true);

        $this->has('ob', false)->shouldBe(true);
    }

    function it_should_return_true_if_value_has_any_of_given_string()
    {
        $this->hasAny(['bc','oB'])->shouldBe(true);

        $this->hasAny(['bc','dB'])->shouldBe(false);

        $this->hasAny(['cb','ob'], false)->shouldBe(true);
    }

    function it_should_return_true_if_value_has_all_of_given_string()
    {
        $this->hasAll(['fo','oB'])->shouldBe(true);

        $this->hasAll(['fo','oZ'])->shouldBe(false);

        $this->hasAll(['fo','ob'], false)->shouldBe(true);
    }

    function it_should_collapse_whitespaces()
    {
        $init = "\n\t".'foo          bar             baz' . "\n\t";

        $this->set($init)->collapseWhitespace()->value()->shouldBe('foo bar baz');
    }

    function it_should_return_ascii()
    {
        $init = 'ща_foo';

        $this->set($init)->toAscii()->value()->shouldBe('shcha_foo');
    }

    function it_should_replace_tabs_to_given_space_quantity()
    {
        $init = "\tfoo\t";

        $this->set($init)->toSpaces()->value()->shouldBe('    foo    ');

        $this->set($init)->toSpaces(2)->value()->shouldBe('  foo  ');
    }

    function it_should_replace_given_space_quantity_to_tab()
    {
        $init = "    foo    ";

        $this->set($init)->toTabs()->value()->shouldBe("\tfoo\t");

        $this->set($init)->toTabs(2)->value()->shouldBe("\t\tfoo\t\t");
    }

    function it_should_surrond_value_with_given_string()
    {
        $surround = 'Z';

        $this->surround($surround)->value()->shouldBe($surround.$this->init.$surround);
    }

    function it_should_insert_string_or_char_at_given_index()
    {
        $insert = 'insert';

        $this->insert($insert, 0)->value()->shouldBe($insert.$this->init);

        $this->insert($insert, 3)->value()->shouldBe('foo'.$insert.'Bar');

        $this->insert($insert, strlen($this->init) + 2)->value()->shouldBe($this->init);
    }

    function it_should_reverse_value()
    {
        $reverse = strrev($this->init);

        $this->reverse()->value()->shouldBe($reverse);
    }

    function it_should_return_char_at_given_index()
    {
        $this->at(1)->value()->shouldBe(substr($this->init, 1, 1));
    }

    function it_should_return_first_n_items()
    {
        $this->first(3)->value()->shouldBe(substr($this->init, 0, 3));
    }

    function it_should_return_last_n_items()
    {
        $this->last(3)->value()->shouldBe(substr($this->init, -3));
    }

    function it_should_ensure_that_left_part_of_value_has_given_string_if_not_than_add()
    {
        $left = substr($this->init, 0, 3);

        $this->ensureLeft($left)->value()->shouldBe($this->init);

        $this->ensureLeft('ensured')->value()->shouldBe('ensured'.$this->init);
    }

    function it_should_ensure_that_right_part_of_value_has_given_string_if_not_than_add()
    {
        $right = substr($this->init, -3);

        $this->ensureRight($right)->value()->shouldBe($this->init);

        $this->ensureRight('ensured')->value()->shouldBe($this->init.'ensured');
    }

    function it_should_remove_chars_from_left()
    {
        $str = substr($this->init, 2);

        $this->removeLeft('fo')->value()->shouldBe($str);
    }

    function it_should_remove_chars_from_right()
    {
        $str = substr($this->init, 0, -2);

        $this->removeRight('ar')->value()->shouldBe($str);
    }

    function it_should_replace_string()
    {
        $this->replace('foo', 'baz')->value()->shouldBe(str_replace('foo', 'baz', $this->init));
    }

    function it_should_replace_arrayable_of_replacements_in_string()
    {
        $array = ['f', 'o'];

        $container = container($array);

        $this->replace($array, 'baz')->value()->shouldBe(str_replace($array, 'baz', $this->init));

        $this->replace($container, 'baz')->value()->shouldBe(str_replace($container->all(), 'baz', $this->init));
    }

    function it_should_check_if_value_starts_with_given_string()
    {
        $this->startsWith('foo')->shouldBe(true);
        $this->startsWith('Bar')->shouldBe(false);
        $this->startsWith(container(['foo', 'f']))->shouldBe(true);
    }

    function it_should_check_if_value_ends_with_given_string()
    {
        $this->endsWith('foo')->shouldBe(false);
        $this->endsWith('Bar')->shouldBe(true);
        $this->endsWith(container(['Bar', 'ar']))->shouldBe(true);
    }

    function it_should_check_if_string_is_matching_pattern()
    {
        $this->is('.*')->shouldBe(true);
    }

    function it_should_remove_duplicated_values_at_the_end_and_leave_one()
    {
        $this->finish('r')->value()->shouldBe($this->init);

        $this->set('dir//')->finish('/')->value()->shouldBe('dir/');
    }

    function it_should_cut_by_words_count()
    {
        $this->set('lorem ipsum dolor foo bar')->limitWords(3)->value()->shouldBe('lorem ipsum dolor...');
    }

    function it_should_parse_callback_and_method()
    {
        $this->set('class@method')->parseCallback()->value()->shouldBe(['class', 'method']);
    }

    function it_should_return_random_string()
    {
        $this->random()->value()->shouldBeString();
    }

    function it_should_return_quick_random_string()
    {
        $this->quickRandom()->value()->shouldBeString();
    }

    function it_should_return_slug_with_ascii()
    {
        $match = (string) StaticStringy::slugify('Вот такой вот адрес');

        $this->set('Вот такой вот адрес')->slug()->value()->shouldBe($match);
    }

    function it_should_explode_value_in_container()
    {
        $explode = $this->split('B');

        $explode->shouldHaveType(Container::class);

        $explode->all()->shouldBe(['foo', 'ar']);
    }

    function it_should_implode_arrayable_to_value()
    {
        $this->join('', container(['foo', 'Bar']))->value()->shouldBe($this->init);

        $this->shouldThrow('InvalidArgumentException')->duringJoin('', true);
    }

    function it_should_trim_value_by_given_parameter()
    {
        $init = ' foo ';

        $this->set($init)->trim('front')->value()->shouldBe(ltrim($init));
        $this->set($init)->trim('back')->value()->shouldBe(rtrim($init));
        $this->set($init.' bar')->trim('all')->value()->shouldBe(trim($init).'bar');
        $this->set($init)->trim()->value()->shouldBe(trim($init));
    }

    function it_should_generate_random_uuid()
    {
        $uuid = $this->uuid();

        $uuid->value()->shouldBeString();

        $this->isUuid($uuid)->shouldBe(true);

        $this->set($uuid)->isUuid()->shouldBe(true);

        $this->uuid()->shouldNotBe($uuid);
    }

    function it_should_repeat_value()
    {
        $this->repeat(3)->value()->shouldBe(str_repeat($this->init, 3));
    }

    function it_should_shuffle_value()
    {
        $this->shuffle()->value()->shouldNotBe($this->init);
        $this->shuffle(false)->value()->shouldNotBe($this->init);
    }

    function it_should_strip_tags()
    {
        $tags = '
'.$this->init.'
';

        $this->set($tags)->stripTags()->value()->shouldBe(strip_tags($tags));
    }

    function it_should_encode_to_base64()
    {
        $_64 = $this->base64();

        $_64->value()->shouldBe(base64_encode($this->init));
    }

    function it_should_init_from_base64_to_valid_string()
    {
        $_64 = base64_encode($this->init);

        $this->fromBase64($_64)->value()->shouldBe($this->init);
    }

    function it_should_encode_html_entities()
    {
        $tags = '
'.$this->init.'
';

        $this->set($tags)->toEntities()->value()->shouldBe(htmlentities($tags));
    }

    function it_should_decode_html_entities()
    {
        $tags = '
'.$this->init.'
';

        $this->set($tags)->fromEntities()->value()->shouldBe(html_entity_decode($tags));

        $this->fromEntities($tags)->value()->shouldBe(html_entity_decode($tags));
    }

    function it_should_echo_value_with_append_and_prepend()
    {
        ob_start();

        $this->say('me', 'you');

        $said = ob_get_contents();

        $this->set($said)->value()->shouldBe('me'.$this->init.'you');

        ob_end_clean();
    }

    function it_should_echo_value()
    {
        ob_start();

        $this->say(new \stdClass(), new \stdClass());

        $said = ob_get_contents();

        $this->set($said)->value()->shouldBe($this->init);

        ob_end_clean();
    }

    function it_should_cut_value()
    {
        $this->cut(2)->value()->shouldBe(substr($this->init, 2));
        $this->cut(2, 1)->value()->shouldBe(substr($this->init, 2, 1));
    }

    function it_should_limit_letters_quantity_to_given()
    {
        $this->limit(3)->value()->shouldBe(substr($this->init, 0, 3).'...');
    }

    function it_should_limit_letters_quantity_to_given_but_check_for_words_cut()
    {
        $this->limitSafe(3)->value()->shouldBe('...');
    }

    function it_should_parse_vars_from_string()
    {
        $init = 'http://localhost:8000/?XDEBUG_SESSION_START=11857';

        $vars = $this->set($init)->toVars();

        $vars->shouldHaveType(Container::class);

        $expect = [];
        mb_parse_str($init, $expect);

        $vars->all()->shouldBe($expect);
    }

    function it_should_clean_string_from_tags_entities_and_trim()
    {
        $init = '
'.$this->init.'
& ';

        $this->set($init)->clean()->value()->shouldBe(trim(htmlentities(strip_tags($init))));
    }

    function it_should_reset_inner_string()
    {
        $this->reset()->value()->shouldBe('');
    }

    function it_should_compress_string()
    {
        $this->compress()->value()->shouldBe(gzcompress($this->init));
    }

    function it_should_decompress_string()
    {
        $str = gzcompress($this->init);

        $this->set($str)->decompress()->value()->shouldBe($this->init);

        $this->set($this->init)->decompress($str)->value()->shouldBe($this->init);
    }

    function it_should_return_encrypted_string()
    {
        $key = 'cypher';
        $expires = time() + 3600;

        $encrypted = $this->encrypt($key, $expires);

        $encrypted->shouldBeString();

        $payload = [
            'exp' => $expires,
            'string' => $this->init
        ];

        $encrypted->shouldBeEqualTo(JWT::encode($payload, $key));
    }

    function it_should_construct_from_encrypted_string()
    {
        $key = 'cypher';
        $expires = time() + 3600;

        $encrypted = $this->encrypt($key, $expires);

        $this->fromEncrypted($encrypted, $key)->all()->shouldBeEqualTo($this->init);
    }

    function it_should_return_length_of_string()
    {
        $this->length()->shouldBe(mb_strlen($this->init));
    }

    function it_should_return_inner_string()
    {
        $this->all()->shouldBe($this->init);
    }

    function it_should_get_file_contents_if_is_file()
    {
        $this->shouldThrow('im\Primitive\String\Exceptions\StringException')->duringContents();

        $this->set(__DIR__.'/../Container/data.json')->contents()->isJson()->shouldBe(true);
    }

    function it_should_check_if_string_is_empty()
    {
        $this->isEmpty()->shouldBe(false);

        $this->set('')->isEmpty()->shouldBe(true);
    }

    function it_should_check_if_string_is_not_empty()
    {
        $this->isNotEmpty()->shouldBe(true);

        $this->set('')->isNotEmpty()->shouldBe(false);
    }

    function it_should_check_if_string_is_alpha()
    {
        $this->isAlpha()->shouldBe(true);

        $this->set('123qwe')->isAlpha()->shouldBe(false);
    }

    function it_should_check_if_string_is_alphanumeric()
    {
        $this->isAlphanumeric()->shouldBe(true);

        $this->set('123qwe')->isAlphanumeric()->shouldBe(true);

        $this->set('./../')->isAlphanumeric()->shouldBe(false);
    }

    function it_should_check_if_string_is_whitespace_chars()
    {
        $this->isWhitespaces()->shouldBe(false);

        $this->set("\n\t  ")->isWhitespaces()->shouldBe(true);
    }

    function it_should_check_if_string_is_hexadecimal()
    {
        $this->isHex()->shouldBe(false);

        $this->set('2AF3')->isHex()->shouldBe(true);
    }

    function it_should_check_if_string_is_upper()
    {
        $this->isUpper()->shouldBe(false);

        $this->upper()->isUpper()->shouldBe(true);
    }

    function it_should_check_if_string_is_lower()
    {
        $this->isLower()->shouldBe(false);

        $this->lower()->isLower()->shouldBe(true);

        $this->upper()->isLower()->shouldBe(false);
    }

    function it_should_check_if_is_uuid()
    {
        $uuid = $this->uuid();

        $uuid->isUuid()->shouldBe(true);

        $this->set('asdaa234-sd34-df35-vd2f-ptuqwv45ct56')->isUuid()->shouldBe(false);
    }

    function it_should_check_if_is_json()
    {
        $this->isJson()->shouldBe(false);

        $this->set('{"name":"fooBar"}')->isJson()->shouldBe(true);
    }

    function it_should_check_if_is_file()
    {
        $this->isFile()->shouldBe(false);

        $this->set(__DIR__.'/../Container/data.json')->isFile()->shouldBe(true);
    }

    function it_should_check_if_is_serialized()
    {
        $this->isSerialized()->shouldBe(false);

        $this->set('a:4:{s:4:"name";s:4:"John";s:7:"surname";s:3:"Doe";s:5:"email";s:19:"johndoe@example.com";s:4:"wife";a:4:{s:4:"name";s:4:"Jane";s:7:"surname";s:3:"Doe";s:5:"email";s:19:"janedoe@example.com";s:5:"hobby";s:5:"music";}}
')->isSerialized()->shouldBe(true);
    }

    function it_should_auto_convert_to_string()
    {
        $this->__toString()->shouldBe($this->init);
    }

    /**
     * Abstract Type methods
     */

    function it_should_return_value_if_call_instance_like_function()
    {
        $this()->shouldBe($this->init);
    }

    function it_should_serialize()
    {
        $match = serialize($this->init);

        $this->serialize()->shouldBe($match);
    }

    function it_should_unserialize()
    {
        $serialized = serialize($this->init);

        $this->unserialize($serialized);
        $this->value()->shouldBe($this->init);
    }

    function it_should_make_new_instance()
    {
        $match = $this->init;

        $this->make($match)->value()->shouldBe($match);
    }

    function it_should_create_new_instance_statically()
    {
        $match = $this->init;

        static::create($match)->value()->shouldBe($match);
    }

    function it_should_have_helper_function_and_create_new_instance()
    {
        $match = $this->init;

        $this->set(string($match))->value()->shouldBe($match);
    }
}


<?php
/*
Copyright 2016 Thomas Bollmeier <entwickler@tbollmeier.de>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

namespace tbollmeier\parsian\input;

class ParseException extends \Exception
{
    /** Error codes */
    const NO_TOKEN = 1;
    const UNEXPECTED_TOKEN = 2;
    const OTHER_ERROR = 99;

    /**
     * Create parse exceptiion for missing token
     *
     * @param $tokenTypes
     * @return ParseException
     */
    public static function noTokenForTokenTypes($tokenTypes) : ParseException
    {
        $message = "No token could be found for any of types ";
        $message .= join(", ", $tokenTypes);

        return new ParseException($message, self::NO_TOKEN);
    }

    /**
     * Create parse exceptiion for missing token
     *
     * @param $tokenType
     * @return ParseException
     */
    public static function noTokenForTokenType($tokenType) : ParseException
    {
        $message = "No token could be found for type {$tokenType}";

        return new ParseException($message, self::NO_TOKEN);
    }

    public static function unexpectedToken(Token $token) : ParseException
    {
        $text = $token->getContent();
        $pos = $token->getStartPos();
        $line = $pos->line;
        $col = $pos->column;
        $message = "Unexpected token '{$text}' at line {$line}, column {$col}";

        return new ParseException($message, self::UNEXPECTED_TOKEN);
    }

    public static function createError($message) : ParseException
    {
        return new ParseException($message, self::OTHER_ERROR);
    }

}