<?php

/**
 * Jin Framework
 * Diatem
 */

namespace Jin2\Form\Components;

/**
 * Composant <input type="checkbox">
 */
class Combo extends AbstractComponent
{

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

  /**
   * @var array  Valeurs a présélectionner. (Tableau de la forme array('value',...))
   */
  protected $checkedValues = array();

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

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

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

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

      if (is_numeric(array_search($v['value'], $this->checkedValues))) {
        $selected = 'checked="checked" ';
      }

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

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

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

  /**
   * Définit les value à mettre à checked
   *
   * @param array $valuesToChecked  Tableau de values array(1,'toto'...)
   */
  public function forceCheckedValues($valuesToChecked)
  {
    $this->checkedValues = $valuesToChecked;
  }

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

}


<?php
/**
 * PEAR_Command_Mirror (download-all command)
 *
 * PHP versions 4 and 5
 *
 * @category   pear
 * @package    PEAR
 * @author     Alexander Merz <alexmerz@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    CVS: $Id: Mirror.php 313023 2011-07-06 19:17:11Z dufuz $
 * @link       http://pear.php.net/package/PEAR
 * @since      File available since Release 1.2.0
 */

/**
 * base class
 */
require_once 'PEAR/Command/Common.php';

/**
 * PEAR commands for providing file mirrors
 *
 * @category   pear
 * @package    PEAR
 * @author     Alexander Merz <alexmerz@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    Release: 1.9.4
 * @link       http://pear.php.net/package/PEAR
 * @since      Class available since Release 1.2.0
 */
class PEAR_Command_Mirror extends PEAR_Command_Common
{
    var $commands = array(
        'download-all' => array(
            'summary' => 'Downloads each available package from the default channel',
            'function' => 'doDownloadAll',
            'shortcut' => 'da',
            'options' => array(
                'channel' =>
                    array(
                    'shortopt' => 'c',
                    'doc' => 'specify a channel other than the default channel',
                    'arg' => 'CHAN',
                    ),
                ),
            'doc' => '
Requests a list of available packages from the default channel ({config default_channel})
and downloads them to current working directory.  Note: only
packages within preferred_state ({config preferred_state}) will be downloaded'
            ),
        );

    /**
     * PEAR_Command_Mirror constructor.
     *
     * @access public
     * @param object PEAR_Frontend a reference to an frontend
     * @param object PEAR_Config a reference to the configuration data
     */
    function PEAR_Command_Mirror(&$ui, &$config)
    {
        parent::PEAR_Command_Common($ui, $config);
    }

    /**
     * For unit-testing
     */
    function &factory($a)
    {
        $a = &PEAR_Command::factory($a, $this->config);
        return $a;
    }

    /**
    * retrieves a list of avaible Packages from master server
    * and downloads them
    *
    * @access public
    * @param string $command the command
    * @param array $options the command options before the command
    * @param array $params the stuff after the command name
    * @return bool true if succesful
    * @throw PEAR_Error
    */
    function doDownloadAll($command, $options, $params)
    {
        $savechannel = $this->config->get('default_channel');
        $reg = &$this->config->getRegistry();
        $channel = isset($options['channel']) ? $options['channel'] :
            $this->config->get('default_channel');
        if (!$reg->channelExists($channel)) {
            $this->config->set('default_channel', $savechannel);
            return $this->raiseError('Channel "' . $channel . '" does not exist');
        }
        $this->config->set('default_channel', $channel);

        $this->ui->outputData('Using Channel ' . $this->config->get('default_channel'));
        $chan = $reg->getChannel($channel);
        if (PEAR::isError($chan)) {
            return $this->raiseError($chan);
        }

        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
            $rest = &$this->config->getREST('1.0', array());
            $remoteInfo = array_flip($rest->listPackages($base, $channel));
        }

        if (PEAR::isError($remoteInfo)) {
            return $remoteInfo;
        }

        $cmd = &$this->factory("download");
        if (PEAR::isError($cmd)) {
            return $cmd;
        }

        $this->ui->outputData('Using Preferred State of ' .
            $this->config->get('preferred_state'));
        $this->ui->outputData('Gathering release information, please wait...');

        /**
         * Error handling not necessary, because already done by
         * the download command
         */
        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
        $err = $cmd->run('download', array('downloadonly' => true), array_keys($remoteInfo));
        PEAR::staticPopErrorHandling();
        $this->config->set('default_channel', $savechannel);
        if (PEAR::isError($err)) {
            $this->ui->outputData($err->getMessage());
        }

        return true;
    }
}


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

namespace Maths\Geometry;

use \Maths\Maths;
use \Maths\Geometry\Quadrilateral;
use \Maths\Geometry\Segment;

/**
 * Class Rectangle
 *
 *      D       C
 *      ---------
 *      |       |
 *      ---------
 *      A       B
 *  y
 *  ↑ → x
 *
 * @author  piwi <me@e-piwi.fr>
 */
class Rectangle
    extends Quadrilateral
{

    /**
     * @param   null|\Maths\Point(s)    $point_a
     * @param   null|\Maths\Point(s)    $point_b
     * @param   null|\Maths\Point(s)    $point_c
     * @param   null|\Maths\Point(s)    $point_d
     * @param   int                             $space_type
     */
    public function __construct(
        $point_a = null, $point_b = null, $point_c = null, $point_d = null,
        $space_type = Maths::CARTESIAN_2D
    ) {
        parent::__construct(
            $point_a, $point_b, $point_c, $point_d, $space_type
        );
    }

// Characteristics

    /**
     * Get rectangle's width (by convention width > height)
     *
     * @return  numeric
     */
    public function getWidth()
    {
        return max(array(
            ($this->getPointB()->getAbscissa() - $this->getPointA()->getAbscissa()),
            ($this->getPointD()->getOrdinate() - $this->getPointA()->getOrdinate())
        ));
    }

    /**
     * Get rectangle's height (by convention width > height)
     *
     * @return  numeric
     */
    public function getHeight()
    {
        return min(array(
            ($this->getPointB()->getAbscissa() - $this->getPointA()->getAbscissa()),
            ($this->getPointD()->getOrdinate() - $this->getPointA()->getOrdinate())
        ));
    }

    /**
     * @return  numeric
     */
    public function getArea()
    {
        return ($this->getWidth() * $this->getHeight());
    }

    /**
     * @return  numeric
     */
    public function getPerimeter()
    {
        return ($this->getWidth() + $this->getHeight()) * 2;
    }

// Specials

    /**
     * @param   array   ( Ax , Ay , Cx, Cy )
     */
    public function createFromCoordinates(array $coords)
    {
        return $this
            ->setA(array( 'x'=>$coords[0], 'y'=>$coords[1] ))
            ->setB(array( 'x'=>$coords[2], 'y'=>$coords[1] ))
            ->setC(array( 'x'=>$coords[0], 'y'=>$coords[3] ))
            ->setD(array( 'x'=>$coords[2], 'y'=>$coords[3] ))
            ;
    }
}


<?php

namespace Mooti\Factory;

use Mooti\Factory\Exception\ClassNotFoundException;

trait Factory
{
    private $objects = [];

    /**
     * Add an instance of a class. This will be returned when the user tries to create a the object
     *
     * @param string $className  The class to create
     * @param string $mockObject The class to create
     *
     */
    public function addInstance($className, $mockObject)
    {
        if(!isset($this->objects[$className])) {
            $this->objects[$className] = [];
        }
        $this->objects[$className][] = $mockObject;
    }

    /**
     * Create a new instance of a given class
     *
     * @param string $className The class to create
     *
     * @return object The new class
     */
    public function createNew($className)
    {
        $constructArguments = func_get_args();
        return $this->_createNew( ...$constructArguments);
    }

    /**
     * Create a new instance of a given class
     *
     * @param string $className The class to create
     *
     * @return object The new class
     */
    protected function _createNew($className)
    {
        if (!empty($this->objects[$className])) {
            return array_shift($this->objects[$className]);
        }

        if (class_exists($className) == false) {
            throw new ClassNotFoundException('The class '.$className.' cannot be found');
        }

        $constructArguments = func_get_args();
        array_shift($constructArguments);
        return new $className( ...$constructArguments);
    }
}


<?php

/*
 * This file is part of Core.
 *
 * (c) DraperStudio <hello@draperstudio.tech>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Apivore\Core;

use Apivore\Core\Contracts\HttpClient;
use League\Container\Container;
use ReflectionClass;

/**
 * Class AbstractClient.
 */
abstract class AbstractClient
{
    /**
     * @var mixed|object
     */
    private $httpClient;

    /**
     * AbstractClient constructor.
     */
    public function __construct()
    {
        $this->container = new Container();

        $this->container->addServiceProvider($this->getServiceProvider());

        $this->httpClient = $this->container->get(HttpClient::class);
    }

    /**
     * @param $name
     *
     * @return mixed
     */
    public function api($name)
    {
        $reflector = new ReflectionClass(get_called_class());
        $namespace = $reflector->getNamespaceName();

        $class = $namespace.'\\Api\\'.$name;

        $apiClass = new $class($this->httpClient);

        $this->httpClient->setApiClass($apiClass);

        return $apiClass;
    }

    /**
     * Call inaccessible methods of this class through the HttpClient.
     *
     * @param $name
     * @param $arguments
     *
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        return call_user_func_array([$this->httpClient, $name], $arguments);
    }

    /**
     * @return mixed
     */
    abstract protected function getServiceProvider();
}


<?php

namespace Evispa\ObjectMigration\Action;

/**
 * Description of ActionSerializer
 *
 * @author nerijus
 */
class ActionSerializer
{
    const ACTION_CREATE = 1;
    const ACTION_CLONE = 2;

    public static function serializeAction(MigrationActionInterface $action) {
        if ($action instanceof CloneAction) {
            return array(self::ACTION_CLONE, $action->getMethod()->class, $action->getMethod()->getName());
        } elseif ($action instanceof CreateAction) {
            return array(self::ACTION_CREATE, $action->getMethod()->class, $action->getMethod()->getName());
        }
        throw new \Exception('Unkown action '.  get_class($action));
    }

