<?php namespace Ordercloud\Support\Http;

use Exception;
use Ordercloud\OrdercloudException;

class OrdercloudHttpException extends OrdercloudException
{
    /**
     * @var Response
     */
    private $response;
    /**
     * @var Request
     */
    private $request;

    public function __construct(Response $response, Request $request, Exception $previousException = null)
    {
        $message = $response->getData('message', false);
        if ( ! $message) {
            $message = $previousException ? $previousException->getMessage() : 'Unkown error.';
        }

        parent::__construct($message, $response->getStatusCode(), $previousException);

        $this->response = $response;
        $this->request = $request;
    }

    /**
     * @param Response  $response
     * @param Exception $previousException
     *
     * @return static
     */
    public static function create(Response $response, Exception $previousException = null)
    {
        return new static($response, $response->getRequest(), $previousException);
    }

    /**
     * @return Response
     */
    public function getResponse()
    {
        return $this->response;
    }

    /**
     * @return Request
     */
    public function getRequest()
    {
        return $this->request;
    }
}


<?php
namespace Reaction\Validators;

use DateTime;
use IntlDateFormatter;
use Reaction;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Helpers\FormatConverter;
use Reaction\I18n\I18N;

/**
 * DateValidator verifies if the attribute represents a date, time or datetime in a proper [[format]].
 *
 * It can also parse internationalized dates in a specific [[locale]] like e.g. `12 мая 2014` when [[format]]
 * is configured to use a time pattern in ICU format.
 *
 * It is further possible to limit the date within a certain range using [[min]] and [[max]].
 *
 * Additional to validating the date it can also export the parsed timestamp as a machine readable format
 * which can be configured using [[timestampAttribute]]. For values that include time information (not date-only values)
 * also the time zone will be adjusted. The time zone of the input value is assumed to be the one specified by the [[timeZone]]
 * property and the target timeZone will be UTC when [[timestampAttributeFormat]] is `null` (exporting as UNIX timestamp)
 * or [[timestampAttributeTimeZone]] otherwise. If you want to avoid the time zone conversion, make sure that [[timeZone]] and
 * [[timestampAttributeTimeZone]] are the same.
 */
class DateValidator extends Validator
{
    /**
     * Constant for specifying the validation [[type]] as a date value, used for validation with intl short format.
     * @see type
     */
    const TYPE_DATE = 'date';
    /**
     * Constant for specifying the validation [[type]] as a datetime value, used for validation with intl short format.
     * @see type
     */
    const TYPE_DATETIME = 'datetime';
    /**
     * Constant for specifying the validation [[type]] as a time value, used for validation with intl short format.
     * @see type
     */
    const TYPE_TIME = 'time';

    /**
     * Formatter used for validation
     * @var Reaction\I18n\Formatter|Reaction\I18n\Request\Formatter
     */
    public $formatter;
    /**
     * @var string the type of the validator. Indicates, whether a date, time or datetime value should be validated.
     * This property influences the default value of [[format]] and also sets the correct behavior when [[format]] is one of the intl
     * short formats, `short`, `medium`, `long`, or `full`.
     *
     * This is only effective when the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed.
     *
     * This property can be set to the following values:
     *
     * - [[TYPE_DATE]] - (default) for validating date values only, that means only values that do not include a time range are valid.
     * - [[TYPE_DATETIME]] - for validating datetime values, that contain a date part as well as a time part.
     * - [[TYPE_TIME]] - for validating time values, that contain no date information.
     */
    public $type = self::TYPE_DATE;
    /**
     * @var string the date format that the value being validated should follow.
     * This can be a date time pattern as described in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax).
     *
     * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the PHP Datetime class.
     * Please refer to <http://php.net/manual/en/datetime.createfromformat.php> on supported formats.
     *
     * If this property is not set, the default value will be obtained from `Yii::$app->formatter->dateFormat`, see [[\yii\i18n\Formatter::dateFormat]] for details.
     * Default value will be determined from different formats of the formatter class,
     * dependent on the value of [[type]]:
     *
     * - if type is [[TYPE_DATE]], the default value will be taken from [[\yii\i18n\Formatter::dateFormat]],
     * - if type is [[TYPE_DATETIME]], it will be taken from [[\yii\i18n\Formatter::datetimeFormat]],
     * - and if type is [[TYPE_TIME]], it will be [[\yii\i18n\Formatter::timeFormat]].
     *
     * Here are some example values:
     *
     * ```php
     * 'MM/dd/yyyy' // date in ICU format
     * 'php:m/d/Y' // the same date in PHP format
     * 'MM/dd/yyyy HH:mm' // not only dates but also times can be validated
     * ```
     *
     * **Note:** the underlying date parsers being used vary dependent on the format. If you use the ICU format and
     * the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed, the [IntlDateFormatter](http://php.net/manual/en/intldateformatter.parse.php)
     * is used to parse the input value. In all other cases the PHP [DateTime](http://php.net/manual/en/datetime.createfromformat.php) class
     * is used. The IntlDateFormatter has the advantage that it can parse international dates like `12. Mai 2015` or `12 мая 2014`, while the
     * PHP parser is limited to English only. The PHP parser however is more strict about the input format as it will not accept
     * `12.05.05` for the format `php:d.m.Y`, but the IntlDateFormatter will accept it for the format `dd.MM.yyyy`.
     * If you need to use the IntlDateFormatter you can avoid this problem by specifying a [[min|minimum date]].
     */
    public $format;
    /**
     * @var string the locale ID that is used to localize the date parsing.
     * This is only effective when the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed.
     * If not set, the locale of the [[\yii\base\Application::formatter|formatter]] will be used.
     * See also [[\yii\i18n\Formatter::locale]].
     */
    public $locale;
    /**
     * @var string the timezone to use for parsing date and time values.
     * This can be any value that may be passed to [date_default_timezone_set()](http://www.php.net/manual/en/function.date-default-timezone-set.php)
     * e.g. `UTC`, `Europe/Berlin` or `America/Chicago`.
     * Refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available timezones.
     * If this property is not set, [[\yii\base\Application::timeZone]] will be used.
     */
    public $timeZone;
    /**
     * @var string the name of the attribute to receive the parsing result.
     * When this property is not null and the validation is successful, the named attribute will
     * receive the parsing result.
     *
     * This can be the same attribute as the one being validated. If this is the case,
     * the original value will be overwritten with the timestamp value after successful validation.
     *
     * Note, that when using this property, the input value will be converted to a unix timestamp,
     * which by definition is in UTC, so a conversion from the [[$timeZone|input time zone]] to UTC
     * will be performed. When defining [[$timestampAttributeFormat]] you can control the conversion by
     * setting [[$timestampAttributeTimeZone]] to a different value than `'UTC'`.
     *
     * @see timestampAttributeFormat
     * @see timestampAttributeTimeZone
     */
    public $timestampAttribute;
    /**
     * @var string the format to use when populating the [[timestampAttribute]].
     * The format can be specified in the same way as for [[format]].
     *
     * If not set, [[timestampAttribute]] will receive a UNIX timestamp.
     * If [[timestampAttribute]] is not set, this property will be ignored.
     * @see format
     * @see timestampAttribute
     */
    public $timestampAttributeFormat;
    /**
     * @var string the timezone to use when populating the [[timestampAttribute]]. Defaults to `UTC`.
     *
     * This can be any value that may be passed to [date_default_timezone_set()](http://www.php.net/manual/en/function.date-default-timezone-set.php)
     * e.g. `UTC`, `Europe/Berlin` or `America/Chicago`.
     * Refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available timezones.
     *
     * If [[timestampAttributeFormat]] is not set, this property will be ignored.
     * @see timestampAttributeFormat
     */
    public $timestampAttributeTimeZone = 'UTC';
    /**
     * @var int|string upper limit of the date. Defaults to null, meaning no upper limit.
     * This can be a unix timestamp or a string representing a date time value.
     * If this property is a string, [[format]] will be used to parse it.
     * @see tooBig for the customized message used when the date is too big.
     */
    public $max;
    /**
     * @var int|string lower limit of the date. Defaults to null, meaning no lower limit.
     * This can be a unix timestamp or a string representing a date time value.
     * If this property is a string, [[format]] will be used to parse it.
     * @see tooSmall for the customized message used when the date is too small.
     */
    public $min;
    /**
     * @var string user-defined error message used when the value is bigger than [[max]].
     */
    public $tooBig;
    /**
     * @var string user-defined error message used when the value is smaller than [[min]].
     */
    public $tooSmall;
    /**
     * @var string user friendly value of upper limit to display in the error message.
     * If this property is null, the value of [[max]] will be used (before parsing).
     */
    public $maxString;
    /**
     * @var string user friendly value of lower limit to display in the error message.
     * If this property is null, the value of [[min]] will be used (before parsing).
     */
    public $minString;

    /**
     * @var array map of short format names to IntlDateFormatter constant values.
     */
    private $_dateFormats = [
        'short' => 3, // IntlDateFormatter::SHORT,
        'medium' => 2, // IntlDateFormatter::MEDIUM,
        'long' => 1, // IntlDateFormatter::LONG,
        'full' => 0, // IntlDateFormatter::FULL,
    ];

    /**
     * {@inheritdoc}
     */
    public function init()
    {
        parent::init();
        if ($this->message === null) {
            $this->message = Reaction::t('rct', 'The format of {attribute} is invalid.');
        }
        if ($this->format === null) {
            if ($this->type === self::TYPE_DATE) {
                $this->format = $this->getFormatter()->dateFormat;
            } elseif ($this->type === self::TYPE_DATETIME) {
                $this->format = $this->getFormatter()->datetimeFormat;
            } elseif ($this->type === self::TYPE_TIME) {
                $this->format = $this->getFormatter()->timeFormat;
            } else {
                throw new InvalidConfigException('Unknown validation type set for DateValidator::$type: ' . $this->type);
            }
        }
        if ($this->locale === null) {
            $this->locale = Reaction::$app->language;
        }
        if ($this->timeZone === null) {
            $this->timeZone = Reaction::$app->timeZone;
        }
        if ($this->min !== null && $this->tooSmall === null) {
            $this->tooSmall = Reaction::t('rct', '{attribute} must be no less than {min}.');
        }
        if ($this->max !== null && $this->tooBig === null) {
            $this->tooBig = Reaction::t('rct', '{attribute} must be no greater than {max}.');
        }
        if ($this->maxString === null) {
            $this->maxString = (string)$this->max;
        }
        if ($this->minString === null) {
            $this->minString = (string)$this->min;
        }
        if ($this->max !== null && is_string($this->max)) {
            $timestamp = $this->parseDateValueFormat($this->max, $this->format);
            if ($timestamp === false) {
                throw new InvalidConfigException("Invalid max date value: {$this->max}");
            }
            $this->max = $timestamp;
        }
        if ($this->min !== null && is_string($this->min)) {
            $timestamp = $this->parseDateValueFormat($this->min, $this->format);
            if ($timestamp === false) {
                throw new InvalidConfigException("Invalid min date value: {$this->min}");
            }
            $this->min = $timestamp;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function validateAttribute($model, $attribute)
    {
        $value = $model->$attribute;
        if ($this->isEmpty($value)) {
            if ($this->timestampAttribute !== null) {
                $model->{$this->timestampAttribute} = null;
            }
            return;
        }

        $timestamp = $this->parseDateValueFormat($value, $this->format);
        if ($timestamp === false) {
            if ($this->timestampAttribute === $attribute) {
                if ($this->timestampAttributeFormat === null) {
                    if (is_int($value)) {
                        return;
                    }
                } else {
                    if ($this->parseDateValueFormat($value, $this->timestampAttributeFormat) !== false) {
                        return;
                    }
                }
            }
            $this->addError($model, $attribute, $this->message, []);
        } elseif ($this->min !== null && $timestamp < $this->min) {
            $this->addError($model, $attribute, $this->tooSmall, ['min' => $this->minString]);
        } elseif ($this->max !== null && $timestamp > $this->max) {
            $this->addError($model, $attribute, $this->tooBig, ['max' => $this->maxString]);
        } elseif ($this->timestampAttribute !== null) {
            if ($this->timestampAttributeFormat === null) {
                $model->{$this->timestampAttribute} = $timestamp;
            } else {
                $model->{$this->timestampAttribute} = $this->formatTimestamp($timestamp, $this->timestampAttributeFormat);
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function validateValue($value)
    {
        $timestamp = $this->parseDateValueFormat($value, $this->format);
        if ($timestamp === false) {
            return [$this->message, []];
        } elseif ($this->min !== null && $timestamp < $this->min) {
            return [$this->tooSmall, ['min' => $this->minString]];
        } elseif ($this->max !== null && $timestamp > $this->max) {
            return [$this->tooBig, ['max' => $this->maxString]];
        }

        return null;
    }

    /**
     * Parses date string into UNIX timestamp.
     *
     * @param string $value string representing date
     * @param string $format expected date format
     * @return int|false a UNIX timestamp or `false` on failure.
     */
    private function parseDateValueFormat($value, $format)
    {
        if (is_array($value)) {
            return false;
        }
        if (strncmp($format, 'php:', 4) === 0) {
            $format = substr($format, 4);
        } else {
            if (extension_loaded('intl')) {
                return $this->parseDateValueIntl($value, $format);
            }

            // fallback to PHP if intl is not installed
            $format = FormatConverter::convertDateIcuToPhp($format, 'date');
        }

        return $this->parseDateValuePHP($value, $format);
    }

    /**
     * Parses a date value using the IntlDateFormatter::parse().
     * @param string $value string representing date
     * @param string $format the expected date format
     * @return int|bool a UNIX timestamp or `false` on failure.
     * @throws InvalidConfigException
     */
    private function parseDateValueIntl($value, $format)
    {
        if (isset($this->_dateFormats[$format])) {
            if ($this->type === self::TYPE_DATE) {
                $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, 'UTC');
            } elseif ($this->type === self::TYPE_DATETIME) {
                $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], $this->_dateFormats[$format], $this->timeZone);
            } elseif ($this->type === self::TYPE_TIME) {
                $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, $this->_dateFormats[$format], $this->timeZone);
            } else {
                throw new InvalidConfigException('Unknown validation type set for DateValidator::$type: ' . $this->type);
            }
        } else {
            // if no time was provided in the format string set time to 0 to get a simple date timestamp
            $hasTimeInfo = (strpbrk($format, 'ahHkKmsSA') !== false);
            $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $hasTimeInfo ? $this->timeZone : 'UTC', null, $format);
        }
        // enable strict parsing to avoid getting invalid date values
        $formatter->setLenient(false);

        // There should not be a warning thrown by parse() but this seems to be the case on windows so we suppress it here
        // See https://github.com/yiisoft/yii2/issues/5962 and https://bugs.php.net/bug.php?id=68528
        $parsePos = 0;
        $parsedDate = @$formatter->parse($value, $parsePos);
        if ($parsedDate === false || $parsePos !== mb_strlen($value, Reaction::$app ? Reaction::$app->charset : 'UTF-8')) {
            return false;
        }

        return $parsedDate;
    }

    /**
     * Parses a date value using the DateTime::createFromFormat().
     * @param string $value string representing date
     * @param string $format the expected date format
     * @return int|bool a UNIX timestamp or `false` on failure.
     */
    private function parseDateValuePHP($value, $format)
    {
        // if no time was provided in the format string set time to 0 to get a simple date timestamp
        $hasTimeInfo = (strpbrk($format, 'HhGgisU') !== false);

        $date = DateTime::createFromFormat($format, $value, new \DateTimeZone($hasTimeInfo ? $this->timeZone : 'UTC'));
        $errors = DateTime::getLastErrors();
        if ($date === false || $errors['error_count'] || $errors['warning_count']) {
            return false;
        }

        if (!$hasTimeInfo) {
            $date->setTime(0, 0, 0);
        }

        return $date->getTimestamp();
    }

    /**
     * Formats a timestamp using the specified format.
     * @param int $timestamp
     * @param string $format
     * @return string
     */
    private function formatTimestamp($timestamp, $format)
    {
        if (strncmp($format, 'php:', 4) === 0) {
            $format = substr($format, 4);
        } else {
            $format = FormatConverter::convertDateIcuToPhp($format, 'date');
        }

        $date = new DateTime();
        $date->setTimestamp($timestamp);
        $date->setTimezone(new \DateTimeZone($this->timestampAttributeTimeZone));
        return $date->format($format);
    }

    /**
     * Get formatter
     * @return Reaction\I18n\Formatter|Reaction\I18n\Request\Formatter
     */
    protected function getFormatter()
    {
        if ($this->formatter === null) {
            $this->formatter = Reaction::$app->formatter;
        }
        return $this->formatter;
    }
}


<?php
/**
 * This file is part of the CarteBlanche PHP framework.
 *
 * (c) Pierre Cassat <me@e-piwi.fr> and contributors
 *
 * License Apache-2.0 <http://github.com/php-carteblanche/carteblanche/blob/master/LICENSE>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CarteBlanche\Library\AutoObject;

use \CarteBlanche\CarteBlanche;
use \CarteBlanche\App\Locator;
use \Patterns\Abstracts\AbstractSingleton;
use \Patterns\Commons\Registry;

/**
 */
class AutoObjectMapper extends AbstractSingleton
{

    protected $registry;

    protected function init()
    {
        $this->registry = new Registry;
        $this->registry->setEntry('entityManager', array());
        $this->registry->setEntry('objectStructure', array());
    }

    /**
     * Get an entityManager
     * @param string $emname The name of the entity manager to search
     * @return object Returns an object to manage the entity
     */
    static function getEntityManager($emname)
    {
        $_this = self::getInstance();
        $emname = $_this->buildEntityName($emname);

        $known_manager = $_this->registry->getEntry($emname, 'entityManager');
        if ($known_manager) {
            return $known_manager;
        } else {
    //			$manager = $_this->buildEntityManager($emname);
            $manager = CarteBlanche::getContainer()->get('entity_manager')
                ->getStorageEngine($emname);
            $_this->registry->setEntry($emname, $manager, 'entityManager');
            return $manager;
        }
    }

    /**
     * Get the objects structure from a specific database
     * @param string $dbname The name of the database to search
     * @return array Returns an array of the objects structure (FALSE if nothing is found)
     */
    static function getObjectsStructure($dbname = null)
    {
        $_this = self::getInstance();
        $dbname = $_this->buildEntityName($dbname);

        $known_structure = $_this->registry->getEntry($dbname, 'objectStructure');
        if ($known_structure) {
            return $known_structure;
        } else {
            $structure = $_this->buildObjectsStructure($dbname);
            $_this->registry->setEntry($dbname, $structure, 'objectStructure');
            return $structure;
        }
    }

    /**
     * Get a table entry from a specific database
     * @param string $tablename The name of the table to search
     * @param string $dbname The name of the database to search
     * @return array Returns an array of the table structure (FALSE if nothing is find)
     */
    static function getAutoObject($tablename = null, $dbname = null)
    {
        if (empty($tablename)) return false;
        $tables = self::getObjectsStructure( $dbname );
        if ($tables) {
            foreach ($tables as $_tbl_name=>$_tbl_obj) {
                if ($_tbl_obj->getTableName()==$tablename) {
                    return $_tbl_obj;
                }
            }
        }
        return false;
    }

    /**
     * Get a table structure from a specific database
     * @param string $tablename The name of the table to search
     * @param string $dbname The name of the database to search
     * @return array Returns an array of the table structure (FALSE if nothing is find)
     */
    static function getTableStructure($tablename = null, $dbname = null)
    {
        $_tbl_obj = self::getAutoObject( $tablename, $dbname );
        if (!empty($_tbl_obj)) {
            return $_tbl_obj->getStructureEntry('structure');
        }
        return false;
    }

    /**
     * Get an auto-object model
     * @param string $tablename The name of the table to search
     * @param string $dbname The name of the database to search
     * @return array Returns an instance of the model (FALSE if nothing is find)
     */
    static function getModel($tablename = null, $dbname = null)
    {
        $_tbl_obj = self::getAutoObject( $tablename, $dbname );
        if (!empty($_tbl_obj)) {
            return $_tbl_obj->getModel();
        }
        return false;
    }

    /**
     * Get an auto-object fields list organized by fields types
     * @param string $tablename The name of the table to search
     * @param string $dbname The name of the database to search
     * @return array Returns an array of the fields organized by type (FALSE if nothing is find)
     */
    static function getFieldsByType($tablename = null, $dbname = null)
    {
        $_tbl_obj = self::getAutoObject( $tablename, $dbname );
        if (!empty($_tbl_obj)) {
            return $_tbl_obj->getFieldsByType();
        }
        return false;
    }