    /**
     * @param array $data
     *
     * @return MigrationActionInterface
     */
    public static function deserializeAction($data) {
        if (self::ACTION_CLONE === $data[0]) {
            return new CloneAction(new \ReflectionMethod($data[1], $data[2]));
        } elseif (self::ACTION_CREATE === $data[0]) {
            return new CreateAction(new \ReflectionMethod($data[1], $data[2]));
        }
        throw new \Exception('Can not deserialize "'.  $data[1] . '"" action.');
    }
}


<?php

namespace Think\Db;

use PDO;
use PDOException;
use Think\BaseException;

/**
 * Class Driver
 * @package Think\Db
 * @method  mixed insertAll(array $dataSet, $options = [], $replace = false) 批量插入记录
 */
abstract class Driver
{
    /**
     * @var \PDOStatement $PDOStatement PDO操作实例
     */
    protected $PDOStatement = null;
    // 当前操作所属的模型名
    protected $model = '_think_';
    // 当前SQL指令
    protected $queryStr = '';
    protected $modelSql = [];
    // 最后插入ID
    protected $lastInsID = null;
    // 返回或者影响记录数
    protected $numRows = 0;
    // 事务指令数
    protected $transTimes = 0;
    // 错误信息
    protected $error = '';
    // 数据库连接ID 支持多个连接
    protected $linkID = [];
    /**
     * @var \PDO $_linkID 当前连接ID
     */
    protected $_linkID = null;
    // 数据库连接参数配置
    protected $config = [
        'type'           => '',     // 数据库类型
        'hostname'       => '127.0.0.1', // 服务器地址
        'database'       => '',          // 数据库名
        'username'       => '',      // 用户名
        'password'       => '',          // 密码
        'hostport'       => '',        // 端口
        'dsn'            => '', //
        'params'         => [], // 数据库连接参数
        'charset'        => 'utf8',      // 数据库编码默认采用utf8
        'prefix'         => '',    // 数据库表前缀
        'debug'          => false, // 数据库调试模式
        'deploy'         => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
        'rw_separate'    => false,       // 数据库读写是否分离 主从式有效
        'master_num'     => 1, // 读写分离后 主服务器数量
        'slave_no'       => '', // 指定从服务器序号
        'db_like_fields' => '',
    ];
    // 数据库表达式
    protected $exp = [
        'eq'          => '=',
        'neq'         => '<>',
        'gt'          => '>',
        'egt'         => '>=',
        'lt'          => '<',
        'elt'         => '<=',
        'notlike'     => 'NOT LIKE',
        'like'        => 'LIKE',
        'in'          => 'IN',
        'notin'       => 'NOT IN',
        'not in'      => 'NOT IN',
        'between'     => 'BETWEEN',
        'not between' => 'NOT BETWEEN',
        'notbetween'  => 'NOT BETWEEN',
    ];
    // 查询表达式
    protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%';
    // 查询次数
    protected $queryTimes = 0;
    // 执行次数
    protected $executeTimes = 0;
    // PDO连接参数
    protected $options = [
        PDO::ATTR_CASE              => PDO::CASE_NATURAL,
        PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,
        PDO::ATTR_STRINGIFY_FETCHES => false,
    ];
    // 参数绑定
    protected $bind = [];

    /**
     * 读取数据库配置信息

     *
     * @param array $config 数据库配置数组
     */
    public function __construct(array $config = [])
    {
        if (!empty($config)) {
            $this->config = array_merge($this->config, $config);
            if (is_array($this->config['params'])) {
                $this->options = $this->config['params'] + $this->options;
            }
        }
    }

    /**
     * 启动事务

     * @return mixed
     */
    public function startTrans()
    {
        $this->initConnect();
        if (!$this->_linkID) {
            return false;
        }
        //数据rollback 支持
        if ($this->transTimes == 0) {
            $this->_linkID->beginTransaction();
        }
        $this->transTimes++;

        return;
    }

    /**
     * 初始化数据库连接

     * @return void
     */
    protected function initConnect()
    {
        // 默认单数据库
        if (!$this->_linkID) {
            $this->_linkID = $this->connect();
        }
    }

    /**
     * 连接数据库方法

     *
     * @param string $config
     * @param int $linkNum
     * @param bool $autoConnection
     * @return mixed|PDO
     * @throws BaseException
     */
    public function connect($config = '', $linkNum = 0, $autoConnection = false)
    {
        if (!isset($this->linkID[$linkNum])) {
            if (empty($config)) {
                $config = $this->config;
            }
            try {
                if (empty($config['dsn'])) {
                    $config['dsn'] = $this->parseDsn($config);
                }
                $this->linkID[$linkNum] = new PDO(
                    $config['dsn'],
                    $config['username'],
                    $config['password'],
                    $this->options
                );
            } catch (PDOException $e) {
                if ($autoConnection) {
                    trace($e->getMessage(), '', 'ERR');

                    return $this->connect($autoConnection, $linkNum);
                } elseif ($config['debug']) {
                    throw new BaseException($e->getMessage());
                }
            }
        }

        return $this->linkID[$linkNum];
    }

    /**
     * 解析pdo连接的dsn信息

     *
     * @param array $config 连接信息
     *
     * @return string
     */
    protected function parseDsn(array $config = [])
    {
    }

    /**
     * 用于非自动提交状态下面的查询提交

     * @return bool
     */
    public function commit()
    {
        if ($this->transTimes > 0) {
            $result = $this->_linkID->commit();
            $this->transTimes = 0;
            if (!$result) {
                $this->error();

                return false;
            }
        }

        return true;
    }

    /**
     * 数据库错误信息
     * 并显示当前的SQL语句

     * @return string
     * @throws BaseException
     */
    public function error()
    {
        if ($this->PDOStatement) {
            $error = $this->PDOStatement->errorInfo();
            $this->error = $error[1].':'.$error[2];
        } else {
            $this->error = '';
        }
        if ('' != $this->queryStr) {
            $this->error .= "\n [ SQL语句 ] : ".$this->queryStr;
        }
        // 记录错误日志
        trace($this->error, '', 'ERR');
        // 开启数据库调试模式
        if ($this->config['debug']) {
            throw new BaseException($this->error);
        } else {
            return $this->error;
        }
    }

    /**
     * 事务回滚

     * @return bool
     */
    public function rollback()
    {
        if ($this->transTimes > 0) {
            $result = $this->_linkID->rollBack();
            $this->transTimes = 0;
            if (!$result) {
                $this->error();

                return false;
            }
        }

        return true;
    }

    /**
     * 获得查询次数

     *
     * @param bool $execute 是否包含所有查询
     *
     * @return int
     */
    public function getQueryTimes($execute = false)
    {
        return $execute ? $this->queryTimes + $this->executeTimes : $this->queryTimes;
    }

    /**
     * 获得执行次数

     * @return int
     */
    public function getExecuteTimes()
    {
        return $this->executeTimes;
    }

    /**
     * 插入记录

     *
     * @param array $data 数据
     * @param array $options 参数表达式
     * @param bool $replace 是否replace
     *
     * @return false | int
     */
    public function insert(array $data, array $options = [], $replace = false)
    {
        $values = $fields = [];
        $this->model = $options['model'];
        $this->parseBind(!empty($options['bind']) ? $options['bind'] : []);
        foreach ($data as $key => $val) {
            if (is_array($val) && 'exp' == $val[0]) {
                $fields[] = $this->parseKey($key);
                $values[] = $val[1];
            } elseif (is_null($val)) {
                $fields[] = $this->parseKey($key);
                $values[] = 'NULL';
                // 过滤非标量数据
            } elseif (is_scalar($val)) {
                $fields[] = $this->parseKey($key);
                if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) {
                    $values[] = $this->parseValue($val);
                } else {
                    $name = count($this->bind);
                    $values[] = ':'.$name;
                    $this->bindParam($name, $val);
                }
            }
        }
        // 兼容数字传入方式
        $replace = (is_numeric($replace) && $replace > 0) ? true : $replace;
        $sql = (true === $replace ? 'REPLACE' : 'INSERT').' INTO '.$this->parseTable(
                $options['table']
            ).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')'.$this->parseDuplicate($replace);
        $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');

        return $this->execute($sql, !empty($options['fetch_sql']));
    }

    /**
     * 参数绑定分析

     *
     * @param array $bind
     */
    protected function parseBind(array $bind = [])
    {
        $this->bind = array_merge($this->bind, $bind);
    }

    /**
     * 字段名分析

     *
     * @param string $key
     *
     * @return string
     */
    protected function parseKey(&$key)
    {
        return $key;
    }

    /**
     * value分析

     *
     * @param mixed $value
     *
     * @return string
     */
    protected function parseValue($value)
    {
        if (is_string($value)) {
            $value = strpos($value, ':') === 0 && in_array($value, array_keys($this->bind)) ? $this->escapeString(
                $value
            ) : '\''.$this->escapeString($value).'\'';
        } elseif (isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp') {
            $value = $this->escapeString($value[1]);
        } elseif (is_array($value)) {
            $value = array_map([$this, 'parseValue'], $value);
        } elseif (is_bool($value)) {
            $value = $value ? '1' : '0';
        } elseif (is_null($value)) {
            $value = 'null';
        }

        return $value;
    }

    /**
     * SQL指令安全过滤

     *
     * @param string $str SQL字符串
     *
     * @return string
     */
    public function escapeString($str)
    {
        return addslashes($str);
    }

    /**
     * 参数绑定

     *
     * @param string $name 绑定参数名
     * @param mixed $value 绑定值
     *
     * @return void
     */
    protected function bindParam($name, $value)
    {
        $this->bind[':'.$name] = $value;
    }

    /**
     * table分析

     *
     * @param string|array $tables
     *
     * @return string
     */
    protected function parseTable($tables)
    {
        // 支持别名定义
        if (is_array($tables)) {
            $array = [];
            foreach ($tables as $table => $alias) {
                if (!is_numeric($table)) {
                    $array[] = $this->parseKey($table).' '.$this->parseKey($alias);
                } else {
                    $array[] = $this->parseKey($alias);
                }
            }
            $tables = $array;
        } elseif (is_string($tables)) {
            $tables = explode(',', $tables);
            array_walk($tables, [&$this, 'parseKey']);
        }

        return implode(',', $tables);
    }

    /**
     * ON DUPLICATE KEY UPDATE 分析

     *
     * @param mixed $duplicate
     *
     * @return string
     */
    protected function parseDuplicate($duplicate)
    {
        return '';
    }

    /**
     * comment分析

     *
     * @param string $comment
     *
     * @return string
     */
    protected function parseComment($comment)
    {
        return !empty($comment) ? ' /* '.$comment.' */' : '';
    }

    /**
     * 执行语句

     *
     * @param string $str sql指令
     * @param bool $fetchSql 不执行只是获取SQL
     *
     * @throws \PDOException
     * @return mixed
     */
    public function execute($str, $fetchSql = false)
    {
        $this->initConnect();
        if (!$this->_linkID) {
            return false;
        }
        $this->queryStr = $str;
        if (!empty($this->bind)) {
            $that = $this;
            $this->queryStr = strtr(
                $this->queryStr,
                array_map(
                    function ($val) use ($that) {
                        return '\''.$that->escapeString($val).'\'';
                    },
                    $this->bind
                )
            );
        }
        if ($fetchSql) {
            return $this->queryStr;
        }
        //释放前次的查询结果
        if (!empty($this->PDOStatement)) {
            $this->free();
        }
        $this->executeTimes++;
        // 记录写入操作
//            N('db_write', 1);
        // 记录开始执行时间
        $this->debug(true);
        $this->PDOStatement = $this->_linkID->prepare($str);
        if (false === $this->PDOStatement) {
            $this->error();

            return false;
        }
        foreach ($this->bind as $key => $val) {
            if (is_array($val)) {
                $this->PDOStatement->bindValue($key, $val[0], $val[1]);
            } else {
                $this->PDOStatement->bindValue($key, $val);
            }
        }
        $this->bind = [];
        try {
            $result = $this->PDOStatement->execute();
            // 调试结束
            $this->debug(false);
            if (false === $result) {
                $this->error();

                return false;
            } else {
                $this->numRows = $this->PDOStatement->rowCount();
                if (preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) {
                    $this->lastInsID = $this->_linkID->lastInsertId();
                }

                return $this->numRows;
            }
        } catch (PDOException $e) {
            $this->error();

            return false;
        }
    }

    /**
     * 释放查询结果

     */
    public function free()
    {
        $this->PDOStatement = null;
    }

    /**
     * 数据库调试 记录当前SQL

     *
     * @param bool $start 调试开始标记 true 开始 false 结束
     */
    protected function debug($start)
    {
        // 开启数据库调试模式
        if ($this->config['debug']) {
            if ($start) {
                G('queryStartTime');
            } else {
                $this->modelSql[$this->model] = $this->queryStr;
                // 记录操作结束时间
                G('queryEndTime');
                trace($this->queryStr.' [ RunTime:'.G('queryStartTime', 'queryEndTime').'s ]', '', 'SQL');
            }
        }
    }

    /**
     * 通过Select方式插入记录
     * @access   public
     *
     * @param string $fields 要插入的数据表字段名
     * @param string $table 要插入的数据表名
     * @param array $options 查询数据参数
     *
     * @return false|int
     */
    public function selectInsert($fields, $table, array $options = [])
    {
        $this->model = $options['model'];
        $this->parseBind(!empty($options['bind']) ? $options['bind'] : []);
        if (is_string($fields)) {
            $fields = explode(',', $fields);
        }
        array_walk($fields, [$this, 'parseKey']);
        $sql = 'INSERT INTO '.$this->parseTable($table).' ('.implode(',', $fields).') ';
        $sql .= $this->buildSelectSql($options);

        return $this->execute($sql, !empty($options['fetch_sql']));
    }

    /**
     * 生成查询SQL

     *
     * @param array $options 表达式
     *
     * @return string
     */
    public function buildSelectSql(array $options = [])
    {
        if (isset($options['page'])) {
            // 根据页数计算limit
            list($page, $listRows) = $options['page'];
            $page = $page > 0 ? $page : 1;
            $listRows = $listRows > 0 ? $listRows : (is_numeric(
                $options['limit']
            ) ? $options['limit'] : 20);
            $offset = $listRows * ($page - 1);
            $options['limit'] = $offset.','.$listRows;
        }

        return $this->parseSql($this->selectSql, $options);
    }

    /**
     * 替换SQL语句中表达式

     *
     * @param  string $sql
     * @param array $options 表达式
     *
     * @return string
     */
    public function parseSql($sql = '', array $options = [])
    {
        return str_replace(
            [
                '%TABLE%',
                '%DISTINCT%',
                '%FIELD%',
                '%JOIN%',
                '%WHERE%',
                '%GROUP%',
                '%HAVING%',
                '%ORDER%',
                '%LIMIT%',
                '%UNION%',
                '%LOCK%',
                '%COMMENT%',
                '%FORCE%',
            ],
            [
                $this->parseTable($options['table']),
                $this->parseDistinct(isset($options['distinct']) ? $options['distinct'] : false),
                $this->parseField(!empty($options['field']) ? $options['field'] : '*'),
                $this->parseJoin(!empty($options['join']) ? $options['join'] : ''),
                $this->parseWhere(!empty($options['where']) ? $options['where'] : ''),
                $this->parseGroup(!empty($options['group']) ? $options['group'] : ''),
                $this->parseHaving(!empty($options['having']) ? $options['having'] : ''),
                $this->parseOrder(!empty($options['order']) ? $options['order'] : ''),
                $this->parseLimit(!empty($options['limit']) ? $options['limit'] : ''),
                $this->parseUnion(!empty($options['union']) ? $options['union'] : ''),
                $this->parseLock(isset($options['lock']) ? $options['lock'] : false),
                $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''),
                $this->parseForce(!empty($options['force']) ? $options['force'] : ''),
            ],
            $sql
        );
    }

    /**
     * distinct分析

     *
     * @param mixed $distinct
     *
     * @return string
     */
    protected function parseDistinct($distinct)
    {
        return !empty($distinct) ? ' DISTINCT ' : '';
    }

    /**
     * field分析
     *
     * @param mixed $fields
     *
     * @return string
     */
    protected function parseField($fields)
    {
        if (is_string($fields) && '' !== $fields) {
            $fields = explode(',', $fields);
        }
        if (is_array($fields)) {
            // 完善数组方式传字段名的支持
            // 支持 'field1'=>'field2' 这样的字段别名定义
            $array = [];
            foreach ($fields as $key => $field) {
                if (!is_numeric($key)) {
                    $array[] = $this->parseKey($key).' AS '.$this->parseKey($field);
                } else {
                    $array[] = $this->parseKey($field);
                }
            }
            $fieldsStr = implode(',', $array);
        } else {
            $fieldsStr = '*';
        }

        //TODO 如果是查询全部字段，并且是join的方式，那么就把要查的表加个别名，以免字段被覆盖
        return $fieldsStr;
    }

    /**
     * join分析

     *
     * @param mixed $join
     *
     * @return string
     */
    protected function parseJoin($join)
    {
        $joinStr = '';
        if (!empty($join)) {
            $joinStr = ' '.implode(' ', $join).' ';
        }

        return $joinStr;
    }

    /**
     * where分析

     *
     * @param string|array $where
     *
     * @return string
     */
    protected function parseWhere($where)
    {
        $whereStr = '';
        if (is_string($where)) {
            // 直接使用字符串条件
            $whereStr = $where;
        } else { // 使用数组表达式
            $operate = isset($where['_logic']) ? strtoupper($where['_logic']) : '';
            if (in_array($operate, ['AND', 'OR', 'XOR'])) {
                // 定义逻辑运算规则 例如 OR XOR AND NOT
                $operate = ' '.$operate.' ';
                unset($where['_logic']);
            } else {
                // 默认进行 AND 运算
                $operate = ' AND ';
            }
            foreach ($where as $key => $val) {
                if (is_numeric($key)) {
                    $key = '_complex';
                }
                if (0 === strpos($key, '_')) {
                    // 解析特殊条件表达式
                    $whereStr .= $this->parseThinkWhere($key, $val);
                } else {
                    // 查询字段的安全过滤
                    // if(!preg_match('/^[A-Z_\|\&\-.a-z0-9\(\)\,]+$/',trim($key))){
                    //     E(L('_EXPRESS_ERROR_').':'.$key);
                    // }
                    // 多条件支持
                    $multi = is_array($val) && isset($val['_multi']);
                    $key = trim($key);
                    // 支持 name|title|nickname 方式定义查询字段
                    if (strpos($key, '|')) {
                        $array = explode('|', $key);
                        $str = [];
                        foreach ($array as $m => $k) {
                            $v = $multi ? $val[$m] : $val;
                            $str[] = $this->parseWhereItem($this->parseKey($k), $v);
                        }
                        $whereStr .= '( '.implode(' OR ', $str).' )';
                    } elseif (strpos($key, '&')) {
                        $array = explode('&', $key);
                        $str = [];
                        foreach ($array as $m => $k) {
                            $v = $multi ? $val[$m] : $val;
                            $str[] = '('.$this->parseWhereItem($this->parseKey($k), $v).')';
                        }
                        $whereStr .= '( '.implode(' AND ', $str).' )';
                    } else {
                        $whereStr .= $this->parseWhereItem($this->parseKey($key), $val);
                    }
                }
                $whereStr .= $operate;
            }
            $whereStr = substr($whereStr, 0, -strlen($operate));
        }

        return empty($whereStr) ? '' : ' WHERE '.$whereStr;
    }

    /**
     * 特殊条件分析

     *
     * @param string $key
     * @param mixed $val
     *
     * @return string
     */
    protected function parseThinkWhere($key, $val)
    {
        $whereStr = '';
        switch ($key) {
            case '_string':
                // 字符串模式查询条件
                $whereStr = $val;
                break;
            case '_complex':
                // 复合查询条件
                $whereStr = substr($this->parseWhere($val), 6);
                break;
            case '_query':
                // 字符串模式查询条件
                parse_str($val, $where);
                if (isset($where['_logic'])) {
                    $op = ' '.strtoupper($where['_logic']).' ';
                    unset($where['_logic']);
                } else {
                    $op = ' AND ';
                }
                $array = [];
                foreach ($where as $field => $data) {
                    $array[] = $this->parseKey($field).' = '.$this->parseValue($data);
                }
                $whereStr = implode($op, $array);
                break;
            default:
                break;
        }

        return '( '.$whereStr.' )';
    }

    /**
     * where子单元解析
     *
     * @param $key
     * @param $val
     * @return string
     * @throws BaseException
     */
    protected function parseWhereItem($key, $val)
    {
        $whereStr = '';
        if (is_array($val)) {
            if (is_string($val[0])) {
                $exp = strtolower($val[0]);
                // 比较运算
                if (preg_match('/^(eq|neq|gt|egt|lt|elt)$/', $exp)) {
                    $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]);
                    // 模糊查找
                } elseif (preg_match('/^(notlike|like)$/', $exp)) {
                    if (is_array($val[1])) {
                        $likeLogic = isset($val[2]) ? strtoupper($val[2]) : 'OR';
                        if (in_array($likeLogic, ['AND', 'OR', 'XOR'])) {
                            $like = [];
                            foreach ($val[1] as $item) {
                                $like[] = $key.' '.$this->exp[$exp].' '.$this->parseValue($item);
                            }
                            $whereStr .= '('.implode(' '.$likeLogic.' ', $like).')';
                        }
                    } else {
                        $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]);
                    }
                    // 使用表达式
                } elseif ('bind' == $exp) {
                    $whereStr .= $key.' = :'.$val[1];
                    // 使用表达式
                } elseif ('exp' == $exp) {
                    $whereStr .= $key.' '.$val[1];
                    // IN 运算
                } elseif (preg_match('/^(notin|not in|in)$/', $exp)) {
                    if (isset($val[2]) && 'exp' == $val[2]) {
                        $whereStr .= $key.' '.$this->exp[$exp].' '.$val[1];
                    } else {
                        if (is_string($val[1])) {
                            $val[1] = explode(',', $val[1]);
                        }
                        $zone = implode(',', $this->parseValue($val[1]));
                        $whereStr .= $key.' '.$this->exp[$exp].' ('.$zone.')';
                    }
                    // BETWEEN运算
                } elseif (preg_match('/^(notbetween|not between|between)$/', $exp)) {
                    $data = is_string($val[1]) ? explode(',', $val[1]) : $val[1];
                    $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue(
                            $data[0]
                        ).' AND '.$this->parseValue($data[1]);
                } else {
                    throw new BaseException(L('_EXPRESS_ERROR_').':'.$val[0]);
                }
            } else {
                $count = count($val);
                $rule = isset($val[$count - 1]) ? (is_array($val[$count - 1]) ? strtoupper(
                    $val[$count - 1][0]
                ) : strtoupper($val[$count - 1])) : '';
                if (in_array($rule, ['AND', 'OR', 'XOR'])) {
                    $count = $count - 1;
                } else {
                    $rule = 'AND';
                }
                for ($i = 0; $i < $count; $i++) {
                    $data = is_array($val[$i]) ? $val[$i][1] : $val[$i];
                    if ('exp' == strtolower($val[$i][0])) {
                        $whereStr .= $key.' '.$data.' '.$rule.' ';
                    } else {
                        $whereStr .= $this->parseWhereItem($key, $val[$i]).' '.$rule.' ';
                    }
                }
                $whereStr = '( '.substr($whereStr, 0, -4).' )';
            }
        } else {
            //对字符串类型字段采用模糊匹配
            $likeFields = $this->config['db_like_fields'];
            if ($likeFields && preg_match('/^('.$likeFields.')$/i', $key)) {
                $whereStr .= $key.' LIKE '.$this->parseValue('%'.$val.'%');
            } else {
                $whereStr .= $key.' = '.$this->parseValue($val);
            }
        }

        return $whereStr;
    }

    /**
     * group分析

     *
     * @param mixed $group
     *
     * @return string
     */
    protected function parseGroup($group)
    {
        return !empty($group) ? ' GROUP BY '.$group : '';
    }

    /**
     * having分析

     *
     * @param string $having
     *
     * @return string
     */
    protected function parseHaving($having)
    {
        return !empty($having) ? ' HAVING '.$having : '';
    }

    /**
     * order分析

     *
     * @param mixed $order
     *
     * @return string
     */
    protected function parseOrder($order)
    {
        if (is_array($order)) {
            $array = [];
            foreach ($order as $key => $val) {
                if (is_numeric($key)) {
                    $array[] = $this->parseKey($val);
                } else {
                    $array[] = $this->parseKey($key).' '.$val;
                }
            }
            $order = implode(',', $array);
        }

        return !empty($order) ? ' ORDER BY '.$order : '';
    }

    /**
     * limit分析

     *
     * @param mixed $limit
     *
     * @return string
     */
    protected function parseLimit($limit)
    {
        return !empty($limit) ? ' LIMIT '.$limit.' ' : '';
    }

    /**
     * union分析

     *
     * @param mixed $union
     *
     * @return string
     */
    protected function parseUnion($union)
    {
        if (empty($union)) {
            return '';
        }
        if (isset($union['_all'])) {
            $str = 'UNION ALL ';
            unset($union['_all']);
        } else {
            $str = 'UNION ';
        }
        foreach ($union as $u) {
            $sql[] = $str.(is_array($u) ? $this->buildSelectSql($u) : $u);
        }

        return implode(' ', $sql);
    }

    /**
     * 设置锁机制

     *
     * @param bool $lock
     *
     * @return string
     */
    protected function parseLock($lock = false)
    {
        return $lock ? ' FOR UPDATE ' : '';
    }

    /**
     * index分析，可在操作链中指定需要强制使用的索引

     *
     * @param mixed $index
     *
     * @return string
     */
    protected function parseForce($index)
    {
        if (empty($index)) {
            return '';
        }
        if (is_array($index)) {
            $index = implode(",", $index);
        }

        return sprintf(" FORCE INDEX ( %s ) ", $index);
    }

    /**
     * 更新记录

     *
     * @param mixed $data 数据
     * @param array $options 表达式
     *
     * @return false | int
     */
    public function update($data, $options)
    {
        $this->model = $options['model'];
        $this->parseBind(!empty($options['bind']) ? $options['bind'] : []);
        $table = $this->parseTable($options['table']);
        $sql = 'UPDATE '.$table.$this->parseSet($data);
        // 多表更新支持JOIN操作
        if (strpos($table, ',')) {
            $sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : '');
        }
        $sql .= $this->parseWhere(!empty($options['where']) ? $options['where'] : '');
        if (!strpos($table, ',')) {
            //  单表更新支持order和lmit
            $sql .= $this->parseOrder(!empty($options['order']) ? $options['order'] : '')
                .$this->parseLimit(!empty($options['limit']) ? $options['limit'] : '');
        }
        $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');

        return $this->execute($sql, !empty($options['fetch_sql']));
    }

    /**
     * set分析

     *
     * @param array $data
     *
     * @return string
     */
    protected function parseSet($data)
    {
        foreach ($data as $key => $val) {
            if (is_array($val) && isset($val[0]) && 'exp' == $val[0]) {
                $set[] = $this->parseKey($key).'='.$val[1];
            } elseif (is_null($val)) {
                $set[] = $this->parseKey($key).'=NULL';
            } elseif (is_scalar($val)) {// 过滤非标量数据
                if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) {
                    $set[] = $this->parseKey($key).'='.$this->escapeString($val);
                } else {
                    $name = count($this->bind);
                    $set[] = $this->parseKey($key).'=:'.$name;
                    $this->bindParam($name, $val);
                }
            }
        }

        return ' SET '.implode(',', $set);
    }

    /**
     * 删除记录

     *
     * @param array $options 表达式
     *
     * @return false | int
     */
    public function delete($options = [])
    {
        $this->model = $options['model'];
        $this->parseBind(!empty($options['bind']) ? $options['bind'] : []);
        $table = $this->parseTable($options['table']);
        $sql = 'DELETE FROM '.$table;
        // 多表删除支持USING和JOIN操作
        if (strpos($table, ',')) {
            if (!empty($options['using'])) {
                $sql .= ' USING '.$this->parseTable($options['using']).' ';
            }
            $sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : '');
        }
        $sql .= $this->parseWhere(!empty($options['where']) ? $options['where'] : '');
        if (!strpos($table, ',')) {
            // 单表删除支持order和limit
            $sql .= $this->parseOrder(!empty($options['order']) ? $options['order'] : '')
                .$this->parseLimit(!empty($options['limit']) ? $options['limit'] : '');
        }
        $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');

        return $this->execute($sql, !empty($options['fetch_sql']));
    }

    /**
     * 查找记录

     *
     * @param array $options 表达式
     *
     * @return mixed
     */
    public function select(array $options = [])
    {
        $this->model = $options['model'];
        $this->parseBind(!empty($options['bind']) ? $options['bind'] : []);
        $sql = $this->buildSelectSql($options);

        return $this->query($sql, !empty($options['fetch_sql']));
    }

    /**
     * 执行查询 返回数据集

     *
     * @param string $str sql指令
     * @param bool $fetchSql 不执行只是获取SQL
     *
     * @throws \PDOException
     * @return mixed
     */
    public function query($str, $fetchSql = false)
    {
        $this->initConnect();
        if (!$this->_linkID) {
            return false;
        }
        $this->queryStr = $str;
        if (!empty($this->bind)) {
            $that = $this;
            $this->queryStr = strtr(
                $this->queryStr,
                array_map(
                    function ($val) use ($that) {
                        return '\''.$that->escapeString($val).'\'';
                    },
                    $this->bind
                )
            );
        }
        if ($fetchSql) {
            return $this->queryStr;
        }
        //释放前次的查询结果
        if (!empty($this->PDOStatement)) {
            $this->free();
        }
        $this->queryTimes++;
        // 记录查询操作
//            N('db_query', 1);
        // 调试开始
        $this->debug(true);
        $this->PDOStatement = $this->_linkID->prepare($str);
        if (false === $this->PDOStatement) {
            $this->error();

            return false;
        }
        foreach ($this->bind as $key => $val) {
            if (is_array($val)) {
                $this->PDOStatement->bindValue($key, $val[0], $val[1]);
            } else {
                $this->PDOStatement->bindValue($key, $val);
            }
        }
        $this->bind = [];
        try {
            $result = $this->PDOStatement->execute();
            // 调试结束
            $this->debug(false);
            if (false === $result) {
                $this->error();

                return false;
            } else {
                return $this->getResult();
            }
        } catch (PDOException $e) {
            $this->error();

            return false;
        }
    }

    /**
     * 获得所有的查询数据

     * @return array
     */
    private function getResult()
    {
        //返回数据集
        $result = $this->PDOStatement->fetchAll(PDO::FETCH_ASSOC);
        $this->numRows = count($result);

        return $result;
    }

    /**
     * 获取最近一次查询的sql语句
     *
     * @param string $model 模型名
     *

     * @return string
     */
    public function getLastSql($model = '')
    {
        return $model ? $this->modelSql[$model] : $this->queryStr;
    }

    /**
     * 获取最近插入的ID

     * @return string
     */
    public function getLastInsID()
    {
        return $this->lastInsID;
    }

    /**
     * 获取最近的错误信息

     * @return string
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * 设置当前操作模型

     *
     * @param string $model 模型名
     *
     * @return void
     */
    public function setModel($model)
    {
        $this->model = $model;
    }

    /**
     * 析构方法

     */
    public function __destruct()
    {
        // 释放查询
        if ($this->PDOStatement) {
            $this->free();
        }
        // 关闭连接
        $this->close();
    }

    /**
     * 关闭数据库

     */
    public function close()
    {
        $this->_linkID = null;
    }
}