    /**
     * Get an auto-object relations array
     * @param string $tablename The name of the table to search
     * @param string $dbname The name of the database to search
     * @return array Returns an array of the relations of the object (FALSE if nothing is find)
     */
    static function getRelations($tablename = null, $dbname = null)
    {
        $_tbl_obj = self::getAutoObject( $tablename, $dbname );
        if (!empty($_tbl_obj)) {
            return $_tbl_obj->getRelations();
        }
        return false;
    }

// ------------------
// Entities Builders
// ------------------

    /**
     * Transform the name of an entity (skipping '..._db' and '..._em' suffix or retrieving it if '..._base')
     * @param string $dbname The name of the database to search
     * @return string The re-formed name if so
     */
    protected function buildEntityName($name = null)
    {
        if (empty($name)) {
            $_name = CarteBlanche::getContainer()->get('request')->getUrlArg('altdb');
            if (!empty($_name))
                $name = $_name;
            else
                $name = 'default';
        }
        if (substr_count($name, '_base')) {
            $_name = CarteBlanche::getKernel()->getRegistry()->getStackKey( $name, 'db_name', 'config' );
            if (empty($_name))
                $_name = CarteBlanche::getKernel()->getRegistry()->getStackKey( $name, 'db_name', 'app' );
            if (!empty($_name))
                $name = $_name;
        }
        return str_replace(array('_database', '_entity_manager', '_base'), '', $name);
    }

    /**
     * Build a specific entity manager
     * @param string $emname The name of the entity manager to build
     * @return object Returns an object to manage the entity
     */
    protected function buildEntityManager($emname = 'default')
    {
        $em_cfg = CarteBlanche::getConfig($emname.'_entity_manager');

        if (!isset($em_cfg['class'])) {
            throw new \RuntimeException(
                'An entity manager configuration must define a class name!'
            );
        }
        $em_class = $em_cfg['class'];

        if (!isset($em_cfg['options'])) {
            throw new \RuntimeException(
                'An entity manager configuration must define an options array!'
            );
        }

        if (\CarteBlanche\App\Loader::classExists($em_class)) {
            try {
                $em = new $em_class( $em_cfg['options'] );
            } catch ( \Exception $e ) {
                throw new \RuntimeException(
                    sprintf('An error occurred while trying to load entity manager "%s"!', $em_class)
                );
            }
            if (!($em instanceof \CarteBlanche\Interfaces\EntityManagerInterface)) {
                throw new \DomainException(
                    sprintf('An entity manager must implements the "\CarteBlanche\Interfaces\EntityManagerInterface" interface (in "%s")!', $em_class)
                );
            }
        } else {
            throw new \RuntimeException(
                sprintf('Entity manager named "%s" doesn\'t exist!', $em_class)
            );
        }
        return $em;
    }

    /**
     * Build the objects structure from a specific entity
     * @param string $dbname The name of the database to build
     * @return array Returns an array of the objects structure (FALSE if nothing is found)
     */
    protected function buildObjectsStructure($dbname = null)
    {
        $dbname = str_replace(array(CarteBlanche::getPath('root_path'), CarteBlanche::getPath('config_dir')), '', $dbname);
        $tables_def = CarteBlanche::getConfig($dbname.'_database.db_structure');
        $tables_def_file = Locator::locateConfig($tables_def);

        if ($tables_def_file && @file_exists($tables_def_file) && @is_file($tables_def_file)) {
            $table = array();
            include $tables_def_file;
            if (!empty($tables)) {
                $tables_stacks=array();
                foreach ($tables as $_tbl) {
                    $_t_n = $_tbl['table'];
                    $tables_stacks[$_t_n] = new \CarteBlanche\Library\AutoObject\AutoObject( $_t_n, $_tbl, $_t_n, $dbname );
                    $this->registry->setEntry(
                        $_tbl['table'],
                        $tables_stacks[$_t_n],
                        $dbname
                    );
                }
                return $tables_stacks;
            } else
                throw new \RuntimeException(
                    sprintf('Tables definition can\'t be found in file "%s"!', $tables_def)
                );
        } else
            throw new \RuntimeException(
                sprintf('Tables definition file "%s" can\'t be found!', $tables_def)
            );
    }

}

// Endfile


<?php

/**
 * Jin Framework
 * Diatem
 */

namespace Jin2\Form\Validators;

use Jin2\Language\Translation;

/**
 * Validateur : teste si le nombre de caractères du valeur entre dans une plage autorisée
 */
class Length extends AbstractValidator
{

  /**
   * Constructeur
   *
   * @param type $args    Tableau d'arguments. (min : nombre max de caractères (-1 : pas de minimum) max : nombre max de caractères (-1 : pas de maximum)
   */
  public function __construct($args)
  {
    parent::__construct($args, array('min', 'max'));
  }

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

  /**
   * Teste la validité
   *
   * @param mixed $valeur Valeur à tester
   * @return boolean
   */
  public function isValid($valeur)
  {
    parent::resetErrors();

    $min = $this->getArgValue('min');
    $max = $this->getArgValue('max');

    if ($min == $max) {
      if (strlen($valeur) != $min) {
        parent::addError($this->prepareError('valisatorerror_length_exact'));
        return false;
      }
    } else if ($min == -1) {
      if (strlen($valeur) > $max) {
        parent::addError($this->prepareError('valisatorerror_length_max'));
        return false;
      }
    } else if ($max == -1) {
      if (strlen($valeur) < $min) {
        parent::addError($this->prepareError('valisatorerror_length_min'));
        return false;
      }
    } else {
      if (strlen($valeur) < $min || strlen($valeur) > $max) {
        parent::addError($this->prepareError('valisatorerror_length_range'));
        return false;
      }
    }

    return true;
  }

  /**
   * Formatte un texte d'erreur
   *
   * @param string $code  Code erreur (cf. fichier langue formvalidators.ini)
   * @return string
   */
  protected function prepareError($code)
  {
    $min = $this->getArgValue('min');
    $max = $this->getArgValue('max');
    $error = Translation::get($code);
    $error = str_replace('%min%', $min, $error);
    $error = str_replace('%max%', $max, $error);
    return $error;
  }

}


<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateKeylistsTables extends Migration
{

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('keytypes', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name', 50);
            $table->longText('description')->nullable();
            $table->longText('extended_data')->nullable();
            $table->string('created_by')->nullable();
            $table->string('updated_by')->nullable();
            $table->timestamps();
            $table->softDeletes();

            $table->unique('name');
        });

        Schema::create('keyvalues', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('keytype_id')->unsigned();
            $table->string('keyvalue', 255);
            $table->string('keyname', 255);
            $table->longText('description')->nullable();
            $table->longText('extended_data')->nullable();
            $table->string('created_by')->nullable();
            $table->string('updated_by')->nullable();
            $table->timestamps();
            $table->softDeletes();

            $table->unique(['keytype_id', 'keyvalue']);

            $table->foreign('keytype_id')
                ->references('id')->on('keytypes')
                ->onDelete('cascade')
                ->onUpdate('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('keyvalues');
        Schema::drop('keytypes');
    }
}


<?php namespace Ordercloud\Entities\Products;

use JsonSerializable;

class ProductPriceDiscount implements JsonSerializable
{
    /**
     * The amount of discount
     * @var float
     */
    private $amount;
    /**
     * Item price befor discount
     * @var float
     */
    private $originalPrice;

    /**
     * Percentage discount of the price
     * @var float
     */
    private $percentage;

    /**
     * Percentage discount descritpion
     * @var String
     */
    private $description;

    /**
     * Is the discount by the product owner
     * @var Boolean
     */
    private $productOwner;

    public function __construct($amount, $originalPrice, $percentage , $description, $productOwner)
    {
        $this->amount = $amount;
        $this->originalPrice =  $originalPrice;
        $this->percentage=  $percentage;
        $this->description =  $description;
        $this->productOwner = $productOwner;
    }

    /**
     * @return float
     */
    public function getAmount()
    {
        return $this->amount;
    }

    /**
     * @return float
     */
    public function getOriginalPrice()
    {
        return $this->originalPrice;
    }

    /**
     * @return float
     */
    public function getPercentage()
    {
        return $this->percentage;
    }

    /**
     * @return String
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * @return Boolean
     */
    public function getProductOwner()
    {
        return $this->productOwner;
    }

    /**
     * Specify data which should be serialized to JSON
     */
    public function jsonSerialize()
    {
        return [
            'amount' => $this->getAmount(),
            'description' => $this->getDescription(),
            'originalPrice' => $this->getOriginalPrice(),
            'percentage' => $this->getPercentage(),
            'productOwner' => $this->productOwner()
        ];
    }
}


<?php
/*
 * This file is a part of Solve framework.
 *
 * @author Alexandr Viniychuk <alexandr.viniychuk@icloud.com>
 * @copyright 2009-2014, Alexandr Viniychuk
 * created: 07.05.14 16:53
 */

namespace Solve\Database\Adapters;
use Solve\Database\QC;
use Solve\Database\Exceptions\MysqlDBAdapterException;

require_once 'BaseDBAdapter.php';
require_once dirname(__FILE__) . '/../Exceptions/MysqlDBAdapterException.php';

/**
 * Class MysqlDBAdapter
 * @package Solve\Database\Adapters
 *
 * @changed
 * Class MysqlDBAdapter is used to ...
 *
 * @version 1.0
 * @author Alexandr Viniychuk <alexandr.viniychuk@icloud.com>
 */
class MysqlDBAdapter extends BaseDBAdapter {

    private $_pregParametricParams      = null;
    private $_pregParametricCounter     = 1;

    /**
     * @var \PDO connection
     */
    private $_dbh                       = null;

    public function connect($options) {
        if (!extension_loaded('pdo')) throw new \Exception('PDO extension is not loaded.');
        try {
            $this->_dbh = new \PDO(($dsn = self::compileDSN($options)), $options['user'], $options['pass']);
            $this->_dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        } catch(\PDOException $e) {
            throw new MysqlDBAdapterException('Database connection error, check access to '.(empty($options['name']) ? "(empty profile)" : $options['name']) . "\n".$e->getMessage());
        }

        try {
            if (!empty($options['name'])) {
                $this->_dbh->query('USE '.$options['name']);
            }
            $this->_dbh->setAttribute(\PDO::ATTR_AUTOCOMMIT , true);
            if (empty($options['charset'])) $options['charset'] = 'utf8';
            $this->_dbh->query('SET NAMES '.$options['charset']);
        } catch (\PDOException $e) {
            throw new MysqlDBAdapterException('Database connection error, check access to '.$options['name']."\n".$e->getMessage());
        }

        return true;
    }