<?php

namespace Think\Cache\Driver;

use Think\BaseException;
use Think\Cache;

/**
 * Redis缓存驱动
 * 要求安装phpredis扩展：https://github.com/nicolasff/phpredis
 */
class Redis extends Cache
{
    /**
     * @param array $options 缓存参数
     *
     * @throws BaseException
     */
    public function __construct(array $options = [])
    {
        if (!extension_loaded('redis')) {
            throw new BaseException(L('_NOT_SUPPORT_').':redis');
        }
        $options = array_merge(
            [
                'host'       => C('REDIS_HOST') ?: '127.0.0.1',
                'port'       => C('REDIS_PORT') ?: 6379,
                'timeout'    => C('DATA_CACHE_TIMEOUT'),
                'persistent' => false,
            ],
            $options
        );

        $this->options = $options;
        $this->options['expire'] = isset($options['expire']) ? $options['expire'] : C('DATA_CACHE_TIME');
        $this->options['prefix'] = isset($options['prefix']) ? $options['prefix'] : C('DATA_CACHE_PREFIX');
        $this->options['length'] = isset($options['length']) ? $options['length'] : 0;
        $func = $options['persistent'] ? 'pconnect' : 'connect';
        $this->handler = new \Redis;
        $options['timeout'] === false ?
            $this->handler->$func($options['host'], $options['port']) :
            $this->handler->$func($options['host'], $options['port'], $options['timeout']);
    }

    /**
     * 读取缓存
     *
     * @param string $name 缓存变量名
     *
     * @return mixed
     */
    public function get($name)
    {
//            N('cache_read', 1);
        $value = $this->handler->get($this->options['prefix'].$name);
        $jsonData = json_decode($value, true);

        //检测是否为JSON数据 true 返回JSON解析数组, false返回源数据
        return ($jsonData === null) ? $value : $jsonData;
    }

    /**
     * 写入缓存
     *
     * @param string $name 缓存变量名
     * @param mixed $value 存储数据
     * @param int $expire 有效时间（秒）
     *
     * @return bool
     */
    public function set($name, $value, $expire = null)
    {
//            N('cache_write', 1);
        if (is_null($expire)) {
            $expire = $this->options['expire'];
        }
        $name = $this->options['prefix'].$name;
        //对数组/对象数据进行缓存处理，保证数据完整性
        $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value;
        if (is_int($expire) && $expire) {
            $result = $this->handler->setex($name, $expire, $value);
        } else {
            $result = $this->handler->set($name, $value);
        }
        if ($result && $this->options['length'] > 0) {
            // 记录缓存队列
            $this->queue($name);
        }

        return $result;
    }

    /**
     * 删除缓存
     *
     * @param string $name 缓存变量名
     *
     * @return void
     */
    public function rm($name)
    {
        $this->handler->delete($this->options['prefix'].$name);
    }

    /**
     * 清除缓存
     * @return bool
     */
    public function clear()
    {
        return $this->handler->flushDB();
    }

}


<?php

declare(strict_types=1);

namespace Ruwork\ObjectStore\TypeResolver;

use Psr\Container\ContainerInterface;
use Ruwork\ObjectStore\Exception\UnexpectedValueException;
use Ruwork\ObjectStore\Type\StoreTypeInterface;

final class StoreTypeResolver implements StoreTypeResolverInterface
{
    private $types;
    private $resolvedTypes;

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

    /**
     * {@inheritdoc}
     */
    public function resolve(string $typeName): ResolvedStoreTypeInterface
    {
        if (isset($this->resolvedTypes[$typeName])) {
            return $this->resolvedTypes[$typeName];
        }

        $type = $this->types->get($typeName);

        if (!$type instanceof StoreTypeInterface) {
            throw UnexpectedValueException::createForValue($type, StoreTypeInterface::class);
        }

        $all = [];

        foreach ($type::getRequiredTypes() as $childName) {
            if (isset($all[$childName])) {
                continue;
            }

            $resolvedChild = $this->resolve($childName);

            foreach ($resolvedChild->getRequiredTypes() as $child2Name => $child2) {
                if (isset($all[$child2Name])) {
                    continue;
                }

                $all[$child2Name] = $child2;
            }

            $all[$childName] = $resolvedChild->getType();
        }

        return $this->resolvedTypes[$typeName] = new ResolvedStoreType($typeName, $type, $all);
    }
}


<?php declare(strict_types=1);
/**
 * Uthando CMS (http://www.shaunfreeman.co.uk/)
 *
 * @package   UthandoUser\Event
 * @author    Shaun Freeman <shaun@shaunfreeman.co.uk>
 * @link      https://github.com/uthando-cms for the canonical source repository
 * @copyright Copyright (c) 2014 Shaun Freeman. (http://www.shaunfreeman.co.uk)
 * @license   see LICENSE
 */

namespace UthandoUser\Event;

use UthandoUser\Controller\Plugin\IsAllowed;
use UthandoUser\Controller\UserController;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\Http\Request;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Mvc\MvcEvent;

/**
 * Class MvcListener
 *
 * @package UthandoUser\Event
 */
class MvcListener implements ListenerAggregateInterface
{
    /**
     * @var \Zend\Stdlib\CallbackHandler[]
     */
    protected $listeners = [];

    /**
     * {@inheritDoc}
     */
    public function attach(EventManagerInterface $events)
    {
        $events = $events->getSharedManager();
        $this->listeners[] = $events->attach(
            AbstractActionController::class,
            MvcEvent::EVENT_DISPATCH,
            [$this, 'doAuthentication'],
            2
        );
    }

    public function detach(EventManagerInterface $events)
    {
        foreach ($this->listeners as $index => $listener) {
            if ($events->detach($listener)) {
                unset($this->listeners[$index]);
            }
        }
    }

    public function doAuthentication(MvcEvent $event)
    {
        if (!$event->getRequest() instanceof Request) {
            return true;
        }

        $application    = $event->getApplication();
        $sm             = $application->getServiceManager();
        $match          = $event->getRouteMatch();
        $controller     = $match->getParam('controller');
        $action         = $match->getParam('action');
        $plugin         = $sm->get('ControllerPluginManager')->get(IsAllowed::class);
        $hasIdentity    = $plugin->getIdentity();

        if (!$plugin->isAllowed($controller, $action)) {

            $router = $event->getRouter();
            $route  = (
                'guest' === $hasIdentity->getRoleId() &&
                $plugin->isAllowed(UserController::class, 'login')
            ) ? 'user' : 'home';
            $url    = $router->assemble([], ['name' => $route]);

            $response = $event->getResponse();
            $response->setStatusCode(302);
            //redirect to login route...
            // change with header('location: '.$url); if code below not working
            $response->getHeaders()->addHeaderLine('Location', $url);
            $event->stopPropagation();
            return $response;
        }
        return true;
    }
}


<?php

namespace Potherca\Katwizy\Immutable;

use Symfony\Component\HttpFoundation\Request;

class Debug
{
    ////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
    const DEBUG_OFF = '0';
    const DEBUG_ON = '1';
    const DEBUG_TOKEN = 'debug-token';

    /** @var bool */
    private $debug;
    /** @var Request */
    private $request;

    //////////////////////////// SETTERS AND GETTERS \\\\\\\\\\\\\\\\\\\\\\\\\\\
    /**
     * @return bool
     */
    private function getDebug()
    {
        if ($this->debug === null) {
            $this->debug = $this->createDebug();
        }

        return $this->debug;
    }

    //////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    /**
     * @param Request $request
     */
    final public function __construct(Request $request = null)
    {
        $this->request = $request;
    }

    final public function __toString()
    {
        return $this->getDebug()
            ? self::DEBUG_ON
            : self::DEBUG_OFF
        ;
    }