    /**
     * Execute query
     *
     * @param QC $query
     * @throws MysqlDBAdapterException
     */
    public function executeQuery(QC $query) {
        $type   = $query->getType();
        $methodName = 'execute' . ucfirst($type);
        if (method_exists($this, $methodName)) {
            $result = $this->$methodName($query);
        } else {
            throw new MysqlDBAdapterException('Invalid method specified: '.$type);
        }

        return $result;
    }

    /**
     * Process query to SQL
     * @param QC $qc
     * @param mixed $type
     * @return mixed
     * @throws MysqlDBAdapterException
     */
    public function buildQuery(QC $qc, $type = null) {
        if (!$type) $type = $qc->getType();

        $methodName = 'build' . ucfirst($type);
        if (method_exists($this, $methodName)) {
            $result = $this->$methodName($qc);
        } else {
            throw new MysqlDBAdapterException('Invalid method specified: '.$type);
        }
        return $result;
    }

    private function buildSelect(QC $q) {
        if ($q->getModifier('rawSelect')) {
            $sqlArray = $q->getModifier('rawSelect');
            return $sqlArray[0];
        }

        $sql = 'SELECT ';

        $fields = $q->getQueryParams('fields');
        if (empty($fields)) {
            $fields = '*';
        } else {
            $fields = $this->escapeSqlName($fields);
        }
        $sql .= $fields . ' FROM ';
        $sql .= $this->escapeSqlName($this->requireTable($q));

        $joins = $q->getJoins();
        if (!empty($joins)) {
            $sql .= ' ';
            foreach($joins as $type => $list) {
                foreach($list as $join) {
                    $sql .= strtoupper($type) . ' JOIN '. $join[0]
                        .(strpos($join[1], ' ') === false ? ' USING ('.$this->escapeSqlName($join[1]) : ' ON ('.$join[1]).')';
                }
            }
        }

        $c = $q->getCriteria();
        if (!empty($c)) {
            $sql .= ' WHERE ' . $this->processCriteria($c);
        }
        $sql .= $this->processModifiers($q);
        return $sql;
    }

    /**
     * @param \PDOStatement $res
     * @return array
     */
    public function fetchSelectResult($res) {
        return $res->rowCount() ? $res->fetchAll(\PDO::FETCH_ASSOC) : array();
    }

    private function executeSelect(QC $q) {
        $sql = $this->buildSelect($q);

        $res = $this->_dbh->query($sql);
        return $this->fetchSelectResult($res);
    }

    private function buildInsert(QC $q) {
        $sql = 'INSERT INTO' . ' ' . $this->escapeSqlName($q->getTables()) . ' ';

        $keys = array();
        $data = $q->getQueryParams('data');
        if (count($data)) {
            if (!array_key_exists(0, $data)) {
                $data = array($data);
            }
            foreach($data as $i=>$item) {
                if (!is_array($item)) continue;

                if (array_key_exists(0, $item)) {
                    unset($data[$i]);
                    foreach($item as $sub_item) {
                        $keys = array_merge($keys, array_keys($sub_item));
                        $data[] = $sub_item;
                    }
                } else {
                    $keys = array_merge($keys, array_keys($item));
                }
            }
            $keys = array_unique($keys);
            if (count($keys)) {
                $sql .= '(`'.implode('`, `',$keys).'`) VALUES ';
                foreach($data as $item) {
                    $sql .= '(';
                    foreach($keys as $key) {
                        $sql .= (isset($item[$key]) ? $this->escapeOne($item[$key]) : '""').", ";
                    }
                    $sql = substr($sql, 0, -2).'), ';
                }
            } else {
                $sql.= 'SET ';
                foreach($q->getQueryParams('data') as $item) $sql.= $item.',';
            }
            $sql = substr($sql, 0, -2);
        } else {
            $sql .= '() VALUES ()';
        }
        $sql .= $this->processModifiers($q);

        return $sql;
    }

    private function executeInsert(QC $q) {
        $sql = $this->buildInsert($q);
        $res = $this->_dbh->query($sql);
        return $res ? $this->_dbh->lastInsertId() : false;
    }

    private function buildReplace(QC $q) {
        $sql = $this->buildInsert($q);
        $sql = str_replace('INSERT', 'REPLACE', $sql);

        return $sql;
    }

    private function executeReplace(QC $q) {
        $sql = $this->buildReplace($q);
        $res = $this->_dbh->query($sql);
        return $res ? $this->_dbh->lastInsertId() : false;
    }

    private function buildUpdate(QC $q) {
//        var_dump($q->getQueryParams('data'));die();
        $sql = 'UPDATE ' . $this->escapeSqlName($q->getTables())
            .' SET '.$this->processData($q->getQueryParams('data'), ', ');
        $c = $q->getCriteria();
        if (!empty($c)) {
            $sql .= ' WHERE ' . $this->processCriteria($c);
        }
        $sql .= $this->processModifiers($q);
        return $sql;
    }

    private function executeUpdate(QC $q) {
        $sql = $this->buildUpdate($q);
        $res = $this->_dbh->query($sql);
        return $res ? $res->rowCount() : false;
    }

    private function buildDelete(QC $q) {
        $sql = 'DELETE FROM' . ' ' . $this->escapeSqlName($q->getTables());

        $c = $q->getCriteria();
        if (!empty($c)) {
            $sql .= ' WHERE ' . $this->processCriteria($c);
        }
        $sql .= $this->processModifiers($q);

        return $sql;
    }

    private function executeDelete(QC $q) {
        $sql = $this->buildDelete($q);
        $res = $this->_dbh->query($sql);
        return $res ? $res->rowCount() : false;
    }

    private function requireTable(QC $q) {
        if (!($tables = $q->getTables())) {
            throw new MysqlDBAdapterException('This query requires a table to be specified');
        }
        return $tables;
    }

    private function processModifiers(QC $q) {
        $sql = '';
        if (($groupBy = $q->getModifier('groupBy'))) $sql .= ' GROUP BY ' . $this->escapeSqlName($groupBy[0]);
        if (($orderBy = $q->getModifier('orderBy'))) $sql .= ' ORDER BY ' . $this->escapeSqlName($orderBy[0]);
        if ($q->getModifier('one')) {
            $sql .= ' LIMIT 1';
        } elseif(($limit = $q->getModifier('limit'))) {
            if (count($limit) > 1) $limit[0] = implode(', ', $limit);
            $sql .= ' LIMIT '.$limit[0];
        }
        return $sql;
    }

    private function processCriteria($params) {
        $sql = '';
        foreach($params as $p) {
            if (!empty($p['isComplex'])) {
                $sql .= ' '.strtoupper($p['method']) . ' ' . $this->processCriteria($p['params']);
            } else {
                $sql .= ' '.strtoupper($p['method']) . ' (' . $this->processParametricCondition($p['params']) . ')';
            }
        }
        $sql = '(' . substr($sql, strlen($params[0]['method']) + 2) . ')';

        return $sql;
    }

    private function processData($data, $glue = ',') {
        $sql = '';
        if (array_key_exists(0, $data)) {
            $sql .= $this->processParametricCondition($data);
        } else {
            foreach($data as $field => $value) {
                if (is_array($value)) throw new MysqlDBAdapterException('You tried to set array as a value in data part');
                $sql .=  $glue . ' ' . $this->processParametricCondition(array($field => $value));
            }
            $sql = substr($sql, strlen($glue) + 1);
        }

        return $sql;
    }

    public function executeSQL($sql) {
        return $this->_dbh->query($sql);
    }

    private function processParametricCondition($condition) {
        $sql = '';
        if (count($condition) > 1) {
            if ($this->isValidSQLIdentifier($condition[0])) {
                $sql = $this->escapeSqlName($condition[0]);
                if (is_array($condition[1])) {
                    $sql .= ' IN (' . $this->escape($condition[1]);
                } else {
                    $sql .= ' = ' . $this->escapeOne($condition[1]);
                }
            } else {
                $savedParams = $this->_pregParametricParams;
                $this->_pregParametricParams = $condition;
                $sql = preg_replace_callback('#:[dfsbna\?]#', array($this, 'onPregParameterCallback'), $condition[0]);
                $this->_pregParametricParams = $savedParams;
                $this->_pregParametricCounter = 1;
            }
        } else {
            if (array_key_exists(0, $condition) && is_string($condition[0])) {
                $sql .= $condition[0];
            } else {
                if (array_key_exists(0, $condition)) {
                    $condition = $condition[0];
                }
                foreach($condition as $key=>$value) {
                    if (is_scalar($value) || is_null($value)) {
                        $sql .=  $this->escapeSqlName($key) . ' = ' . $this->escapeOne($value);
                    } else {
                        $sql .=  $this->escapeSqlName($key) . ' IN (' . $this->escape($value) . ')';
                    }
                    $sql .= ' AND ';
                }
                $sql = substr($sql, 0, -5);
            }
        }
        return $sql;
    }

    private function onPregParameterCallback($params) {
        if (array_key_exists($this->_pregParametricCounter, $this->_pregParametricParams)) {
            if ($params[0] == ':d') {
                return intval($this->_pregParametricParams[$this->_pregParametricCounter++]);
            } elseif ($params[0] == ':f') {
                return floatval($this->_pregParametricParams[$this->_pregParametricCounter++]);
            } elseif ($params[0] == ':s') {
                return $this->escapeOne($this->_pregParametricParams[$this->_pregParametricCounter++], 'string');
            } elseif ($params[0] == ':?') {
                return substr($this->escapeOne($this->_pregParametricParams[$this->_pregParametricCounter++], 'string'), 1, -1);
            }
        } else {
            throw new MysqlDBAdapterException('Invalid parameters count for parametric query');
        }
    }

    /**
     * Escape on value using database driver specific
     *
     * @param mixed $value to be escaped
     * @param mixed $type force type definition
     * @return mixed escaped
     */
    protected function escapeOne($value, $type = false) {
        if ($type === false) {
            $type = gettype($value);
        }
        if (strpos($value, '#sql#') !== false) {
            return substr($value, 5);
        }
        if (in_array($type, array('integer'))) {
            return $value;
        } elseif ($type == 'boolean') {
            return intval($value);
        } elseif ($type == 'NULL') {
            return 'null';
        } else {
            return $this->_dbh->quote($value);
        }
    }

    public function __destruct() {
    }

}


<?php

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

namespace Valkyrja\Http;

use Valkyrja\Application;
use Valkyrja\Http\Exceptions\HttpRedirectException;
use Valkyrja\Http\Exceptions\InvalidStatusCodeException;
use Valkyrja\Support\Providers\Provides;

/**
 * Class RedirectResponse.
 *
 * @author Melech Mizrachi
 */