    ////////////////////////////// UTILITY METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    /**
     * @return bool
     */
    private function createDebug()
    {
        $debug = getenv('SYMFONY_DEBUG');

        if ((int)$debug !== 0) {
            $debug = true;
        } else {
            $systemDebugToken = getenv('DEBUG_TOKEN');
            $userDebugToken = null;

            $request = $this->request;

            if ($request !== null) {
                $userDebugToken = $this->debugToken($request);
                $cookieDebugToken = $request->cookies->get(self::DEBUG_TOKEN);

                if ($userDebugToken === null) {
                    $userDebugToken = $cookieDebugToken;
                } elseif ($userDebugToken !== $cookieDebugToken) {
                    $this->setCookie($userDebugToken);
                } // else { /*Cookie already set*/ }
            }

            if ($userDebugToken !== null && $userDebugToken === $systemDebugToken) {
                $debug = true;
            }
        }

        return $debug;
    }

    /**
     * @param Request $request
     *
     * @return string|null
     */
    private function debugToken(Request $request)
    {
        $tokens = [
            $request->request->get(self::DEBUG_TOKEN),   // $_POST
            $request->query->get(self::DEBUG_TOKEN),     // $_GET
            $request->headers->get(self::DEBUG_TOKEN),   // Header
        ];

        /* Remove empty values from array */
        $tokens = array_filter($tokens);

        return array_shift($tokens);
    }

    /**
     * @param mixed $userDebugToken
     */
    private function setCookie($userDebugToken)
    {
        $name = self::DEBUG_TOKEN;
        $value = $userDebugToken;
        $expire = 0;
        $path = '/';
        $domain = null;
        $secure = false;
        $httpOnly = true;

        try {
            $domain = $this->request->getHost();
        } catch (\UnexpectedValueException $exception) {
            // Host name is invalid
        }

        setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
    }

}


<?php

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

namespace jarrus90\User\controllers;

use jarrus90\User\UserFinder;
use jarrus90\User\models\Profile;
use jarrus90\User\models\SettingsForm;
use jarrus90\User\Module;
use jarrus90\Core\Traits\AjaxValidationTrait;
use jarrus90\User\traits\EventTrait;
use Yii;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\ForbiddenHttpException;
use yii\web\NotFoundHttpException;

/**
 * SettingsController manages updating user settings (e.g. profile, email and password).
 *
 * @property \jarrus90\User\Module $module
 *
 * @author Dmitry Erofeev <dmeroff@gmail.com>
 */
class SettingsController extends \yii\web\Controller {

    use AjaxValidationTrait;

    use EventTrait;

    /**
     * Event is triggered before updating user's profile.
     * Triggered with \jarrus90\User\events\UserEvent.
     */
    const EVENT_BEFORE_PROFILE_UPDATE = 'beforeProfileUpdate';

    /**
     * Event is triggered after updating user's profile.
     * Triggered with \jarrus90\User\events\UserEvent.
     */
    const EVENT_AFTER_PROFILE_UPDATE = 'afterProfileUpdate';

    /**
     * Event is triggered before updating user's account settings.
     * Triggered with \jarrus90\User\events\FormEvent.
     */
    const EVENT_BEFORE_ACCOUNT_UPDATE = 'beforeAccountUpdate';

    /**
     * Event is triggered after updating user's account settings.
     * Triggered with \jarrus90\User\events\FormEvent.
     */
    const EVENT_AFTER_ACCOUNT_UPDATE = 'afterAccountUpdate';

    /**
     * Event is triggered before changing users' email address.
     * Triggered with \jarrus90\User\events\UserEvent.
     */
    const EVENT_BEFORE_CONFIRM = 'beforeConfirm';

    /**
     * Event is triggered after changing users' email address.
     * Triggered with \jarrus90\User\events\UserEvent.
     */
    const EVENT_AFTER_CONFIRM = 'afterConfirm';

    /**
     * Event is triggered before disconnecting social account from user.
     * Triggered with \jarrus90\User\events\ConnectEvent.
     */
    const EVENT_BEFORE_DISCONNECT = 'beforeDisconnect';

    /**
     * Event is triggered after disconnecting social account from user.
     * Triggered with \jarrus90\User\events\ConnectEvent.
     */
    const EVENT_AFTER_DISCONNECT = 'afterDisconnect';

    /** @inheritdoc */
    public $defaultAction = 'profile';

    /** @var UserFinder */
    protected $finder;

    /**
     * @param string           $id
     * @param \yii\base\Module $module
     * @param UserFinder           $finder
     * @param array            $config
     */
    public function __construct($id, $module, UserFinder $finder, $config = []) {
        $this->finder = $finder;
        parent::__construct($id, $module, $config);
    }

    /** @inheritdoc */
    public function behaviors() {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'disconnect' => ['post'],
                ],
            ],
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => ['profile', 'account', 'networks', 'disconnect'],
                        'roles' => ['@'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['confirm'],
                        'roles' => ['?', '@'],
                    ],
                ],
            ],
        ];
    }

    /**
     * Shows profile settings form.
     *
     * @return string|\yii\web\Response
     */
    public function actionProfile() {
        $model = $this->finder->findProfileById(Yii::$app->user->identity->getId());

        if ($model == null) {
            $model = Yii::createObject(Profile::className());
            $model->link('user', Yii::$app->user->identity);
        }

        $event = $this->getProfileEvent($model);

        $this->performAjaxValidation($model);

        $this->trigger(self::EVENT_BEFORE_PROFILE_UPDATE, $event);
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            Yii::$app->getSession()->setFlash('success', Yii::t('user', 'Your profile has been updated'));
            $this->trigger(self::EVENT_AFTER_PROFILE_UPDATE, $event);
            return $this->refresh();
        }

        return $this->render('profile', [
                    'model' => $model,
        ]);
    }

    /**
     * Displays page where user can update account settings (username, email or password).
     *
     * @return string|\yii\web\Response
     */
    public function actionAccount() {
        /** @var SettingsForm $model */
        $model = Yii::createObject(SettingsForm::className());
        $event = $this->getFormEvent($model);

        $this->performAjaxValidation($model);

        $this->trigger(self::EVENT_BEFORE_ACCOUNT_UPDATE, $event);
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            Yii::$app->session->setFlash('success', Yii::t('user', 'Your account details have been updated'));
            $this->trigger(self::EVENT_AFTER_ACCOUNT_UPDATE, $event);
            return $this->refresh();
        }

        return $this->render('account', [
                    'model' => $model,
        ]);
    }

    /**
     * Attempts changing user's email address.
     *
     * @param int    $id
     * @param string $code
     *
     * @return string
     * @throws \yii\web\HttpException
     */
    public function actionConfirm($id, $code) {
        $user = $this->finder->findUserById($id);

        if ($user === null || $this->module->emailChangeStrategy == Module::STRATEGY_INSECURE) {
            throw new NotFoundHttpException();
        }

        $event = $this->getUserEvent($user);

        $this->trigger(self::EVENT_BEFORE_CONFIRM, $event);
        $user->attemptEmailChange($code);
        $this->trigger(self::EVENT_AFTER_CONFIRM, $event);

        return $this->redirect(['account']);
    }

    /**
     * Displays list of connected network accounts.
     *
     * @return string
     */
    public function actionNetworks() {
        return $this->render('networks', [
                    'user' => Yii::$app->user->identity,
        ]);
    }

    /**
     * Disconnects a network account from user.
     *
     * @param int $id
     *
     * @return \yii\web\Response
     * @throws \yii\web\NotFoundHttpException
     * @throws \yii\web\ForbiddenHttpException
     */
    public function actionDisconnect($id) {
        $account = $this->finder->findAccount()->byId($id)->one();

        if ($account === null) {
            throw new NotFoundHttpException();
        }
        if ($account->user_id != Yii::$app->user->id) {
            throw new ForbiddenHttpException();
        }

        $event = $this->getConnectEvent($account, $account->user);

        $this->trigger(self::EVENT_BEFORE_DISCONNECT, $event);
        $account->delete();
        $this->trigger(self::EVENT_AFTER_DISCONNECT, $event);

        return $this->redirect(['networks']);
    }

}


<?php

namespace Reaction\I18n;

use React\Filesystem\Node\FileInterface;
use Reaction;
use Reaction\Promise\ExtendedPromiseInterface;
use function Reaction\Promise\reject;
use function Reaction\Promise\resolve;

/**
 * PhpMessageSource represents a message source that stores translated messages in PHP scripts.
 *
 * PhpMessageSource uses PHP arrays to keep message translations.
 *
 * - Each PHP script contains one array which stores the message translations in one particular
 *   language and for a single message category;
 * - Each PHP script is saved as a file named as "[[basePath]]/LanguageID/CategoryName.php";
 * - Within each PHP script, the message translations are returned as an array like the following:
 *
 * ```php
 * return [
 *     'original message 1' => 'translated message 1',
 *     'original message 2' => 'translated message 2',
 * ];
 * ```
 *
 * You may use [[fileMap]] to customize the association between category names and the file names.
 */
class PhpMessageSource extends MessageSource
{
    /**
     * @var string the base path for all translated messages. Defaults to '@app/Messages'.
     */
    public $basePath = '@app/Messages';
    /**
     * @var array mapping between message categories and the corresponding message file paths.
     * The file paths are relative to [[basePath]]. For example,
     *
     * ```php
     * [
     *     'core' => 'core.php',
     *     'ext' => 'extensions.php',
     * ]
     * ```
     */
    public $fileMap;
    /**
     * @var array|null All used categories
     */
    protected $_categories;

    /**
     * Loads the message translation for the specified $language and $category.
     * If translation for specific locale code such as `en-US` isn't found it
     * tries more generic `en`. When both are present, the `en-US` messages will be merged
     * over `en`. See [[loadFallbackMessages]] for details.
     * If the $language is less specific than [[sourceLanguage]], the method will try to
     * load the messages for [[sourceLanguage]]. For example: [[sourceLanguage]] is `en-GB`,
     * $language is `en`. The method will load the messages for `en` and merge them over `en-GB`.
     *
     * @param string $category the message category
     * @param string $language the target language
     * @return ExtendedPromiseInterface with array the loaded messages. The keys are original messages, and the values are the translated messages.
     * @see loadFallbackMessages
     * @see sourceLanguage
     */
    protected function loadMessages($category, $language)
    {
        $messageFile = $this->getMessageFilePath($category, $language);
        $method = __METHOD__;
        return $this->loadMessagesFromFile($messageFile)
            ->otherwise(function() { return null; })
            ->then(function($messages) use ($category, $language, $messageFile, $method) {
                $fallbackLanguage = substr($language, 0, 2);
                $fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2);

                if ($language !== $fallbackLanguage) {
                    return $this->loadFallbackMessages($category, $fallbackLanguage, $messages, $messageFile);
                } elseif ($language === $fallbackSourceLanguage) {
                    return $this->loadFallbackMessages($category, $this->sourceLanguage, $messages, $messageFile);
                } else {
                    if ($messages === null) {
                        Reaction::warning("The message file for category '$category' does not exist: $messageFile in {$method}");
                    }
                    return (array)$messages;
                }
            });
    }

    /**
     * The method is normally called by [[loadMessages]] to load the fallback messages for the language.
     * Method tries to load the $category messages for the $fallbackLanguage and adds them to the $messages array.
     *
     * @param string $category the message category
     * @param string $fallbackLanguage the target fallback language
     * @param array $messages the array of previously loaded translation messages.
     * The keys are original messages, and the values are the translated messages.
     * @param string $originalMessageFile the path to the file with messages. Used to log an error message
     * in case when no translations were found.
     * @return ExtendedPromiseInterface with array the loaded messages. The keys are original messages, and the values are the translated messages.
     */
    protected function loadFallbackMessages($category, $fallbackLanguage, $messages, $originalMessageFile)
    {
        $fallbackMessageFile = $this->getMessageFilePath($category, $fallbackLanguage);
        return $this->loadMessagesFromFile($fallbackMessageFile)
            ->otherwise(function() { return null; })
            ->then(function($fallbackMessages) use ($category, $messages, $fallbackMessageFile, $fallbackLanguage, $originalMessageFile) {
                if (
                    $messages === null && $fallbackMessages === null
                    && $fallbackLanguage !== $this->sourceLanguage
                    && $fallbackLanguage !== substr($this->sourceLanguage, 0, 2)
                ) {
                    Reaction::error("The message file for category '$category' does not exist: $originalMessageFile "
                        . "Fallback file does not exist as well: $fallbackMessageFile");
                } elseif (empty($messages)) {
                    return $fallbackMessages;
                } elseif (!empty($fallbackMessages)) {
                    foreach ($fallbackMessages as $key => $value) {
                        if (!empty($value) && empty($messages[$key])) {
                            $messages[$key] = $fallbackMessages[$key];
                        }
                    }
                }

                return (array)$messages;
            });
    }

    /**
     * Returns message file path for the specified language and category.
     *
     * @param string $category the message category
     * @param string $language the target language
     * @return string path to message file
     */
    protected function getMessageFilePath($category, $language)
    {
        $messageFile = Reaction::$app->getAlias($this->basePath) . "/$language/";
        if (isset($this->fileMap[$category])) {
            $messageFile .= $this->fileMap[$category];
        } else {
            $messageFile .= str_replace('\\', '/', $category) . '.php';
        }

        return $messageFile;
    }

    /**
     * Loads the message translation for the specified language and category or returns null if file doesn't exist.
     *
     * @param string $messageFile path to message file
     * @return ExtendedPromiseInterface with array of messages or null if file not found
     */
    protected function loadMessagesFromFile($messageFile)
    {
        if (is_file($messageFile)) {
            $messages = include $messageFile;
            if (!is_array($messages)) {
                $messages = [];
            }

            return resolve($messages);
        }

        return reject(new Reaction\Exceptions\Error("Message file '{$messageFile}' not found"));
    }

    /**
     * Find all categories used in message source
     * @return ExtendedPromiseInterface
     */
    protected function findAllCategories()
    {
        if (isset($this->_categories)) {
            return resolve($this->_categories);
        }
        $categoryMap = is_array($this->fileMap) ? array_flip($this->fileMap) : [];
        $baseDirPath = Reaction::getAlias($this->basePath);
        //Use resolve()->then() to convert PromiseInterface to ExtendedPromiseInterface
        return resolve(true)
            ->then(function() use ($baseDirPath, $categoryMap) {
                $dir = Reaction\Helpers\FileHelperAsc::dir($baseDirPath);
                return $dir->lsRecursive()
                    ->then(function($results) use ($baseDirPath, $categoryMap) {
                        $categories = [];
                        foreach ($results as $result) {
                            if (!is_object($result) || !$result instanceof FileInterface || substr($result->getPath(), -4) !== '.php') {
                                continue;
                            }
                            //Remove base path part
                            $filePath = substr($result->getPath(), mb_strlen($baseDirPath) + 1);
                            //Remove language part
                            if (($langSepPos = strpos($filePath, DIRECTORY_SEPARATOR)) !== false) {
                                $filePath = substr($filePath, $langSepPos + 1);
                            }
                            //Search category in file map
                            if (isset($categoryMap[$filePath])) {
                                $categories[] = $categoryMap[$filePath];
                                continue;
                            } else {
                                //Remove .php extension
                                $filePath = substr($filePath, 0, -4);
                            }
                            //Add possible category with another slashes
                            if (strpos($filePath, DIRECTORY_SEPARATOR) !== false) {
                                $categories[] = str_replace(DIRECTORY_SEPARATOR, '\\', $filePath);
                            }
                            $categories[] = $filePath;
                        }
                        $this->_categories = array_unique($categories);
                        sort($this->_categories);
                        return $this->_categories;
                    });
            });

    }
}


<?php

/**
 * Jin Framework
 * Diatem
 */

namespace Jin2\Form\Components;

/**
 * Composant ColorPicker (Choix couleur)
 */
class ColorPicker extends AbstractComponent
{

  public static $assetsLoaded = false;

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

  /**
   * Rendu du composant
   *
   * @return type
   */
  public function render()
  {
    $html = '';
    if (!self::$assetsLoaded) {
      $html = static::loadAssets();
    }
    $html .= parent::render();
    return $html;
  }

  /**
   * Charge les assets
   *
   * @return string
   */
  protected static function loadAssets()
  {
    self::$assetsLoaded = true;
    return static::getAssetContent('js') . static::getAssetContent('css');
  }

}


<?php

namespace Reaction\Rbac\Migrations;

use Reaction;
use Reaction\Db\ConnectionInterface;
use Reaction\Db\Migration;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Rbac\DbManager;
use function Reaction\Promise\allInOrder;

/**
 * Initializes RBAC tables.
 */
class m140506_102106_rbac_init extends Migration
{
    /**
     * @throws \Reaction\Exceptions\InvalidConfigException
     * @return DbManager
     */
    protected function getAuthManager()
    {
        $authManager = Reaction::$app->getAuthManager();
        if (!$authManager instanceof DbManager) {
            throw new InvalidConfigException('You should configure "authManager" component to use database before executing this migration.');
        }

        return $authManager;
    }

    /**
     * Check that DB is MSSQL
     * @return bool
     */
    protected function isMSSQL()
    {
        $driver = $this->db->getDriverName();
        return $driver === 'mssql' || $driver === 'sqlsrv' || $driver === 'dblib';
    }

    /**
     * Check that DB is Oracle
     * @return bool
     */
    protected function isOracle()
    {
        return $this->db->getDriverName() === 'oci';
    }