class NativeRedirectResponse extends NativeResponse implements RedirectResponse
{
    use Provides;

    /**
     * The uri to redirect to.
     *
     * @var string
     */
    protected $uri;

    /**
     * RedirectResponse constructor.
     *
     * @param string $content [optional] The response content, see setContent()
     * @param int    $status  [optional] The response status code
     * @param array  $headers [optional] An array of response headers
     * @param string $uri     [optional] The URI to redirect to
     *
     * @throws \InvalidArgumentException
     * @throws \Valkyrja\Http\Exceptions\InvalidStatusCodeException
     */
    public function __construct(
        string $content = '',
        int $status = StatusCode::FOUND,
        array $headers = [],
        string $uri = null
    ) {
        // Use the parent constructor to setup the class
        parent::__construct($content, $status, $headers);

        // If the status code set is not a redirect code
        if (! $this->isRedirect()) {
            // Throw an invalid status code exception
            throw new InvalidStatusCodeException(
                "Status code of \"{$status}\" is not allowed"
            );
        }

        if (null !== $uri) {
            // Set the uri
            $this->setUri($uri);
        }
    }

    /**
     * Create a new redirect response.
     *
     * @param string $uri     [optional] The URI to redirect to
     * @param int    $status  [optional] The response status code
     * @param array  $headers [optional] An array of response headers
     *
     * @throws \InvalidArgumentException
     * @throws \Valkyrja\Http\Exceptions\InvalidStatusCodeException
     *
     * @return \Valkyrja\Http\RedirectResponse
     */
    public static function createRedirect(
        string $uri = null,
        int $status = StatusCode::FOUND,
        array $headers = []
    ): RedirectResponse {
        return new static('', $status, $headers, $uri);
    }

    /**
     * Get the uri.
     *
     * @return string
     */
    public function getUri(): string
    {
        if (null === $this->uri) {
            $this->setUri('/');
        }

        return $this->uri;
    }

    /**
     * Set the uri.
     *
     * @param string $uri The uri
     *
     * @return \Valkyrja\Http\RedirectResponse
     */
    public function setUri(string $uri): RedirectResponse
    {
        // Set the uri
        $this->uri = $uri;

        // Set the location header for the redirect
        $this->headers()->set('Location', $this->uri);

        return $this;
    }

    /**
     * Set the redirect uri to secure.
     *
     * @param string $path The path
     *
     * @return \Valkyrja\Http\RedirectResponse
     */
    public function secure(string $path = null): RedirectResponse
    {
        // If not path was set
        if (null === $path) {
            // If the uri is already set
            if (null !== $this->uri) {
                // Set the path to it
                $path = $this->uri;
            } else {
                // Otherwise set the path to the current path w/ query string
                $path = request()->getPath();
            }
        }

        // If the path doesn't start with a /
        if ('/' !== $path[0]) {
            // Set the uri as the path
            $this->setUri($path);

            // Return out of the method
            return $this;
        }

        // Set the uri to https with the host and path
        $this->setUri('https://' . request()->getHttpHost() . $path);

        return $this;
    }

    /**
     * Redirect back to the referer.
     *
     * @return \Valkyrja\Http\RedirectResponse
     */
    public function back(): RedirectResponse
    {
        $refererUri = request()->headers()->get('Referer');

        // Ensure the route being redirected to is a valid internal route
        if (! router()->isInternalUri($refererUri)) {
            // If not set as the index
            $refererUri = '/';
        }

        $this->setUri($refererUri ?: '/');

        return $this;
    }

    /**
     * Throw this redirect.
     *
     * @throws \Valkyrja\Http\Exceptions\HttpRedirectException
     */
    public function throw(): void
    {
        throw new HttpRedirectException(
            $this->statusCode,
            $this->uri,
            null,
            $this->headers->all()
        );
    }

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

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


<?php

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

namespace Valkyrja\Console\Commands;

use Valkyrja\Console\Command;
use Valkyrja\Console\CommandHandler;
use Valkyrja\Console\Input\Argument;
use Valkyrja\Console\Support\ProvidesCommand;

/**
 * Class ConsoleCommands.
 *
 * @author Melech Mizrachi
 */
class CommandsListCommand extends CommandHandler
{
    use ProvidesCommand;

    /**
     * The command.
     */
    public const COMMAND           = 'commands';
    public const PATH              = '[' . self::COMMAND . '][ {namespace:[a-zA-Z0-9]+}]';
    public const SHORT_DESCRIPTION = 'List all the commands';
    public const DESCRIPTION       = 'List all the commands';

    /**
     * Run the command.
     *
     * @param string $namespace [optional] The namespace to show commands for
     *
     * @return int
     */
    public function run(string $namespace = null): int
    {
        $commands        = console()->all();
        $longestLength   = 0;
        $previousSection = '';

        $this->filterCommands($commands, $longestLength, $namespace);

        $this->applicationMessage();
        $this->sectionDivider();

        $this->usageMessage('command [options] [arguments]');

        $this->optionsSection(...input()->getGlobalOptions());
        $this->sectionDivider();

        $this->sectionTitleMessage(
            'Commands'
            . ($namespace ? " for the \"{$namespace}\" namespace" : '')
        );

        /** @var \Valkyrja\Console\Command $command */
        foreach ($commands as $command) {
            if (null === $namespace) {
                $this->commandSection($command, $previousSection);
            }

            $this->sectionMessage(
                (! $namespace ? static::TAB : '') . $command->getName(),
                $command->getDescription(),
                $longestLength + 2
            );
        }

        return 0;
    }

    /**
     * Get the valid arguments.
     *
     * @return array
     */
    protected function getArguments(): array
    {
        return [
            new Argument('namespace', 'The namespace to list commands for'),
        ];
    }

    /**
     * Filter the commands by type and name.
     *
     * @param array  $commands      The commands
     * @param int    $longestLength The longest length
     * @param string $namespace     [optional] The namespace to show commands
     *                              for
     *
     * @return void
     */
    protected function filterCommands(array &$commands, int &$longestLength, string $namespace = null): void
    {
        $globalCommands = [];

        /** @var \Valkyrja\Console\Command $command */
        foreach ($commands as $key => $command) {
            $parts            = explode(':', $command->getName());
            $commandName      = $parts[1] ?? null;
            $commandNamespace = $commandName ? $parts[0] : 'global';

            // If there was a namespace passed to the command (commands
            // namespace)  and the namespace for this command doesn't match
            // what was passed then get rid of it so only commands in the
            // namespace are shown.
            if ($commandNamespace !== $namespace && null !== $namespace) {
                unset($commands[$key]);

                continue;
            }

            $longestLength = max(\strlen($command->getName()), $longestLength);

            // If this is a global namespaced command
            if ('global' === $commandNamespace) {
                // Set it in the global commands array so when we show the list
                // of commands global commands will be at the top
                $globalCommands[] = $command;

                // Unset from the commands list to avoid duplicates
                unset($commands[$key]);
            }
        }

        // Sort the global commands by name
        $this->sortCommands($globalCommands);
        // Sort the rest of the commands by name
        $this->sortCommands($commands);

        // Set the commands as the merged results of the global and other
        // commands with the global commands at the top of the list
        $commands = array_merge($globalCommands, $commands);
    }

    /**
     * Sort commands by name.
     *
     * @param array $commands The commands
     *
     * @return void
     */
    protected function sortCommands(array &$commands): void
    {
        usort(
            $commands,
            function (Command $item1, Command $item2) {
                return $item1->getName() <=> $item2->getName();
            }
        );
    }

    /**
     * The command section.
     *
     * @param Command $command         The current command
     * @param string  $previousSection The previous section
     *
     * @return void
     */
    protected function commandSection(Command $command, string &$previousSection): void
    {
        $parts          = explode(':', $command->getName());
        $commandName    = $parts[1] ?? null;
        $currentSection = $commandName ? $parts[0] : 'global';

        if ($previousSection !== $currentSection) {
            output()->formatter()->cyan();
            output()->writeMessage(static::TAB);
            output()->writeMessage($currentSection, true);

            $previousSection = $currentSection;
        }
    }
}


<?php

namespace Intahwebz\Session;

use Psr\Log\LoggerInterface;

class Session implements \Intahwebz\Session {

    static private $sessionClosed;

    private $sessionStarted = false;

    private $logger;

    /**
     * @var \Intahwebz\Domain
     */
    private $domain;

    private $sessionName;

    public static $count = 0;

    function __construct(
        LoggerInterface $logger,
        \Intahwebz\Domain $domain,
        $sessionName
    ) {
        $this->logger = $logger;
        $this->domain = $domain;
        $this->sessionName = $sessionName;

        $this->initSession();
    }

    public function startSession() {

        if($this->sessionStarted  == true){
            return;
        }

        //This sends a cookie header.
        //TODO - the whole way PHP has abstracted sessions with these functions just
        //sucks. You should be building up a complete response and then sending everything at once,
        //Not sending a header when this function is called.

        session_start();

        $this->sessionStarted = true;
    }

    /** Initialize the session parametesr. Only opens the session automatically
     *  if the user sent us a cookie that looks like it contains a reference to a session.
     *  That avoids creating sessions for users who are not logged in.
     */
    function initSession() {

        static $initSessionCalled = false;

        if($initSessionCalled == true){
            return;
        }

        $initSessionCalled = true;
        $currentCookieParams = session_get_cookie_params();
        $domainInfo = $this->domain->getDomainInfo();

        session_set_cookie_params(
            $currentCookieParams["lifetime"],
            $currentCookieParams["path"],
            '.'.$domainInfo->rootCanonicalDomain, //leading dot according to http://www.faqs.org/rfcs/rfc2109.html
            $currentCookieParams["secure"],
            $currentCookieParams["httponly"]
        );

        session_name($this->sessionName);

        if (isset($_COOKIE[$this->sessionName])) {
            //Only start the session automatically, if the user sent us a cookie.
            $this->startSession();
        }
    }

    function endSession() {
        //Session data is usually stored after your script terminated without the need to call session_write_close(), but as
        //session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using
        //framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce
        //the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
        session_write_close();
        self::$sessionClosed = true;
    }

    function checkSessionOpen() {
        if(self::$sessionClosed == true){
            throw new \Exception("Session has already been closed");
        }
        $this->startSession();
    }

    function setSessionVariable($name, $value) {
        $this->checkSessionOpen();
        $_SESSION[$this->sessionName][$name] = $value;
    }