    /**
     * {@inheritdoc}
     */
    public function safeUp(ConnectionInterface $connection)
    {
        $authManager = $this->getAuthManager();
        $this->db = $authManager->db;

        $tableOptions = null;
        if ($this->db->getDriverName() === 'mysql') {
            // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
            $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
        }

        $promises = [];

        $promises[] = $this->createTable($authManager->ruleTable, [
            'name' => $this->string(64)->notNull(),
            'data' => $this->binary(),
            'created_at' => $this->integer(),
            'updated_at' => $this->integer(),
            'PRIMARY KEY ([[name]])',
        ], $tableOptions);

        $promises[] = $this->createTable($authManager->itemTable, [
            'name' => $this->string(64)->notNull(),
            'type' => $this->smallInteger()->notNull(),
            'description' => $this->text(),
            'rule_name' => $this->string(64),
            'data' => $this->binary(),
            'created_at' => $this->integer(),
            'updated_at' => $this->integer(),
            'PRIMARY KEY ([[name]])',
            'FOREIGN KEY ([[rule_name]]) REFERENCES ' . $authManager->ruleTable . ' ([[name]])' .
                $this->buildFkClause('ON DELETE SET NULL', 'ON UPDATE CASCADE'),
        ], $tableOptions);
        $promises[] = $this->createIndex('idx-auth_item-type', $authManager->itemTable, 'type');

        $promises[] = $this->createTable($authManager->itemChildTable, [
            'parent' => $this->string(64)->notNull(),
            'child' => $this->string(64)->notNull(),
            'PRIMARY KEY ([[parent]], [[child]])',
            'FOREIGN KEY ([[parent]]) REFERENCES ' . $authManager->itemTable . ' ([[name]])' .
                $this->buildFkClause('ON DELETE CASCADE', 'ON UPDATE CASCADE'),
            'FOREIGN KEY ([[child]]) REFERENCES ' . $authManager->itemTable . ' ([[name]])' .
                $this->buildFkClause('ON DELETE CASCADE', 'ON UPDATE CASCADE'),
        ], $tableOptions);

        $promises[] = $this->createTable($authManager->assignmentTable, [
            'item_name' => $this->string(64)->notNull(),
            'user_id' => $this->string(64)->notNull(),
            'created_at' => $this->integer(),
            'PRIMARY KEY ([[item_name]], [[user_id]])',
            'FOREIGN KEY ([[item_name]]) REFERENCES ' . $authManager->itemTable . ' ([[name]])' .
                $this->buildFkClause('ON DELETE CASCADE', 'ON UPDATE CASCADE'),
        ], $tableOptions);

        if ($this->isMSSQL()) {
            $promises[] = $this->execute("CREATE TRIGGER dbo.trigger_auth_item_child
            ON dbo.{$authManager->itemTable}
            INSTEAD OF DELETE, UPDATE
            AS
            DECLARE @old_name VARCHAR (64) = (SELECT name FROM deleted)
            DECLARE @new_name VARCHAR (64) = (SELECT name FROM inserted)
            BEGIN
            IF COLUMNS_UPDATED() > 0
                BEGIN
                    IF @old_name <> @new_name
                    BEGIN
                        ALTER TABLE {$authManager->itemChildTable} NOCHECK CONSTRAINT FK__auth_item__child;
                        UPDATE {$authManager->itemChildTable} SET child = @new_name WHERE child = @old_name;
                    END
                UPDATE {$authManager->itemTable}
                SET name = (SELECT name FROM inserted),
                type = (SELECT type FROM inserted),
                description = (SELECT description FROM inserted),
                rule_name = (SELECT rule_name FROM inserted),
                data = (SELECT data FROM inserted),
                created_at = (SELECT created_at FROM inserted),
                updated_at = (SELECT updated_at FROM inserted)
                WHERE name IN (SELECT name FROM deleted)
                IF @old_name <> @new_name
                    BEGIN
                        ALTER TABLE {$authManager->itemChildTable} CHECK CONSTRAINT FK__auth_item__child;
                    END
                END
                ELSE
                    BEGIN
                        DELETE FROM dbo.{$authManager->itemChildTable} WHERE parent IN (SELECT name FROM deleted) OR child IN (SELECT name FROM deleted);
                        DELETE FROM dbo.{$authManager->itemTable} WHERE name IN (SELECT name FROM deleted);
                    END
            END;");
        }
        return allInOrder($promises);
    }

    /**
     * {@inheritdoc}
     */
    public function safeDown(ConnectionInterface $connection)
    {
        $authManager = $this->getAuthManager();
        $this->db = $authManager->db;

        $promises = [];
        if ($this->isMSSQL()) {
            $promises[] = $this->execute('DROP TRIGGER dbo.trigger_auth_item_child;');
        }

        $promises[] = $this->dropTable($authManager->assignmentTable);
        $promises[] = $this->dropTable($authManager->itemChildTable);
        $promises[] = $this->dropTable($authManager->itemTable);
        $promises[] = $this->dropTable($authManager->ruleTable);
        return allInOrder($promises);
    }

    /**
     * Build foreign key clause string
     * @param string $delete
     * @param string $update
     * @return string
     */
    protected function buildFkClause($delete = '', $update = '')
    {
        if ($this->isMSSQL()) {
            return '';
        }

        if ($this->isOracle()) {
            return ' ' . $delete;
        }

        return implode(' ', ['', $delete, $update]);
    }
}


<?php

namespace helionogueir\shell\parameter;

use Exception;
use helionogueir\shell\Environment;
use helionogueir\languagepack\Lang;
use helionogueir\shell\autoload\Environment as Env;

/**
 * - Getter paramter in shell
 * @author Helio Nogueira <helio.nogueir@gmail.com>
 * @version v1.0.0
 */
class Getter {

  /**
   * - Check if script execute on shell
   * @return null
   */
  public function __construct() {
    if (!(new Environment())->onShell()) {
      Lang::addRoot(Env::PACKAGE, Env::PATH);
      throw new Exception(Lang::get("shell:environment:not:phpcli", "helionogueir/shell"));
    }
  }

  /**
   * - Check variable exist
   * @param Array $namespaces Variable namespace
   * @return bool Case exist return true, or false case not exist
   */
  public function exist(Array $namespaces): string {
    $exist = false;
    foreach ($namespaces as $namespace) {
      if (in_array($namespace, $_SERVER['argv'])) {
        $exist = true;
      }
    }
    return $exist;
  }

  /**
   * - Get variable by namespace
   * @param Array $namespaces Variable namespace
   * @return string Value of namespace
   */
  public function variable(Array $namespaces): string {
    $value = "";
    if (count($namespaces)) {
      for ($index = 0; $index < count($_SERVER['argv']); $index++) {
        if (!is_object($_SERVER['argv'][$index]) && in_array($_SERVER['argv'][$index], $namespaces)) {
          $value = "";
          if (isset($_SERVER['argv'][++$index])) {
            $value = $_SERVER['argv'][$index];
          }
          break;
        }
      }
    }
    return $value;
  }

}


<?php

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

namespace Valkyrja\Http;

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

/**
 * Class ResponseBuilder.
 *
 * @author Melech Mizrachi
 */
class NativeResponseBuilder implements ResponseBuilder
{
    use Provides;

    /**
     * The application.
     *
     * @var Application
     */
    protected $app;

    /**
     * ResponseBuilder constructor.
     *
     * @param Application $app
     */
    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    /**
     * Make a new instance of Response.
     *
     * @param string $content    [optional] The response content
     * @param int    $statusCode [optional] The response status code
     * @param array  $headers    [optional] An array of response headers
     *
     * @return \Valkyrja\Http\Response
     */
    public function make(string $content = '', int $statusCode = StatusCode::OK, array $headers = []): Response
    {
        return $this->app->response($content, $statusCode, $headers);
    }

    /**
     * View response builder.
     *
     * @param string $template   The view template to use
     * @param array  $data       [optional] The view data
     * @param int    $statusCode [optional] The response status code
     * @param array  $headers    [optional] An array of response headers
     *
     * @return \Valkyrja\Http\Response
     */
    public function view(
        string $template,
        array $data = [],
        int $statusCode = StatusCode::OK,
        array $headers = []
    ): Response {
        $content = $this->app->view()->make($template, $data)->render();

        return $this->make($content, $statusCode, $headers);
    }

    /**
     * Json response builder.
     *
     * @param array $data       [optional] The data to set
     * @param int   $statusCode [optional] The response status code
     * @param array $headers    [optional] An array of response headers
     *
     * @return \Valkyrja\Http\JsonResponse
     */
    public function json(array $data = [], int $statusCode = StatusCode::OK, array $headers = []): JsonResponse
    {
        return $this->app->json($data, $statusCode, $headers);
    }

    /**
     * JsonP response builder.
     *
     * @param string $callback   The jsonp callback
     * @param array  $data       [optional] The data to set
     * @param int    $statusCode [optional] The response status code
     * @param array  $headers    [optional] An array of response headers
     *
     * @throws \InvalidArgumentException
     *
     * @return \Valkyrja\Http\JsonResponse
     */
    public function jsonp(
        string $callback,
        array $data = [],
        int $statusCode = StatusCode::OK,
        array $headers = []
    ): JsonResponse {
        return $this->json($data, $statusCode, $headers)->setCallback(
            $callback
        );
    }

    /**
     * Redirect to response builder.
     *
     * @param string $uri        [optional] The uri to redirect to
     * @param int    $statusCode [optional] The response status code
     * @param array  $headers    [optional] An array of response headers
     *
     * @return \Valkyrja\Http\RedirectResponse
     */
    public function redirect(
        string $uri = '/',
        int $statusCode = StatusCode::FOUND,
        array $headers = []
    ): RedirectResponse {
        return $this->app->redirect($uri, $statusCode, $headers);
    }

    /**
     * Redirect to a named route response builder.
     *
     * @param string $route      The route to match
     * @param array  $parameters [optional] Any parameters to set for dynamic
     *                           routes
     * @param int    $statusCode [optional] The response status code
     * @param array  $headers    [optional] An array of response headers
     *
     * @return \Valkyrja\Http\RedirectResponse
     */
    public function route(
        string $route,
        array $parameters = [],
        int $statusCode = StatusCode::FOUND,
        array $headers = []
    ): RedirectResponse {
        return $this->app->redirectRoute(
            $route,
            $parameters,
            $statusCode,
            $headers
        );
    }

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

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


<?php declare(strict_types = 1); namespace BapCat\Values;

use InvalidArgumentException;

/**
 * Represents a class
 *
 * @property-read  string  $raw
 * @property-read  Text    $local_part
 * @property-read  Text    $domain_part
 *
 * @author    Corey Frenette
 * @copyright Copyright (c) 2019, BapCat
 */
class Email extends Value {
  /** @var  Text  $local  The local (pre-@) part of the email */
  private $local;

  /** @var  Text  $domain  The domain (post-@) part of the email*/
  private $domain;

  /** @var  string  $raw  The raw email */
  private $raw;

  /**
   * @param  string  $email  The raw class name to wrap
   */
  public function __construct($email) {
    $this->validate($email);
    $this->raw = $email;
    $parts = explode('@', $email);

    //TODO: This probably shouldn't be text
    $this->domain = new Text(array_pop($parts));
    $this->local  = new Text(implode('@', $parts));
  }

  /**
   * Ensures the valid passed in is a valid email
   *
   * @throws  InvalidArgumentException  If the value is not a valid email
   *
   * @param  string  $email  The value to validate
   *
   * @return  void
   */
  private function validate($email): void {
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
      throw new InvalidArgumentException('Expected email address, but got [' . var_export($email, true) . '] instead');
    }
  }

  /**
   * Converts this object to a string
   *
   * @return  string  A string representation of this object
   */
  public function __toString(): string {
    return $this->raw;
  }

  /**
   * Converts this object to a json encodable-form
   *
   * @return  string  A representation of this object suitable for encoding
   */
  public function jsonSerialize(): string {
    return $this->raw;
  }

  /**
   * Gets the raw value this object wraps
   *
   * @return  string  The raw value this object wraps
   */
  protected function getRaw(): string {
    return $this->raw;
  }

  /**
   * Gets the local part of this email
   *
   * @return  Text  The local part of this email
   */
  protected function getLocalPart(): Text {
    return $this->local;
  }

  /**
   * Gets the domain part of this email
   *
   * @return  Text  The domain part of this email
   */
  protected function getDomainPart(): Text {
    return $this->domain;
  }
}