    function resetAllSessionVariable() {
        $this->logger->debug("resetAllSessionVariable");

        // $result = @session_destroy(); //suppress warning
        // session_destroy is evil - the session variables can still be set through setSessionVariable and they
        // will work for the same page view. They dissapear on the next page view though.
        // Setting the $_SESSION variable to an empty array deletes all previous entries correctly.
        $_SESSION = array();
        session_regenerate_id();
    }

    function regenerateID() {
        session_regenerate_id();
    }

    function unsetSessionVariable($name) {
        $this->checkSessionOpen();
        unset($_SESSION[$this->sessionName][$name]);
    }

    /**
     * @param $name
     * @param bool|mixed $default
     * @param bool $clear
     * @return bool
     */
    function getSessionVariable($name, $default = false, $clear = false) {

        //$this->checkSessionOpen();

        if ($this->sessionStarted == false) {
            return $default;
        }

        if(isset($_SESSION[$this->sessionName])){
            if(isset($_SESSION[$this->sessionName][$name])){

                $value = $_SESSION[$this->sessionName][$name];

                if($clear){
                    unset($_SESSION[$this->sessionName][$name]);
                }
                return $value;
            }
        }

        return $default;
    }

    function logoutUser() {
        if (isset($_COOKIE[session_name()])) {
            //TODO go through Response::setCookieVariable($cookieName, $value, $secureOnly = false)
            //which would also require removing all reference to the php session functions.
            setcookie(session_name(), '', time() - 42000, '/');
        }

        $this->resetAllSessionVariable();
    }
}


<?php

/**
 * Copyright (c) 2010-2016 Romain Cottard
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Eureka\Component\Timer;

/**
 * Timer class
 *
 * @author Romain Cottard
 */
class Timer
{
    /**
     * @var float[] $times List of timers with start time
     */
    protected static $times = array();

    /**
     * @var float $time Global timer
     */
    protected static $time = 0.0;

    /**
     * Start time. If name is null, start global timer.
     *
     * @param  string $name
     * @return void
     */
    public static function start($name = null)
    {
        if (null === $name) {
            static::$time = -static::getTime();
        } else {
            static::$times[$name] = -static::getTime();
        }
    }

    /**
     * Get Time time.
     *
     * @param  string $name
     * @return float
     */
    public static function get($name = null)
    {
        if (null === $name) {
            $time = static::$time;
        } elseif (isset(static::$times[$name])) {
            $time = static::$times[$name];
        } else {
            throw new \LogicException('Timer with given name does not exist!');
        }

        return ($time + static::getTime());
    }

    /**
     * Display timer value
     *
     * @param  string $name
     * @param  int    $round
     * @return void
     */
    public static function display($name = null, $round = 3)
    {
        $time = round(static::get($name), $round);
        $name = ($name === null ? 'GLOBAL' : $name);

        if (PHP_SAPI !== 'cli') {
            echo '

    Timer[' . $name . ']:  ' . $time . ' s

';
        } else {
            echo ' ### Timer[' . $name . ']: ' . $time . 's ###' . PHP_EOL;
        }
    }

    /**
     * Get microtime
     *
     * @return float
     */
    public static function getTime()
    {
        return microtime(true);
    }
}


<?php
namespace Gosyl\CommonBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\ResetType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class LoginType extends AbstractType {
    //private $_csrfToken;
    private $_builder;
	private $_lastUsername;
	private $action;

	/*public function __construct(array $aParams) {//$lastUsername, $action) {
		$this->_lastUsername = $aParams['lastUsername'];
		$this->action = $aParams['action'];
	}*/

	public function buildForm(FormBuilderInterface $builder, array $options) {
		$this->_lastUsername = $options['data']['lastUsername'];
		$this->action = $options['data']['action'];

		$builder->setAttribute('method', $options['method'])
				->setAttribute('id', $options['id'])
				->setAttribute('legend', $options['legend'])
				->setAttribute('action', $options['data']['action'])
        		//->add('_csrf_token', 'hidden', array('data' => $options['csrfToken']))
        		->add('_username', TextType::class, array('label' => "Nom d'utilisateur", 'data' => $options['data']['lastUsername']))
        		->add('_password', PasswordType::class, array('label' => 'Mot de passe'))
        		->add('_remember_me', CheckboxType::class,array('label' => 'Se souvenir de moi', 'required' => false))
        		->add('sendFormLogin', SubmitType::class, array('label' => 'Connexion'))
                ->add('btnInscription', ButtonType::class, array('label' => 'Inscription', 'attr' => array('onclick' => 'javascript: btnInscriptionFromLogin();')))
                ->add('btnCancel', ResetType::class, array('label' => 'Annuler', 'attr' => array('id' => 'btnCancel')))
        ;

        $this->_builder = $builder;
    }

    public function getName() {
        //return 'gosyl_user_login';
        return $this->getBlockPrefix();
    }

    public function buildView(FormView $view, FormInterface $form, array $options) {
    	foreach ($options as $key => $value) {
    		$view->vars[$key] = $value;
    	}
    }

    public function configureOptions(OptionsResolver $resolver) {
    	$resolver->setDefaults(array(
    		'method' => 'POST',
    		'id' => 'connexion',
    		'legend' => 'Connexion',
    		'lastUsername' => $this->_lastUsername,
    		'action' => $this->action
    	));
    }

    public function getBlockPrefix() {
    	return '';
    }
}


<?php
namespace CakeTaxonomy\Controller;

use CakeTaxonomy\Controller\AppController;

/**
 * Vocabularies Controller
 *
 * @property \CakeTaxonomy\Model\Table\VocabulariesTable $Vocabularies
 */
abstract class AbstractVocabulariesController extends AppController
{

    /**
     * Index method
     *
     * @return \Cake\Network\Response|null
     */
    public function index()
    {
        $vocabularies = $this->paginate($this->Vocabularies);

        $this->set(compact('vocabularies'));
        $this->set('_serialize', ['vocabularies']);
    }

    /**
     * View method
     *
     * @param string|null $id Vocabulary id.
     * @return \Cake\Network\Response|null
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $vocabulary = $this->Vocabularies->get($id, [
            'contain' => ['Terms']
        ]);

        $this->set('vocabulary', $vocabulary);
        $this->set('_serialize', ['vocabulary']);
    }

    /**
     * Add method
     *
     * @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise.
     */
    public function add()
    {
        $vocabulary = $this->Vocabularies->newEntity();
        if ($this->request->is('post')) {
            $vocabulary = $this->Vocabularies->patchEntity($vocabulary, $this->request->data);
            if ($this->Vocabularies->save($vocabulary)) {
                $this->Flash->success(__('The vocabulary has been saved.'));

                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The vocabulary could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('vocabulary'));
        $this->set('_serialize', ['vocabulary']);
    }

    /**
     * Edit method
     *
     * @param string|null $id Vocabulary id.
     * @return \Cake\Network\Response|void Redirects on successful edit, renders view otherwise.
     * @throws \Cake\Network\Exception\NotFoundException When record not found.
     */
    public function edit($id = null)
    {
        $vocabulary = $this->Vocabularies->get($id, [
            'contain' => []
        ]);
        if ($this->request->is(['patch', 'post', 'put'])) {
            $vocabulary = $this->Vocabularies->patchEntity($vocabulary, $this->request->data);
            if ($this->Vocabularies->save($vocabulary)) {
                $this->Flash->success(__('The vocabulary has been saved.'));

                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The vocabulary could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('vocabulary'));
        $this->set('_serialize', ['vocabulary']);
    }

    /**
     * Delete method
     *
     * @param string|null $id Vocabulary id.
     * @return \Cake\Network\Response|null Redirects to index.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);
        $vocabulary = $this->Vocabularies->get($id);
        if ($this->Vocabularies->delete($vocabulary)) {
            $this->Flash->success(__('The vocabulary has been deleted.'));
        } else {
            $this->Flash->error(__('The vocabulary could not be deleted. Please, try again.'));
        }

        return $this->redirect(['action' => 'index']);
    }
}


<?php

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

namespace Valkyrja\Support\Providers;

use Valkyrja\Application;

/**
 * Trait AllowsProviders.
 *
 * @author Melech Mizrachi
 */
trait ProvidersAwareTrait
{
    /**
     * The items provided by providers that are deferred.
     *
     * @var string[]
     */
    protected static $provided = [];

    /**
     * The registered providers.
     *
     * @var array
     */
    protected static $registered = [];

    /**
     * Register a provider.
     *
     * @param string $provider The provider
     * @param bool   $force    [optional] Whether to force regardless of
     *                         deferred status
     *
     * @return void
     */
    public function register(string $provider, bool $force = false): void
    {
        // No need to re-register providers
        if ($this->isRegistered($provider)) {
            return;
        }

        /** @var \Valkyrja\Support\Providers\Provides $provider */

        // If the service provider is deferred
        // and its defined what services it provides
        if (! $force && $provider::deferred() && $provider::provides()) {
            // Add the services to the service providers list
            foreach ($provider::provides() as $provided) {
                self::$provided[$provided] = $provider;
            }

            return;
        }

        // Publish the service provider
        $provider::publish($this->getApplication());

        self::$registered[$provider] = true;
    }

    /**
     * Check whether a given item is provided by a deferred provider.
     *
     * @param string $itemId The item
     *
     * @return bool
     */
    public function isProvided(string $itemId): bool
    {
        return isset(self::$provided[$itemId]);
    }

    /**
     * Determine whether a provider has been registered.
     *
     * @param string $provider The provider
     *
     * @return bool
     */
    public function isRegistered(string $provider): bool
    {
        return isset(self::$registered[$provider]);
    }

    /**
     * Initialize a provided item.
     *
     * @param string $itemId The item
     *
     * @return void
     */
    public function initializeProvided(string $itemId): void
    {
        /** @var \Valkyrja\Support\Providers\Provides $provider */
        $provider = self::$provided[$itemId];

        // Register the provider
        $this->register($provider, true);
    }

    /**
     * Get the application.
     *
     * @return \Valkyrja\Application
     */
    abstract protected function getApplication(): Application;
}


<?php

use Reaction\DI\Container;
use Reaction\StaticApplicationInterface;

/**
 * Class Reaction. Base static class
 */
class Reaction
{
    const APP_ENV_PROD = 'production';
    const APP_ENV_DEV  = 'development';

    /** @var Composer\Autoload\ClassLoader */
    public static $composer;
    /** @var Container */
    public static $di;
    /** @var StaticApplicationInterface */
    public static $app;
    /** @var \Reaction\Base\ConfigReader */
    public static $config;
    /** @var \Reaction\Base\AnnotationsReader */
    public static $annotations;

    /** @var string */
    protected static $configsPath;
    /** @var string */
    protected static $appType;

    /**
     * Initialize whole application
     * @param \Composer\Autoload\ClassLoader $composer
     * @param string                         $configsPath Path where to look for config files
     * @param string                         $appType Application type (web|console)
     */
    public static function init(Composer\Autoload\ClassLoader $composer = null, $configsPath = null, $appType = StaticApplicationInterface::APP_TYPE_WEB)
    {
        static::initBasic($composer, $configsPath, $appType);
        static::initStaticApp();
    }

    /**
     * Initialize basic components
     * @param \Composer\Autoload\ClassLoader|null $composer
     * @param string|null                         $configsPath
     * @param string                              $appType
     */
    public static function initBasic(Composer\Autoload\ClassLoader $composer = null, $configsPath = null, $appType = StaticApplicationInterface::APP_TYPE_WEB)
    {
        if (!isset($composer)) {
            $composer = static::locateClassLoader();
        }
        if (!isset($configsPath)) {
            $configsPath = static::locateConfigsPath();
        }
        if (!isset($composer)) {
            throw new \Reaction\Exceptions\InvalidArgumentException("Missing \$composer option");
        }
        if (!isset($configsPath)) {
            throw new \Reaction\Exceptions\InvalidArgumentException("Missing \$configsPath option");
        }
        static::$composer = $composer;
        static::$configsPath = $configsPath;
        static::$appType = $appType;
        static::initConfigReader();
        static::initAnnotationReader();
        static::initContainer();
    }

    /**
     * Locate configs path
     * @return null|string
     */
    protected static function locateConfigsPath()
    {
        $cwd = getcwd();
        $defaultDir = DIRECTORY_SEPARATOR . 'Config';
        $path = $cwd . $defaultDir;
        if (!file_exists($path) || !is_dir($path)) {
            return null;
        }
        return $path;
    }

    /**
     * Get composer class loader
     * @return null|\Composer\Autoload\ClassLoader
     */
    protected static function locateClassLoader()
    {
        $cwd = getcwd();
        $path = $cwd . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
        if (!file_exists($path) || !is_file($path)) {
            return null;
        }
        return include $path;
    }

    /**
     * Create instance of class without throwing exceptions
     * @param string|array $type
     * @param array $params
     * @return mixed|null
     */
    public static function createNoExc($type, array $params = [])
    {
        try {
            return static::create($type, $params);
        } catch (\Throwable $exception) {
            return null;
        }
    }

    /**
     * Create instance of class
     * @param string|array $type Class name or indexed parameters array with key "class"
     * @param array        $params Constructor parameters indexed array
     * @return object|mixed
     * @throws \Reaction\DI\Exceptions\InvalidConfigException(
     */
    public static function create($type, array $params = [])
    {
        if (is_string($type)) {
            return static::$di->getOrCreate($type, $params);
        } elseif (is_array($type) && isset($type['class'])) {
            $class = $type['class'];
            unset($type['class']);
            return static::$di->getOrCreate($class, $params, $type);
        } elseif (is_callable($type, true)) {
            return static::$di->invoke($type, $params);
        } elseif (is_array($type)) {
            throw new \Reaction\DI\Exceptions\InvalidConfigException('Object configuration must be an array containing a "class" element.');
        }

        throw new \Reaction\DI\Exceptions\InvalidConfigException('Unsupported configuration type: ' . gettype($type));
    }

    /**
     * Call closure with parameters using DI
     * @param callable $callable
     * @param array    $params
     * @return mixed
     * @throws \Reaction\DI\Exceptions\InvalidConfigException
     */
    public static function invoke($callable, $params = [])
    {
        return static::$di->invoke($callable, $params);
    }

    /**
     * Configures an object with the initial property values.
     * @param \object $object the object to be configured
     * @param array $properties the property initial values given in terms of name-value pairs.
     * @return \object the object itself
     */
    public static function configure($object, $properties)
    {
        foreach ($properties as $name => $value) {
            $object->$name = $value;
        }

        return $object;
    }

    /**
     * Translates a message to the specified language.
     *
     * @param string $category Message category
     * @param string $message  Message for translation
     * @param array  $params   Parameters array
     * @param string $language Language translate to
     * @return string
     */
    public static function t($category, $message, $params = [], $language = null)
    {
        if (static::$app !== null && static::$app->getI18n() !== null) {
            return static::$app->getI18n()->translate($category, $message, $params, $language ?: static::$app->language);
        }
        $_params = [];
        foreach ($params as $key => $value) { $_params['{' . $key . '}'] = $value; }
        return !empty($params) ? strtr($message, $_params) : $message;
    }

    /**
     * Translates a message to the specified language.
     * Looks like a ::t() method but returns a TranslationPromise for further translation when request language will known
     *
     * @param string $category Message category
     * @param string $message  Message for translation
     * @param array  $params   Parameters array
     * @param string $language Language translate to
     * @return \Reaction\I18n\TranslationPromise
     */
    public static function tp($category, $message, $params = [], $language = null)
    {
        $translationPromise = new \Reaction\I18n\TranslationPromise($category, $message, $params, $language);
        return $translationPromise;
    }

    /**
     * Returns a string representing the current version of framework.
     * @return string the version of Reaction framework
     */
    public static function getVersion()
    {
        return '0.2.4';
    }

    /**
     * Check that application type is web
     * @return bool
     */
    public static function isWebApp()
    {
        return static::$appType === StaticApplicationInterface::APP_TYPE_WEB;
    }

    /**
     * Check that application type is console
     * @return bool
     */
    public static function isConsoleApp()
    {
        return static::$appType === StaticApplicationInterface::APP_TYPE_CONSOLE;
    }

    /**
     * Shortcut function to check that Application is using DEVELOPMENT environment
     * @return bool
     */
    public static function isDev()
    {
        return empty(Reaction::$app) || Reaction::$app->envType === StaticApplicationInterface::APP_ENV_DEV;
    }

    /**
     * Shortcut function to check that Application is using PRODUCTION environment
     * @return bool
     */
    public static function isProd()
    {
        return Reaction::$app && Reaction::$app->envType === StaticApplicationInterface::APP_ENV_PROD;
    }

    /**
     * Shortcut function to check that Application is in DEBUG mode
     * @return bool
     */
    public static function isDebug()
    {
        return Reaction::$app && Reaction::$app->debug;
    }

    /**
     * Shortcut function to check that Application is in TESTING mode
     * @return bool
     */
    public static function isTest()
    {
        return Reaction::$app && Reaction::$app->test;
    }

    /**
     * Shortcut to Reaction::$app->logger->debug()
     * @param string|mixed $message
     * @param array $context
     */
    public static function debug($message, $context = [])
    {
        static::$app->logger->debug($message, $context, 1);
    }

    /**
     * Shortcut to Reaction::$app->logger->info()
     * @param string|mixed $message
     * @param array $context
     */
    public static function info($message, $context = [])
    {
        static::$app->logger->info($message, $context, 1);
    }

    /**
     * Shortcut to Reaction::$app->logger->warning()
     * @param string|mixed $message
     * @param array $context
     */
    public static function warning($message, $context = [])
    {
        static::$app->logger->warning($message, $context, 1);
    }

    /**
     * Shortcut to Reaction::$app->logger->error()
     * @param string|mixed $message
     * @param array $context
     */
    public static function error($message, $context = [])
    {
        static::$app->logger->error($message, $context, 1);
    }

    /**
     * Shortcut to Reaction::$app->logger->profile()
     * @param string|null $message
     * @param string|null $endId
     * @return string|null
     */
    public static function profile($message = null, $endId = null)
    {
        return static::$app->logger->profile($message, $endId, 1);
    }

    /**
     * Shortcut to Reaction::$app->logger->profileEnd()
     * @param string|null $endId
     * @param string|null $message
     */
    public static function profileEnd($endId = null, $message = null)
    {
        static::$app->logger->profileEnd($endId, $message, 1);
    }

    /**
     * Shortcut to Reaction::$app->getAlias()
     * @param string $alias
     * @param bool   $throwException
     * @return bool|string
     */
    public static function getAlias($alias, $throwException = true)
    {
        return Reaction::$app->getAlias($alias, $throwException);
    }

    /**
     * Shortcut to Reaction::$app->setAlias()
     * @param string $alias
     * @param string $path
     */
    public static function setAlias($alias, $path)
    {
        Reaction::$app->setAlias($alias, $path);
    }

    /**
     * Get instance of config reader
     * @param bool $flush
     * @return \Reaction\Base\ConfigReader
     */
    protected static function getConfigReader($flush = false)
    {
        if ($flush || !isset(static::$config)) {
            $conf = [
                'path' => static::$configsPath,
                'appType' => static::$appType,
            ];
            static::$config = new \Reaction\Base\ConfigReader($conf);
        }
        return static::$config;
    }

    /**
     * Initialize DI container
     */
    protected static function initContainer()
    {
        $config = static::getConfigReader()->get('container');
        Container::setDefaultContainer(new Container($config));
        static::$di = Container::getDefaultContainer();
    }

    /**
     * Initialize application object
     */
    public static function initStaticApp()
    {
        $config = static::getConfigReader()->get('appStatic');
        $config['class'] = StaticApplicationInterface::class;
        //Use config after creation, so Reaction::$app will be available inside StaticApplicationInterface components
        $appLateConfig = [];
        $appLateConfigKeys = ['components'];
        foreach ($appLateConfigKeys as $appKey) {
            if (isset($config[$appKey])) {
                $appLateConfig[$appKey] = $config[$appKey];
                unset($config[$appKey]);
            }
        }
        static::$app = static::create($config);
        Container::setDefaultServiceLocator(static::$app);
        if (!empty($appLateConfig)) {
            static::configure(static::$app, $appLateConfig);
        }
    }

    /**
     * Initialize config reader
     */
    protected static function initConfigReader()
    {
        static::getConfigReader();
    }

    /**
     * Initialize annotation reader
     */
    protected static function initAnnotationReader()
    {
        static::$annotations = new \Reaction\Base\AnnotationsReader();
    }

    /**
     * Print backtrace
     * @param bool $withArgs Show arguments names and content
     * @param bool $useEcho Use direct call to `echo` function instead of Stream::write()
     */
    public static function dbg($withArgs = false, $useEcho = false)
    {
        \Reaction\Base\Logger\Debugger::backTrace($withArgs, 1, $useEcho);
    }
}


<?php
/**
 * Поставщик данных из таблицы модуля ORM.
 *
 * @version ${product.version}
 *
 * @copyright 2011, Михаил Красильников <m.krasilnikov@yandex.ru>
 * @license http://www.gnu.org/licenses/gpl.txt	GPL License 3
 * @author Михаил Красильников <m.krasilnikov@yandex.ru>
 *
 * Данная программа является свободным программным обеспечением. Вы
 * вправе распространять ее и/или модифицировать в соответствии с
 * условиями версии 3 либо (по вашему выбору) с условиями более поздней
 * версии Стандартной Общественной Лицензии GNU, опубликованной Free
 * Software Foundation.
 *
 * Мы распространяем эту программу в надежде на то, что она будет вам
 * полезной, однако НЕ ПРЕДОСТАВЛЯЕМ НА НЕЕ НИКАКИХ ГАРАНТИЙ, в том
 * числе ГАРАНТИИ ТОВАРНОГО СОСТОЯНИЯ ПРИ ПРОДАЖЕ и ПРИГОДНОСТИ ДЛЯ
 * ИСПОЛЬЗОВАНИЯ В КОНКРЕТНЫХ ЦЕЛЯХ. Для получения более подробной
 * информации ознакомьтесь со Стандартной Общественной Лицензией GNU.
 *
 * Вы должны были получить копию Стандартной Общественной Лицензии
 * GNU с этой программой. Если Вы ее не получили, смотрите документ на
 * <http://www.gnu.org/licenses/>
 *
 * @package ORM
 */

/**
 * Поставщик данных из таблицы модуля ORM
 *
 * @package ORM
 */
class ORM_UI_List_DataProvider implements UI_List_DataProvider_Interface
{
    /**
     * Таблица БД
     *
     * @var ORM_Table
     */
    private $table;

    /**
     * Фильтр
     *
     * @var array
     */
    private $filter = array();

    /**
     * Запросы полнотекстового поиска
     *
     * @var array
     */
    //private $fulltext = array();

    /**
     * Правила сортировки
     *
     * @var array
     */
    private $orderBy = array();

    /**
     * Конструктор
     *
     * @param ORM_Table $table
     *
     * @return ORM_UI_List_DataProvider
     *
     * @since 1.00
     */
    public function __construct(ORM_Table $table)
    {
        $this->table = $table;
    }

    /**
     * Добавляет разрешающее условие фильтрации
     *
     * @param string $property  имя свойства
     * @param mixed  $value     значение
     * @param string $cond      условие (=, <, >, <=, >=)
     *
     * @return void
     *
     * @since 1.00
     */
    public function filterInclude($property, $value, $cond = '=')
    {
        $this->filter []= array($property, $value, $cond);
    }

    /* *
     * Добавляет запрос полнотекстового поиска
     *
     * @param array  $properties  имена свойств
     * @param string $query       запрос
     *
     * @return void
     *
     * @since 1.00
     */
    /*public function filterFullText($properties, $query)
    {
        $this->fulltext []= array($properties, $query);
    }*/

    /**
     * Задаёт сортировку списка
     *
     * @param ... имя поля
     * @param ... обратное направление (по умолчанию false)
     *
     * @return void
     *
     * @since 1.00
     */
    public function orderBy()
    {
        $this->orderBy = func_get_args();
    }

    /**
     * Возвращает элементы списка
     *
     * @param int $limit   максимум элементов, который следует вернуть
     * @param int $offset  сколько элементов пропустить
     *
     * @return array
     *
     * @since 1.00
     */
    public function getItems($limit = null, $offset = 0)
    {
        $items = array();
        $query = $this->table->createSelectQuery();
        for ($i = 0; $i < count($this->orderBy); $i += 2)
        {
            $field = $this->orderBy[$i];
            $dir = @$this->orderBy[$i + 1] ? ezcQuerySelect::DESC : ezcQuerySelect::ASC;
            $query->orderBy($field, $dir);
        }

        $this->setFilter($query);
        $entities = $this->table->loadFromQuery($query, $limit, $offset);
        foreach ($entities as $entity)
        {
            $items []= new ORM_UI_List_Item($entity);
        }

        return $items;
    }

    /**
     * Возвращает общее количество записей в списке
     *
     * @return int
     *
     * @since 1.00
     */
    public function getCount()
    {
        $query = $this->table->createCountQuery();
        $this->setFilter($query);
        return $this->table->count($query);
    }

    /**
     * Применяет фильтр к запросу
     *
     * @param ezcQuerySelect $query
     *
     * @return void
     *
     * @since 1.00
     */
    private function setFilter(ezcQuerySelect $query)
    {
        $map = array('<' => 'lt', '<=' => 'lte', '>' => 'gt', '>=' => 'gte');
        $andParts = array();
        foreach ($this->filter as $rule)
        {
            $field = $rule[0];
            $value = $rule[1];
            $method = null;
            if ($rule[2] == '=')
            {
                $method = 'eq';
                if (is_array($value))
                {
                    $method = 'in';
                }
            }
            elseif (isset($map[$rule[2]]))
            {
                $method = $map[$rule[2]];
            }
            if ($method)
            {
                if ($value instanceof ORM_Entity)
                {
                    $value = $value->getPrimaryKey();
                }

                $andParts []= $query->expr->$method($field,
                    is_array($value) ? $value : $query->bindValue($value));
            }
        }
        /*
        if (count($this->fulltext))
        {
            foreach ($this->fulltext as $fulltext)
            {
                $q = $this->buildFullTextQuery($fulltext[0], $fulltext[1]);
                if ($q)
                {
                    $andParts []= '(' . $q . ')';
                }
            }
        }
        */

        if (count($andParts))
        {
            $where = call_user_func_array(array($query->expr, 'lAnd'), $andParts);
            $query->where($where);
        }
    }

    /* *
     * Строит запрос полнотекствового поиска
     *
     * @param array $fields  поля
     * @param string $query  поисковый запрос
     *
     * @return string
     *
     * @since 1.00
     */
    /*private function buildFullTextQuery($fields, $query)
    {
        if (class_exists('SearchAPI_QueryBuilder_LIKE'))
        {
            $builder = new SearchAPI_QueryBuilder_LIKE();
            return $builder->getWherePart($fields, $query);
        }
        else
        {
            eresus_log(__METHOD__, LOG_ERR, 'Class "SearchAPI_QueryBuilder_LIKE" not found!');
            return '';
        }
    }*/
}


<?php
namespace wiggum\services\csrf;

use ArrayAccess;
use RuntimeException;
use wiggum\http\Request;
use wiggum\http\Response;
use wiggum\services\csrf\exceptions\TokenMismatchException;

/**
 * CSRF protection middleware and service
 */
class CSRFGuard
{

    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [];

    /**
     * Key for CSRF parameter
     *
     * @var string
     */
    protected $key;

    /**
     * CSRF storage
     *
     * Should be either an array or an object. If an object is used, then it must
     * implement ArrayAccess
     *
     * @var array|ArrayAccess
     */
    protected $storage;

    /**
     * CSRF Strength
     *
     * @var int
     */
    protected $strength;

    /**
     * Create new CSRF guard
     *
     * @param string $key
     * @param null|array|ArrayAccess $storage
     * @param integer $strength
     * @throws RuntimeException if the session cannot be found
     */
    public function __construct($key = 'csrf_token', &$storage = null, $strength = 16)
    {
        $this->key = trim($key);
        if ($strength < 16) {
            throw new RuntimeException('CSRF middleware failed. Minimum strength is 16.');
        }
        $this->strength = $strength;
        $this->storage = &$storage;
    }

    /**
     * Invoke middleware
     *
     * @param Request $request
     * @param Response $response
     * @param callable $next
     *
     * @return Response
     */
    public function __invoke(Request $request, Response $response, callable $next)
    {
        $this->validateStorage();

        if ($this->isReading($request) ||
            $this->inExceptArray($request) ||
            $this->tokensMatch($request)) {

            return $next($request, $response);
        }

        throw new TokenMismatchException();
    }

    /**
     *
     * @return string
     */
    public function generateFormField()
    {
        $token = $this->getToken();
        return $token ? '<input type="hidden" name="'.$this->key.'" value="'. $token .'">' : '';
    }

    /**
     *
     * @return string
     */
    public function generateMetaTag()
    {
        $token = $this->getToken();
        return $token ? '<meta name="'.$this->key.'" content="'. $token .'">' : '';
    }

    /**
     *
     * @return string|boolean
     */
    public function getToken()
    {
        $this->validateStorage();

        // Generate new CSRF token
        $storedToken = isset($this->storage[$this->key]) ? $this->storage[$this->key] : false;
        if (!$storedToken) {
            $storedToken = $this->generateToken();
        }

        return $storedToken;
    }

    /**
     * Generates a new CSRF token
     *
     * @return string
     */
    protected function generateToken()
    {
        // Generate new CSRF token
        $token = bin2hex(random_bytes($this->strength));
        $this->storage[$this->key] = $token;
        return $token;
    }

    /**
     *
     * @throws RuntimeException
     * @return array|ArrayAccess
     */
    protected function validateStorage()
    {
        if (is_array($this->storage)) {
            return $this->storage;
        }

        if ($this->storage instanceof ArrayAccess) {
            return $this->storage;
        }

        if (!isset($_SESSION)) {
            throw new RuntimeException('CSRF middleware failed. Session not found.');
        }

        if (!array_key_exists($this->key, $_SESSION)) {
            $_SESSION[$this->key] = null;
        }

        $this->storage = &$_SESSION;

        return $this->storage;
    }

    /**
     * Determine if the HTTP request uses a ‘read’ verb.
     *
     * @param  Request  $request
     * @return boolean
     */
    protected function isReading(Request $request)
    {
        return in_array($request->getMethod(), ['HEAD', 'GET', 'OPTIONS']);
    }

    /**
     *
     * @param Request $request
     * @return boolean
     */
    protected function inExceptArray(Request $request)
    {
        foreach ($this->except as $except) {
            if ($except == $request->getRequestURI()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Determine if the storage and input CSRF tokens match.
     *
     * @param  Request $request
     * @return boolean
     */
    protected function tokensMatch(Request $request)
    {
        $token = $this->getTokenFromRequest($request);
        $storedToken = $this->getToken();

        return  is_string($storedToken) &&
                is_string($token) &&
                hash_equals($storedToken, $token);
    }

    /**
     * Get the CSRF token from the request.
     *
     * @param  Request $request
     * @return string
     */
    protected function getTokenFromRequest(Request $request)
    {
        $token = $request->getParameter($this->key) ?: $request->getHeader('X-CSRF-TOKEN');

        return $token;
    }

}