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

namespace CarteBlanche\App;

use \CarteBlanche\CarteBlanche;
use \CarteBlanche\App\Loader;
use \CarteBlanche\App\Kernel;
use \CarteBlanche\App\FrontController;
use \Library\Helper\Text as TextHelper;
use \Library\Helper\Directory as DirectoryHelper;

/**
 * @author  Piero Wbmstr <me@e-piwi.fr>
 */
class Locator
{

    /**
     * Hack to let the 'file_exists' function search in 'include_path'
     *
     * @param   string  $filename   The filename to find
     * @return  bool/string         The valid file path if found, false otherwise
     */
    public static function locate($filename)
    {
        if (@file_exists($filename)) return $filename;

        $_f = CarteBlanche::getPath('carte_blanche_core').$filename;
        if (!empty($_f) && @file_exists($_f)) return $_f;

        $include_paths = explode(PATH_SEPARATOR,get_include_path());
        foreach($include_paths as $_inc) {
            $_f = DirectoryHelper::slashDirname($_inc).$filename;
            if (@file_exists($_f)) return $_f;
        }

        if (class_exists('\CarteBlanche\CarteBlanche')) {
            $bundles = CarteBlanche::getContainer()->get('bundles');
            if (!empty($bundles)) {
                foreach($bundles as $_bundle) {
                    $_f = DirectoryHelper::slashDirname($_bundle->getDirectory()).$filename;
                    if (@file_exists($_f)) return $_f;
                }
            }
        }

        return false;
    }

    /**
     * Locate a file in "data/" directory
     *
     * @param   string $filename
     * @return  null/string
     */
    public static function locateData($filename)
    {
        $etc_dir = CarteBlanche::getPath('config_dir');
        $f = self::locate( DirectoryHelper::slashDirname($etc_dir).$filename );
        if ($f) return $f;
        $var_dir = CarteBlanche::getPath('var_dir');
        $vf = self::locate( DirectoryHelper::slashDirname($var_dir).$filename );
        if ($vf) return $vf;
        return null;
    }

    /**
     * Locate a file in "config/" directory (vendor or not)
     *
     * @param   string  $filename
     * @param   bool    $fallback
     * @return  null/string
     */
    public static function locateConfig($filename, $fallback = true)
    {
        $etc_dir = CarteBlanche::getPath('config_dir');
        if ($fallback) {
            $f = self::locate( DirectoryHelper::slashDirname($etc_dir).$filename );
            if ($f) return $f;
        }
        $vf = self::locate( DirectoryHelper::slashDirname($etc_dir).'vendor/'.$filename );
        if ($vf) return $vf;
        return null;
    }

    /**
     * Locate a file in "i18n/" directory (vendor or not)
     *
     * @param   string  $filename
     * @param   bool    $fallback
     * @return  null/string
     */
    public static function locateLanguage($filename, $fallback = true)
    {
        $ln_dir = CarteBlanche::getPath('language_dir');

        if ($fallback) {
            $f = self::locate( DirectoryHelper::slashDirname($ln_dir).$filename );
            if ($f) {
                return $f;
            }
        }

        $vf = self::locate( DirectoryHelper::slashDirname($ln_dir).'vendor/'.$filename );
        if ($vf) {
            return $vf;
        }

        $mask = CarteBlanche::getConfig('i18n.language_strings_db_filename_mask');
        if ($mask) {
            $argument   = str_replace('%s', '', $mask);
            if (!substr_count($filename, $argument)) {
                $tmp_vf     = sprintf($mask, $filename);
                if ($tmp_vf!=$filename) {
                    return self::locateLanguage($tmp_vf, $fallback);
                }
            }
        }

        return null;
    }

    /**
     * Search a view file in the views directory and sub-directories
     *
     * @param string $view The view filename
     * @param bool $remap
     * @return mixed FALSE if nothing had been find, the filename otherwise
     */
    public static function locateView($view = null, $remap = true)
    {
        if (empty($view)) return;

        // from views mapping
        if (true===$remap) {
            $views_mapping = CarteBlanche::getContainer()->get('config')->get('views');
            if (!empty($views_mapping) && array_key_exists($view, $views_mapping)) {
                $view = $views_mapping[$view];
                if (false!==($remaped = self::locateView($view, false))) {
                    return self::fallback($view, $remaped);
                }
            }
        }

        $views_dir = DirectoryHelper::slashDirname(CarteBlanche::getPath('views_dir'));

        // from the application
        if ($_f = self::locate($views_dir.$view)) {
            return self::fallback($view, $_f);
        }

        // from a bundle
        if ($_f = self::locate(
            DirectoryHelper::slashDirname(CarteBlanche::getPath('bundles_dir')).$view
        )) {
            return self::fallback($view, $_f);
        }

        // from a tool
        if ($_f = self::locate(
            DirectoryHelper::slashDirname(CarteBlanche::getPath('tools_dir')).$view
        )) {
            return self::fallback($view, $_f);
        }

        // globally
        if ($_f = self::locate($view)) {
            return self::fallback($view, $_f);
        }

        if (!self::locate($view)) {
            $view_file = $views_dir.$view;
        } else {
            $view_file = $view;
        }

        if (!self::locate($view_file)) {
            $_ctrl = CarteBlanche::getContainer()
                ->get('front_controller')->getController();
            if (!empty($_ctrl) && property_exists($_ctrl, 'views_dir')) {
                $subdir     = $_ctrl::$views_dir;
                $view_file  = $views_dir.$subdir.$view;
            }
        }

        if (!self::locate($view_file)) {
            $view_file = $view;
        }

        if (!self::locate($view_file)) {
            $view_file = $view;
        }

        if (self::locate($view_file)) {
            return self::fallback($view_file);
        }

        // not found: try with one of configured extensions
        if (true===$remap) {
            $views_extensions = CarteBlanche::getContainer()->get('config')->get('views.extensions');
            if (!empty($views_extensions)) {
                foreach ($views_extensions as $_ext) {
                    $_extended_view = $view.'.'.$_ext;
                    if ($found = self::locateView($_extended_view, false)) {
                        return self::fallback($_extended_view, $found);
                    }
                }
            }
        }

        return false;
    }

    /**
     * Search a controller : from the app or a bundle
     *
     * @param   string  $ctrl   The controller filename
     * @return  mixed   FALSE if nothing had been find, the filename otherwise
     */
    public static function locateController($ctrl)
    {
        $ctrl = TextHelper::toCamelCase($ctrl);
        if (Loader::classExists($ctrl)) {
            return $ctrl;
        }

       // from the application
        $controller = Kernel::CONTROLLER_DEFAULT_NAMESPACE.$ctrl;
        if (false!==($_found = Loader::autoload($controller))) {
            return $_found;
        }

        // from CarteBlanche
        $controller = Kernel::CARTE_BLANCHE_NAMESPACE.'\\'.Kernel::CONTROLLER_DEFAULT_NAMESPACE.$ctrl;
        if (false!==($_found = Loader::autoload($controller))) {
            return $_found;
        }

        // with a full name
        $controller .= Kernel::CONTROLLER_SUFFIX;
        if (false!==($_found = Loader::autoload($controller))) {
            return $_found;
        }

        // from bundles
        if (false!==($_found = Loader::loadClass($ctrl, 'Controller', true))) {
            return $_found;
        }
        // with a full name
        if (false!==($_found = Loader::loadClass($ctrl.Kernel::CONTROLLER_SUFFIX, 'Controller', true))) {
            return $_found;
        }
        return false;
    }

    /**
     * @param   string  $name
     * @param   bool    $is_class
     * @return  bool|mixed|string
     */
    public static function getToolPath($name, $is_class = false)
    {
        $name_parts = explode('\\', $name);
        $tools_dir = CarteBlanche::getFullPath('tools_dir');
        $tool_path = false;
        if ($name_parts[0]==='Tool') {
            $tool_path = str_replace('Tool'.DIRECTORY_SEPARATOR, $tools_dir, str_replace('\\', DIRECTORY_SEPARATOR, $name));
            if (true===$is_class) {
                if (count($name_parts)===2) $tool_path .= '/'.array_pop($name_parts);
                $tool_path .= '.php';
            }
        }
        return $tool_path;
    }

    /**
     * For user overridings
     * This will search a version of `$file` in `user/` and return it in replacement if so.
     *
     * @param   string  $file   The relative file path to search
     * @param   string  $path   The default file path
     * @return  string
     */
    public static function fallback($file = null, $path = null)
    {
        $user_dir = CarteBlanche::getPath('user_path');
        if (file_exists($user_dir.$file)) {
            return $user_dir.$file;
        } else {
            return $path;
        }
    }

}

// Endfile


<?php

namespace Ekyna\Bundle\CoreBundle;

use Ekyna\Bundle\CoreBundle\DependencyInjection\Compiler\FormJsPass;
use Ekyna\Bundle\CoreBundle\DependencyInjection\Compiler\FosHttpCachePass;
use Ekyna\Bundle\CoreBundle\DependencyInjection\Compiler\RedirectionProviderPass;
use Ekyna\Bundle\CoreBundle\DependencyInjection\Compiler\RegisterRoutersPass;
use Ekyna\Bundle\CoreBundle\DependencyInjection\Compiler\SetRouterPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

/**
 * Class EkynaCoreBundle
 * @package Ekyna\Bundle\CoreBundle
 * @author Étienne Dauvergne <contact@ekyna.com>
 */
class EkynaCoreBundle extends Bundle
{
    /**
     * {@inheritdoc}
     */
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new FosHttpCachePass());
        $container->addCompilerPass(new RedirectionProviderPass());
        $container->addCompilerPass(new SetRouterPass());
        $container->addCompilerPass(new RegisterRoutersPass('ekyna_core.router'), PassConfig::TYPE_BEFORE_REMOVING);
        $container->addCompilerPass(new FormJsPass());
    }
}


<?php

namespace gries\NumberSystem;

/**
 * Class Number
 *
 * This is represents a number that can use any kind of number-system passed to it.
 *
 *
 * @package gries\NumberSystem
 */
class Number
{
    /**
     * @var NumberSystem
     */
    protected $numberSystem;

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

    /**
     * @param              $value
     * @param NumberSystem $numberSystem
     * @param mixed         $delimiter
     */
    public function __construct($value, NumberSystem $numberSystem = null)
    {
        if (null === $numberSystem) {
            $numberSystem = new NumberSystem();
        }

        $this->numberSystem = $numberSystem;
        $this->value = $value;

        $this->validate();
    }

    /**
     * Get the value of this number.
     *
     * @return mixed
     */
    public function value()
    {
        return $this->value;
    }

    /**
     * Convert this number into a other number-system.
     *
     * @param NumberSystem $newSystem
     *
     * @return Number
     */
    public function convert(NumberSystem $newSystem)
    {
        $newDigits = [];
        $decimalValue = gmp_init($this->decimalValue());

        do {
            $divisionResult = gmp_div_qr($decimalValue, $newSystem->getBase());
            $remainder = gmp_strval($divisionResult[1]);
            $decimalValue = $divisionResult[0];

            $newDigits[] = $newSystem->getSymbolForPosition($remainder);
        } while (gmp_strval($decimalValue) > 0);

        return $newSystem->buildNumber(array_reverse($newDigits));
    }

    /**
     * Get this number as a decimal string value.
     *
     * @return string
     */
    public function asDecimalString()
    {
        return $this->decimalValue();
    }

    /**
     * Compare two numbers.
     *
     * @param Number $comparedNumber
     *
     * @return bool
     */
    public function equals(Number $comparedNumber)
    {
        if ($this->value() !== $comparedNumber->value() ||
            !$this->getNumberSystem()->equals($comparedNumber->getNumberSystem()))  {
            return false;
        }

        return true;
    }

    /**
     * Get the NumberSystem of this Number.
     *
     * @return NumberSystem
     */
    public function getNumberSystem()
    {
        return $this->numberSystem;
    }

    /**
     * We use this to convert every number to decimal for calculations.
     */
    protected function decimalValue()
    {
        $base = $this->numberSystem->getBase();
        $result = 0;

        foreach (array_reverse($this->getDigits()) as $position => $value) {
            $numberSystemPosition = $this->numberSystem->getSymbolPosition($value);
            $result += $numberSystemPosition * pow($base, $position);
        }

        return $result;
    }

    /**
     * Add two number together.
     * The number-system of the result will be the one of the number
     * who's was the called object.
     *
     * @param Number|Number $addend
     *
     * @return Number
     */
    public function add(Number $addend)
    {
        $resultDecimalValue = $this->decimalValue() + $addend->decimalValue();

        $result = new Number($resultDecimalValue);

        return $result->convert($this->getNumberSystem());
    }

    /**
     * Subtract two numbers.
     * The number-system of the result will be the one of the number
     * who's was the called object.
     *
     * @param Number $subtractor
     *
     * @return Number
     */
    public function subtract(Number $subtractor)
    {
        $resultDecimalValue = $this->decimalValue() - $subtractor->decimalValue();

        $result = new Number($resultDecimalValue);

        return $result->convert($this->getNumberSystem());
    }

    /**
     * Multiply two numbers.
     * The number-system of the result will be the one of the number
     * who's was the called object.
     *
     * @param Number $multiplicator
     *
     * @return Number
     */
    public function multiply(Number $multiplicator)
    {
        $resultDecimalValue = $this->decimalValue() * $multiplicator->decimalValue();

        $result = new Number($resultDecimalValue);

        return $result->convert($this->getNumberSystem());
    }

    /**
     * Divide two numbers.
     * The number-system of the result will be the one of the number
     * who's was the called object.
     *
     * @param Number $multiplicator
     *
     * @return Number
     */
    public function divide(Number $multiplicator)
    {
        $resultDecimalValue = round($this->decimalValue() / $multiplicator->decimalValue(), 0);

        $result = new Number($resultDecimalValue);

        return $result->convert($this->getNumberSystem());
    }

    /**
     * Get a list of digits of this number.
     *
     * @return array
     */
    private function getDigits()
    {
        return $this->numberSystem->getDigits($this);
    }

    /**
     * Check if the number is valid in the current number system.
     */
    private function validate()
    {
        $this->numberSystem->validateNumberValue($this->value());
    }
}


<?php
/*
 * This file is part of wulacms.
 *
 * (c) Leo Ning <windywany@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace curlient;

use curlient\filter\ConcatFilter;
use curlient\filter\JsonFilter;
use curlient\filter\NoHtmlFilter;
use curlient\filter\NoStyleFilter;
use curlient\filter\QueryFilter;
use curlient\filter\ReplaceFilter;
use curlient\filter\StrToTimeFilter;
use curlient\filter\SubFilter;
use curlient\filter\TagAttrFilter;
use curlient\filter\TrimFilter;
use curlient\filter\WrapFilter;

class StringFilter {
	private static $filters  = null;
	private static $INSTANCE = null;

	private function __construct() {
		if (self::$filters === null) {
			self::$filters['sub']       = new SubFilter();
			self::$filters['replace']   = new ReplaceFilter();
			self::$filters['concat']    = new ConcatFilter();
			self::$filters['nohtml']    = new NoHtmlFilter();
			self::$filters['nostyle']   = new NoStyleFilter();
			self::$filters['wrap']      = new WrapFilter();
			self::$filters['trim']      = new TrimFilter();
			self::$filters['json']      = new JsonFilter();
			self::$filters['query']     = new QueryFilter();
			self::$filters['attr']      = new TagAttrFilter();
			self::$filters['strtotime'] = new StrToTimeFilter();
			if (function_exists('fire')) {
				fire('string\initFilter');
			}
		}
	}

	/**
	 * 获取一个字符处理器实例.
	 * @return \curlient\StringFilter
	 */
	public static function getInstance() {
		if (!self::$INSTANCE) {
			self::$INSTANCE = new StringFilter();
		}

		return self::$INSTANCE;
	}

	/**
	 * @param string                 $id
	 * @param \curlient\IFieldFilter $filter
	 */
	public static function register($id, IFieldFilter $filter) {
		if ($id) {
			self::$filters[ $id ] = $filter;
		}
	}

	/**
	 * 取中间的字符串.
	 *
	 * @param string $content
	 * @param array  ...$args
	 *
	 * @return string
	 */
	public static function sub($content, ...$args) {
		array_unshift($args, 'sub');

		return self::getInstance()->filter($content, [$args]);
	}

	/**
	 * 通过正则(简易正则，使用'参数'代表.+?))匹配后再根据规则合并字符（类似于preg_match_callback）.
	 *
	 * @param string $content
	 * @param array  ...$args
	 *
	 * @return string
	 */
	public static function concat($content, ...$args) {
		array_unshift($args, 'concat');

		return self::getInstance()->filter($content, [$args]);
	}

	/**
	 * @param string $content
	 * @param array  $fieldConf
	 *
	 * @return string
	 */
	public function filter($content, array $fieldConf) {
		if ($content) {
			foreach ($fieldConf as $conf) {
				if ($conf) {
					$filterId = array_shift($conf);
					if ($filterId && isset(self::$filters[ $filterId ])) {
						/**@var \curlient\IFieldFilter $filter */
						$filter  = self::$filters[ $filterId ];
						$content = $filter->filter($content, $conf);
					}
				}
			}
		}

		return $content;
	}

	/**
	 * @return array
	 */
	public function getFilters() {
		return self::$filters;
	}
}


<?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\HttpMessage;

use Throwable;
use Valkyrja\Application;
use Valkyrja\Debug\ExceptionHandler;
use Valkyrja\HttpMessage\Events\HttpKernelHandled;
use Valkyrja\HttpMessage\Events\HttpKernelTerminate;
use Valkyrja\HttpMessage\Middleware\MiddlewareAwareTrait;
use Valkyrja\Routing\Route;
use Valkyrja\Routing\Router;
use Valkyrja\Support\Providers\Provides;

/**
 * Class Kernel.
 *
 * @author Melech Mizrachi
 */
class NativeKernel implements Kernel
{
    use MiddlewareAwareTrait;
    use Provides;

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

    /**
     * The router.
     *
     * @var \Valkyrja\Routing\Router
     */
    protected $router;

    /**
     * Kernel constructor.
     *
     * @param Application $application The application
     * @param Router      $router      The router
     */
    public function __construct(Application $application, Router $router)
    {
        $this->app    = $application;
        $this->router = $router;

        $config = $application->config()['routing'];

        self::$middleware       = $config['middleware'];
        self::$middlewareGroups = $config['middlewareGroups'];
    }

    /**
     * Handle a request.
     *
     * @param Request $request The request
     *
     * @throws \Valkyrja\Http\Exceptions\HttpException
     *
     * @return \Valkyrja\HttpMessage\Response
     */
    public function handle(Request $request): Response
    {
        try {
            $response = $this->dispatchRouter($request);
        } catch (Throwable $exception) {
            $response = $this->getExceptionResponse($exception);
        }

        // Dispatch the after request handled middleware and return the response
        $this->responseMiddleware($request, $response);

        // Trigger an event for kernel handled
        $this->app->events()->trigger(
            HttpKernelHandled::class,
            [
                new HttpKernelHandled($request, $response),
            ]
        );

        return $response;
    }

    /**
     * Dispatch the request via the router.
     *
     * @param Request $request The request
     *
     * @return \Valkyrja\HttpMessage\Response
     */
    protected function dispatchRouter(Request $request): Response
    {
        // Set the request object in the container
        $this->app->container()->singleton(Request::class, $request);

        // Dispatch the before request handled middleware
        $request = $this->requestMiddleware($request);

        return $this->router->dispatch($request);
    }

    /**
     * Get a response from an exception.
     *
     * @param \Throwable $exception The exception
     *
     * @return \Valkyrja\HttpMessage\Response
     */
    protected function getExceptionResponse(Throwable $exception): Response
    {
        $handler = new ExceptionHandler($this->app->debug());

        return $handler->getResponse($exception);
    }

    /**
     * Terminate the request.
     *
     * @param Request  $request  The request
     * @param Response $response The response
     *
     * @return void
     */
    public function terminate(Request $request, Response $response): void
    {
        // Dispatch the terminable middleware
        $this->terminableMiddleware($request, $response);

        /* @var Route $route */
        $route = $this->app->container()->getSingleton(Route::class);

        // If the dispatched route has middleware
        if (null !== $route->getMiddleware()) {
            // Terminate each middleware
            $this->terminableMiddleware(
                $request,
                $response,
                $route->getMiddleware()
            );
        }

        // Trigger an event for kernel handled
        $this->app->events()->trigger(
            HttpKernelTerminate::class,
            [
                new HttpKernelTerminate($request, $response),
            ]
        );
    }

    /**
     * Run the kernel.
     *
     * @param Request $request The request
     *
     * @throws \Valkyrja\Http\Exceptions\HttpException
     *
     * @return void
     */
    public function run(Request $request = null): void
    {
        // If no request was passed get the bootstrapped definition
        if (null === $request) {
            $request = $this->app->container()->getSingleton(Request::class);
        }

        // Handle the request, dispatch the after request middleware, and send the response
        $response = $this->handle($request)->send();

        // Terminate the application
        $this->terminate($request, $response);
    }

    /**
     * Get the application.
     *
     * @return \Valkyrja\Application
     */
    protected function getApplication(): Application
    {
        return $this->app;
    }

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

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


<?php
/**
 *  Soluble Components (http://belgattitude.github.io/solublecomponents)
 *
 *  @link      http://github.com/belgattitude/solublecomponents for the canonical source repository
 *  @copyright Copyright (c) 2013-2014 Sébastien Vanvelthem
 *  @license   https://github.com/belgattitude/solublecomponents/blob/master/LICENSE.txt MIT License
 */
namespace Soluble\Db\Compat;

use Zend\Db\Adapter\Adapter;
use Zend\Db\Adapter\Driver;

class Mysqli
{
    /**
     * Return a Zend\Db\Adapter\Adapter object from an existing mysqli connection
     * @param \Mysqli $mysqli
     * @return Adapter
     */
    public static function getAdapter(\Mysqli $mysqli)
    {
        $driver = new Driver\Mysqli\Mysqli($mysqli);
        $adapter = new Adapter($driver);
        return $adapter;
    }
}


<?php

namespace Reaction\Db\Pgsql;

use Reaction\Db\Constraints\Constraint;
use Reaction\Db\Expressions\Expression;
use Reaction\Db\Expressions\ExpressionInterface;
use Reaction\Db\Query;
use Reaction\Exceptions\InvalidArgumentException;
use Reaction\Helpers\StringHelper;
use Reaction\Promise\ExtendedPromiseInterface;
use function Reaction\Promise\reject;
use function Reaction\Promise\resolve;

/**
 * Class QueryBuilder
 * @package Reaction\Db\Pgsql
 */
class QueryBuilder extends \Reaction\Db\QueryBuilder
{
    /**
     * Defines a UNIQUE index for [[createIndex()]].
     * @since 2.0.6
     */
    const INDEX_UNIQUE = 'unique';
    /**
     * Defines a B-tree index for [[createIndex()]].
     * @since 2.0.6
     */
    const INDEX_B_TREE = 'btree';
    /**
     * Defines a hash index for [[createIndex()]].
     * @since 2.0.6
     */
    const INDEX_HASH = 'hash';
    /**
     * Defines a GiST index for [[createIndex()]].
     * @since 2.0.6
     */
    const INDEX_GIST = 'gist';
    /**
     * Defines a GIN index for [[createIndex()]].
     * @since 2.0.6
     */
    const INDEX_GIN = 'gin';

    /**
     * @var array mapping from abstract column types (keys) to physical column types (values).
     */
    public $typeMap = [
        Schema::TYPE_PK => 'serial NOT NULL PRIMARY KEY',
        Schema::TYPE_UPK => 'serial NOT NULL PRIMARY KEY',
        Schema::TYPE_BIGPK => 'bigserial NOT NULL PRIMARY KEY',
        Schema::TYPE_UBIGPK => 'bigserial NOT NULL PRIMARY KEY',
        Schema::TYPE_CHAR => 'char(1)',
        Schema::TYPE_STRING => 'varchar(255)',
        Schema::TYPE_TEXT => 'text',
        Schema::TYPE_TINYINT => 'smallint',
        Schema::TYPE_SMALLINT => 'smallint',
        Schema::TYPE_INTEGER => 'integer',
        Schema::TYPE_BIGINT => 'bigint',
        Schema::TYPE_FLOAT => 'double precision',
        Schema::TYPE_DOUBLE => 'double precision',
        Schema::TYPE_DECIMAL => 'numeric(10,0)',
        Schema::TYPE_DATETIME => 'timestamp(0)',
        Schema::TYPE_TIMESTAMP => 'timestamp(0)',
        Schema::TYPE_TIME => 'time(0)',
        Schema::TYPE_DATE => 'date',
        Schema::TYPE_BINARY => 'bytea',
        Schema::TYPE_BOOLEAN => 'boolean',
        Schema::TYPE_MONEY => 'numeric(19,4)',
        Schema::TYPE_JSON => 'jsonb',
    ];

    /**
     * {@inheritdoc}
     */
    protected function defaultConditionClasses()
    {
        return array_merge(parent::defaultConditionClasses(), [
            'ILIKE' => 'Reaction\Db\conditions\LikeCondition',
            'NOT ILIKE' => 'Reaction\Db\conditions\LikeCondition',
            'OR ILIKE' => 'Reaction\Db\conditions\LikeCondition',
            'OR NOT ILIKE' => 'Reaction\Db\conditions\LikeCondition',
        ]);
    }

    /**
     * {@inheritdoc}
     */
    protected function defaultExpressionBuilders()
    {
        return array_merge(parent::defaultExpressionBuilders(), [
            'Reaction\Db\Expressions\ArrayExpression' => 'Reaction\Db\Pgsql\ArrayExpressionBuilder',
            'Reaction\Db\Expressions\JsonExpression' => 'Reaction\Db\Pgsql\JsonExpressionBuilder',
        ]);
    }

    /**
     * Builds a SQL statement for creating a new index.
     * @param string $name the name of the index. The name will be properly quoted by the method.
     * @param string $table the table that the new index will be created for. The table name will be properly quoted by the method.
     * @param string|array $columns the column(s) that should be included in the index. If there are multiple columns,
     * separate them with commas or use an array to represent them. Each column name will be properly quoted
     * by the method, unless a parenthesis is found in the name.
     * @param bool|string $unique whether to make this a UNIQUE index constraint. You can pass `true` or [[INDEX_UNIQUE]] to create
     * a unique index, `false` to make a non-unique index using the default index type, or one of the following constants to specify
     * the index method to use: [[INDEX_B_TREE]], [[INDEX_HASH]], [[INDEX_GIST]], [[INDEX_GIN]].
     * @return string the SQL statement for creating a new index.
     * @see http://www.postgresql.org/docs/8.2/static/sql-createindex.html
     */
    public function createIndex($name, $table, $columns, $unique = false)
    {
        if ($unique === self::INDEX_UNIQUE || $unique === true) {
            $index = false;
            $unique = true;
        } else {
            $index = $unique;
            $unique = false;
        }

        return ($unique ? 'CREATE UNIQUE INDEX ' : 'CREATE INDEX ') .
            $this->db->quoteTableName($name) . ' ON ' .
            $this->db->quoteTableName($table) .
            ($index !== false ? " USING $index" : '') .
            ' (' . $this->buildColumns($columns) . ')';
    }

    /**
     * Builds a SQL statement for dropping an index.
     * @param string $name the name of the index to be dropped. The name will be properly quoted by the method.
     * @param string $table the table whose index is to be dropped. The name will be properly quoted by the method.
     * @return string the SQL statement for dropping an index.
     */
    public function dropIndex($name, $table)
    {
        return 'DROP INDEX ' . $this->db->quoteTableName($name);
    }

    /**
     * Builds a SQL statement for renaming a DB table.
     * @param string $oldName the table to be renamed. The name will be properly quoted by the method.
     * @param string $newName the new table name. The name will be properly quoted by the method.
     * @return string the SQL statement for renaming a DB table.
     */
    public function renameTable($oldName, $newName)
    {
        return 'ALTER TABLE ' . $this->db->quoteTableName($oldName) . ' RENAME TO ' . $this->db->quoteTableName($newName);
    }

    /**
     * Creates a SQL statement for resetting the sequence value of a table's primary key.
     * The sequence will be reset such that the primary key of the next new row inserted
     * will have the specified value or 1.
     * @param string $tableName the name of the table whose primary key sequence will be reset
     * @param mixed $value the value for the primary key of the next new row inserted. If this is not set,
     * the next new row's primary key will have a value 1.
     * @return string the SQL statement for resetting sequence
     */
    public function resetSequence($tableName, $value = null)
    {
        $tableSchema = $this->db->getSchema()->getTableSchema($tableName);
        if ($tableSchema !== null && $tableSchema->sequenceName !== null) {
            // c.f. http://www.postgresql.org/docs/8.1/static/functions-sequence.html
            $sequence = $this->db->quoteTableName($tableSchema->sequenceName);
            $tableName = $this->db->quoteTableName($tableName);
            if ($value === null) {
                $key = $this->db->quoteColumnName(reset($tableSchema->primaryKey));
                $value = "(SELECT COALESCE(MAX({$key}),0) FROM {$tableName})+1";
            } else {
                $value = (int)$value;
            }

            return "SELECT SETVAL('$sequence',$value,false)";
        } elseif ($tableSchema === null) {
            throw new InvalidArgumentException("Table not found: $tableName");
        }

        throw new InvalidArgumentException("There is not sequence associated with table '$tableName'.");
    }

    /**
     * Builds a SQL statement for enabling or disabling integrity check.
     * @param bool $check whether to turn on or off the integrity check.
     * @param string $schema the schema of the tables.
     * @param string $table the table name.
     * @return string the SQL statement for checking integrity
     */
    public function checkIntegrity($check = true, $schema = '', $table = '')
    {
        $enable = $check ? 'ENABLE' : 'DISABLE';
        $schema = $schema ?: $this->db->getSchema()->defaultSchema;
        $tableNames = $table ? [$table] : $this->db->getSchema()->getTableNames($schema);
        $viewNames = $this->db->getSchema()->getViewNames($schema);
        $tableNames = array_diff($tableNames, $viewNames);
        $command = '';

        foreach ($tableNames as $tableName) {
            $tableName = $this->db->quoteTableName("{$schema}.{$tableName}");
            $command .= "ALTER TABLE $tableName $enable TRIGGER ALL; ";
        }

        return $command;
    }

    /**
     * Builds a SQL statement for truncating a DB table.
     * Explicitly restarts identity for PGSQL to be consistent with other databases which all do this by default.
     * @param string $table the table to be truncated. The name will be properly quoted by the method.
     * @return string the SQL statement for truncating a DB table.
     */
    public function truncateTable($table)
    {
        return 'TRUNCATE TABLE ' . $this->db->quoteTableName($table) . ' RESTART IDENTITY';
    }

    /**
     * Builds a SQL statement for changing the definition of a column.
     * @param string $table the table whose column is to be changed. The table name will be properly quoted by the method.
     * @param string $column the name of the column to be changed. The name will be properly quoted by the method.
     * @param string $type the new column type. The [[getColumnType()]] method will be invoked to convert abstract
     * column type (if any) into the physical one. Anything that is not recognized as abstract type will be kept
     * in the generated SQL. For example, 'string' will be turned into 'varchar(255)', while 'string not null'
     * will become 'varchar(255) not null'. You can also use PostgreSQL-specific syntax such as `SET NOT NULL`.
     * @return string the SQL statement for changing the definition of a column.
     */
    public function alterColumn($table, $column, $type)
    {
        // https://github.com/yiisoft/yii2/issues/4492
        // http://www.postgresql.org/docs/9.1/static/sql-altertable.html
        if (!preg_match('/^(DROP|SET|RESET)\s+/i', $type)) {
            $type = 'TYPE ' . $this->getColumnType($type);
        }

        return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' ALTER COLUMN '
            . $this->db->quoteColumnName($column) . ' ' . $type;
    }

    /**
     * {@inheritdoc}
     */
    public function insert($table, $columns, &$params)
    {
        return parent::insert($table, $this->normalizeTableRowData($table, $columns), $params);
    }

    /**
     * {@inheritdoc}
     * @see https://www.postgresql.org/docs/9.5/static/sql-insert.html#SQL-ON-CONFLICT
     * @see https://stackoverflow.com/questions/1109061/insert-on-duplicate-update-in-postgresql/8702291#8702291
     */
    public function upsert($table, $insertColumns, $updateColumns, &$params)
    {
        $insertColumns = $this->normalizeTableRowData($table, $insertColumns);
        if (!is_bool($updateColumns)) {
            $updateColumns = $this->normalizeTableRowData($table, $updateColumns);
        }
        if (version_compare($this->db->getSchema()->getServerVersion(), '9.5', '<')) {
            return $this->oldUpsert($table, $insertColumns, $updateColumns, $params);
        }

        return $this->newUpsert($table, $insertColumns, $updateColumns, $params);
    }

    /**
     * {@inheritdoc}
     */
    public function update($table, $columns, $condition, &$params)
    {
        $columns = $this->normalizeTableRowData($table, $columns);
        $pk = $this->getTablePrimaryKey($table);
        list($lines, $params) = $this->prepareUpdateSets($table, $columns, $params);
        $sql = 'UPDATE ' . $this->db->quoteTableName($table) . ' SET ' . implode(', ', $lines);
        $where = $this->buildWhere($condition, $params);
        $sql = $where === '' ? $sql : $sql . ' ' . $where;
        $sql .= isset($pk) ? " RETURNING " . $this->db->quoteColumnName($pk) : " RETURNING *";
        return $sql;
    }

    /**
     * {@inheritdoc}
     */
    public function delete($table, $condition, &$params)
    {
        $pk = $this->getTablePrimaryKey($table);
        $sql = 'DELETE FROM ' . $this->db->quoteTableName($table);
        $where = $this->buildWhere($condition, $params);

        $sql = $where === '' ? $sql : $sql . ' ' . $where;
        $sql .= isset($pk) ? " RETURNING " . $this->db->quoteColumnName($pk) : " RETURNING *";
        return $sql;
    }

    /**
     * {@inheritdoc}
     */
    public function batchInsert($table, $columns, $rows, &$params = [])
    {
        if (empty($rows)) {
            return '';
        }

        $schema = $this->db->getSchema();
        if (($tableSchema = $schema->getTableSchema($table)) !== null) {
            $columnSchemas = $tableSchema->columns;
        } else {
            $columnSchemas = [];
        }

        $values = [];
        foreach ($rows as $row) {
            $vs = [];
            foreach ($row as $i => $value) {
                if (isset($columns[$i], $columnSchemas[$columns[$i]])) {
                    $value = $columnSchemas[$columns[$i]]->dbTypecast($value);
                }
                if (is_string($value)) {
                    $value = $schema->quoteValue($value);
                } elseif (is_float($value)) {
                    // ensure type cast always has . as decimal separator in all locales
                    $value = StringHelper::floatToString($value);
                } elseif ($value === true) {
                    $value = 'TRUE';
                } elseif ($value === false) {
                    $value = 'FALSE';
                } elseif ($value === null) {
                    $value = 'NULL';
                } elseif ($value instanceof ExpressionInterface) {
                    $value = $this->buildExpression($value, $params);
                }
                $vs[] = $value;
            }
            $values[] = '(' . implode(', ', $vs) . ')';
        }
        if (empty($values)) {
            return '';
        }

        foreach ($columns as $i => $name) {
            $columns[$i] = $schema->quoteColumnName($name);
        }

        return 'INSERT INTO ' . $schema->quoteTableName($table)
            . ' (' . implode(', ', $columns) . ') VALUES ' . implode(', ', $values);
    }

    /**
     * [[upsert()]] implementation for PostgreSQL 9.5 or higher.
     * @param string $table
     * @param array|Query $insertColumns
     * @param array|bool $updateColumns
     * @param array $params
     * @return string
     */
    protected function newUpsert($table, $insertColumns, $updateColumns, &$params)
    {
        $insertSql = $this->insert($table, $insertColumns, $params);
        list($uniqueNames,, $updateNames) = $this->prepareUpsertColumns($table, $insertColumns, $updateColumns);
        if (empty($uniqueNames)) {
            return $insertSql;
        }

        if ($updateColumns === false) {
            return "$insertSql ON CONFLICT DO NOTHING";
        }

        if ($updateColumns === true) {
            $updateColumns = [];
            foreach ($updateNames as $name) {
                $updateColumns[$name] = new Expression('EXCLUDED.' . $this->db->quoteColumnName($name));
            }
        }
        list($updates, $params) = $this->prepareUpdateSets($table, $updateColumns, $params);
        return $insertSql . ' ON CONFLICT (' . implode(', ', $uniqueNames) . ') DO UPDATE SET ' . implode(', ', $updates);
    }

    /**
     * [[upsert()]] implementation for PostgreSQL older than 9.5.
     * @param string $table
     * @param array|Query $insertColumns
     * @param array|bool $updateColumns
     * @param array $params
     * @return string
     */
    protected function oldUpsert($table, $insertColumns, $updateColumns, &$params)
    {
        /** @var Constraint[] $constraints */
        list($uniqueNames, $insertNames, $updateNames) = $this->prepareUpsertColumns($table, $insertColumns, $updateColumns, $constraints);
        if (empty($uniqueNames)) {
            return $this->insert($table, $insertColumns, $params);
        }

        /** @var Schema $schema */
        $schema = $this->db->getSchema();
        if (!$insertColumns instanceof Query) {
            $tableSchema = $schema->getTableSchema($table);
            $columnSchemas = $tableSchema !== null ? $tableSchema->columns : [];
            foreach ($insertColumns as $name => $value) {
                // NULLs and numeric values must be type hinted in order to be used in SET assigments
                // NVM, let's cast them all
                if (isset($columnSchemas[$name])) {
                    $phName = self::PARAM_PREFIX . count($params);
                    $params[$phName] = $value;
                    $insertColumns[$name] = new Expression("CAST($phName AS {$columnSchemas[$name]->dbType})");
                }
            }
        }
        list(, $placeholders, $values, $params) = $this->prepareInsertValues($table, $insertColumns, $params);
        $updateCondition = ['or'];
        $insertCondition = ['or'];
        $quotedTableName = $schema->quoteTableName($table);
        foreach ($constraints as $constraint) {
            $constraintUpdateCondition = ['and'];
            $constraintInsertCondition = ['and'];
            foreach ($constraint->columnNames as $name) {
                $quotedName = $schema->quoteColumnName($name);
                $constraintUpdateCondition[] = "$quotedTableName.$quotedName=\"EXCLUDED\".$quotedName";
                $constraintInsertCondition[] = "\"upsert\".$quotedName=\"EXCLUDED\".$quotedName";
            }
            $updateCondition[] = $constraintUpdateCondition;
            $insertCondition[] = $constraintInsertCondition;
        }
        $withSql = 'WITH "EXCLUDED" (' . implode(', ', $insertNames)
            . ') AS (' . (!empty($placeholders) ? 'VALUES (' . implode(', ', $placeholders) . ')' : ltrim($values, ' ')) . ')';
        if ($updateColumns === false) {
            $selectSubQuery = (new Query())
                ->select(new Expression('1'))
                ->from($table)
                ->where($updateCondition);
            $insertSelectSubQuery = (new Query())
                ->select($insertNames)
                ->from('EXCLUDED')
                ->where(['not exists', $selectSubQuery]);
            $insertSql = $this->insert($table, $insertSelectSubQuery, $params);
            return "$withSql $insertSql";
        }

        if ($updateColumns === true) {
            $updateColumns = [];
            foreach ($updateNames as $name) {
                $quotedName = $this->db->quoteColumnName($name);
                if (strrpos($quotedName, '.') === false) {
                    $quotedName = '"EXCLUDED".' . $quotedName;
                }
                $updateColumns[$name] = new Expression($quotedName);
            }
        }
        list($updates, $params) = $this->prepareUpdateSets($table, $updateColumns, $params);
        $updateSql = 'UPDATE ' . $this->db->quoteTableName($table) . ' SET ' . implode(', ', $updates)
            . ' FROM "EXCLUDED" ' . $this->buildWhere($updateCondition, $params)
            . ' RETURNING ' . $this->db->quoteTableName($table) . '.*';
        $selectUpsertSubQuery = (new Query())
            ->select(new Expression('1'))
            ->from('upsert')
            ->where($insertCondition);
        $insertSelectSubQuery = (new Query())
            ->select($insertNames)
            ->from('EXCLUDED')
            ->where(['not exists', $selectUpsertSubQuery]);
        $insertSql = $this->insert($table, $insertSelectSubQuery, $params);
        return "$withSql, \"upsert\" AS ($updateSql) $insertSql";
    }

    /**
     * Normalizes data to be saved into the table, performing extra preparations and type converting, if necessary.
     *
     * @param string $table the table that data will be saved into.
     * @param array|Query $columns the column data (name => value) to be saved into the table or instance
     * of [[yii\db\Query|Query]] to perform INSERT INTO ... SELECT SQL statement.
     * Passing of [[Reaction\Db\Query|Query]] is available
     * @return array normalized columns
     */
    protected function normalizeTableRowData($table, $columns)
    {
        //TODO: Make some actions for BLOB fields
        if ($columns instanceof Query) {
            return $columns;
        }

        /*if (($tableSchema = $this->db->getSchema()->getTableSchema($table)) !== null) {
            $columnSchemas = $tableSchema->columns;
            foreach ($columns as $name => $value) {
                if (isset($columnSchemas[$name]) && $columnSchemas[$name]->type === Schema::TYPE_BINARY && is_string($value)) {
                    $columns[$name] = new PdoValue($value, \PDO::PARAM_LOB); // explicitly setup PDO param type for binary column
                }
            }
        }*/

        return $columns;
    }

    /**
     * Get table primary key column(s)
     * @param string $table
     * @param bool   $asArray
     * @return array|mixed|null|string[]
     */
    protected function getTablePrimaryKey($table, $asArray = false) {
        $tableSchema = $this->db->getSchema()->getTableSchema($table);
        $primaryKeys = $tableSchema->primaryKey;
        if (empty($primaryKeys)) {
            return $asArray ? [] : null;
        }
        return $asArray ? $primaryKeys : reset($primaryKeys);
    }
}


<?php
/**
 * CloneModel class file.
 * @copyright (c) 2014, bariew
 * @license http://www.opensource.org/licenses/bsd-license.php
 */
namespace bariew\moduleModule\models;

use Yii;
use yii\base\Model;
use yii\helpers\FileHelper;

/**
 * This model is for cloning modules.
 * E.g. you have module installed in /vendor folder
 * and you want to extend its behavior with new module -
 * you can just clone it into @app/modules/yourNewModule folder.
 * All classes in your new module will be empty classes extending original ones
 * (you may place there your new content or not - it already works).
 *
 * @author Pavel Bariev <bariew@yandex.ru>
 */
class CloneModel extends Model
{
    /**
     * @var string yii2 path alias to original module folder.
     */
    public $source;

    /**
     * @var int whether to replace existing files while cloning.
     */
    public $replace = 0;

    public $inheritContent = 0;

    /**
     * @var array files not to change.
     */
    private $keepFiles = [];

    /**
     * @var string yii2 path alias to target module folder.
     */
    public $destination;

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['source', 'destination'], 'required'],
            ['source', 'in', 'range' => self::aliasList()],
            [['inheritContent', 'replace'], 'boolean'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'source'  => Yii::t('modules/module', 'Clone source'),
            'destination'   => Yii::t('modules/module', 'Clone destination'),
            'inheritContent'=> Yii::t('modules/module', 'Inherit parent php content'),
            'replace'       => Yii::t('modules/module', 'Replace existing files'),
        ];
    }

    /**
     * Gets module cloning done.
     * @return boolean
     */
    public function run()
    {
        return $this->copy() && $this->replace() ;

    }

    /**
     * System path aliases list.
     * @return array available alias list.
     */
    public static function aliasList()
    {
        $result = [];
        foreach (\Yii::$aliases as $alias => $data) {
            if (is_array($data)) {
                $result = array_merge($result, array_keys($data));
            } else {
                $result[] = $alias;
            }
        }
        asort($result);
        return array_values($result);
    }

    /**
     * Searches all path aliases.
     * @param string $query search string started with @
     * @return array found system path aliases matching search query.
     */
    public static function findAliases($query)
    {
        $query = '@' . str_replace('@', '', $query);
        $pattern = '/' . preg_quote($query, '/') . '/';
        return preg_grep($pattern, self::aliasList());
    }

    /**
     * Copies original module files to destination folder.
     * @return boolean
     */
    private function copy()
    {
        $source = Yii::getAlias($this->source);
        if (!file_exists($source) || !is_dir($source)) {
            $this->addError('source', Yii::t('modules/module', 'Source directory not found'));
            return false;
        }
        $destination = Yii::getAlias($this->destination);
        if (!$this->replace && is_dir($destination)) { // if replace is disabled we will skip existing files
            $this->keepFiles = FileHelper::findFiles($destination);
        }
        FileHelper::copyDirectory($source, $destination, [
            'except' => ['.git/'],
            'fileMode' => 0775,
            'beforeCopy' => function ($from, $to) {
                return $this->replace || !file_exists($to) || !is_file($to);
            }
        ]);
        return true;
    }

    /**
     * Replaces all new module classes content with empty template.
     * @return boolean
     */
    private function replace()
    {
        $destination = Yii::getAlias($this->destination);
        $destinationModuleName = $this->getDestinationModuleName();
        foreach (FileHelper::findFiles($destination) as $path) {
            if (!$this->replace && in_array($path, $this->keepFiles)) {
                continue;
            }
            if (!preg_match('/^.*\.php$/', $path, $matches)) { // php file.
                continue;
            } else if (preg_match('/^.*\W([A-Z]\w+)\.php$/', $path, $matches)) { // Class file.
                file_put_contents($path, $this->createClassContent($matches[1], $path));
            } else if (self::isMigration($path)) { // Class file.
                file_put_contents($path, $this->updateFileContent($path));
                if ($destinationModuleName) {
                    $this->renameClassFile($path, function($className) use ($destinationModuleName){
                        return $className . '_' . $destinationModuleName;
                    });
                }
            } else if ($this->inheritContent) {
                file_put_contents($path, $this->createFileContent($path));
            } else {
                file_put_contents($path, $this->updateFileContent($path));
            }
        }
        return true;
    }

    protected function createClassContent($className, $path)
    {
        $destination = Yii::getAlias($this->destination);
        $template = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR .
            'templates' . DIRECTORY_SEPARATOR . 'class_clone_template');
        $addedNamespace = str_replace(
            [$destination, DIRECTORY_SEPARATOR . $className .'.php', '/'],
            ['', '', '\\'],
            $path
        );
        $fileNamespace = $this->getNewNamespace() . $addedNamespace;
        $oldClassName = $this->getOldNamespace() . $addedNamespace . '\\' . $className;
        return  "<?php " . str_replace(
            ['$namespace', '$class', '$oldClass'],
            [$fileNamespace, $className, $oldClassName],
            $template
        );
    }

    private function createFileContent($path)
    {
        $template = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR .
            'templates' .DIRECTORY_SEPARATOR . 'file_clone_template');
        $pathEnd = str_replace(Yii::getAlias($this->destination), '', $path);
        $oldFile = $this->source . str_replace('\\', '/', $pathEnd);
        return  "<?php " . str_replace('$oldFile', $oldFile, $template);
    }

    protected function updateFileContent($path)
    {
        return str_replace(
            $this->getOldNamespace(),
            $this->getNewNamespace(),
            file_get_contents($path)
        );
    }

    private function getNewNamespace()
    {
        return str_replace(['@', '/'], ['', '\\'], $this->destination);
    }

    private function getOldNamespace()
    {
        return str_replace(['@', '/'], ['', '\\'], $this->source);
    }

    private function getDestinationModuleName()
    {
        return preg_match('/.*\/modules\/(.*\/)?([-\w]+)$/', $this->destination, $matches)
            ? $matches[2] : null;
    }

    /**
     * @param $path
     * @return boolean
     */
    private static function isMigration($path)
    {
        $migrationPath = preg_quote(DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR, '/');
        return preg_match('/^.*'.$migrationPath.'\w+\.php$/', $path);
    }

    private function renameClassFile($path, $callback)
    {
        $pathArray = explode(DIRECTORY_SEPARATOR, $path);
        $fileName = array_pop($pathArray);
        $className = str_replace('.php', '', $fileName);
        $newClassName = call_user_func($callback, $className);
        array_push($pathArray, str_replace($className, $newClassName, $fileName)); //new filename
        $newPath = implode(DIRECTORY_SEPARATOR, $pathArray);
        if (!$this->replace && file_exists($newPath)) {
            return unlink($path);
        }
        file_put_contents($path, str_replace(
            "class $className",
            "class $newClassName",
            file_get_contents($path)
        ));
        rename($path, $newPath);
    }
}


<?php
/**
 * Socket wrapper class used by Socket Adapter
 *
 * PHP version 5
 *
 * LICENSE
 *
 * This source file is subject to BSD 3-Clause License that is bundled
 * with this package in the file LICENSE and available at the URL
 * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
 *
 * @category  HTTP
 * @package   HTTP_Request2
 * @author    Alexey Borzov <avb@php.net>
 * @copyright 2008-2014 Alexey Borzov <avb@php.net>
 * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
 * @link      http://pear.php.net/package/HTTP_Request2
 */

/** Exception classes for HTTP_Request2 package */
require_once 'HTTP/Request2/Exception.php';

/**
 * Socket wrapper class used by Socket Adapter
 *
 * Needed to properly handle connection errors, global timeout support and
 * similar things. Loosely based on Net_Socket used by older HTTP_Request.
 *
 * @category HTTP
 * @package  HTTP_Request2
 * @author   Alexey Borzov <avb@php.net>
 * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
 * @version  Release: 2.2.1
 * @link     http://pear.php.net/package/HTTP_Request2
 * @link     http://pear.php.net/bugs/bug.php?id=19332
 * @link     http://tools.ietf.org/html/rfc1928
 */
class HTTP_Request2_SocketWrapper
{
    /**
     * PHP warning messages raised during stream_socket_client() call
     * @var array
     */
    protected $connectionWarnings = array();

    /**
     * Connected socket
     * @var resource
     */
    protected $socket;

    /**
     * Sum of start time and global timeout, exception will be thrown if request continues past this time
     * @var  integer
     */
    protected $deadline;

    /**
     * Global timeout value, mostly for exception messages
     * @var integer
     */
    protected $timeout;

    /**
     * Class constructor, tries to establish connection
     *
     * @param string $address        Address for stream_socket_client() call,
     *                               e.g. 'tcp://localhost:80'
     * @param int    $timeout        Connection timeout (seconds)
     * @param array  $contextOptions Context options
     *
     * @throws HTTP_Request2_LogicException
     * @throws HTTP_Request2_ConnectionException
     */
    public function __construct($address, $timeout, array $contextOptions = array())
    {
        if (!empty($contextOptions)
            && !isset($contextOptions['socket']) && !isset($contextOptions['ssl'])
        ) {
            // Backwards compatibility with 2.1.0 and 2.1.1 releases
            $contextOptions = array('ssl' => $contextOptions);
        }
        $context = stream_context_create();
        foreach ($contextOptions as $wrapper => $options) {
            foreach ($options as $name => $value) {
                if (!stream_context_set_option($context, $wrapper, $name, $value)) {
                    throw new HTTP_Request2_LogicException(
                        "Error setting '{$wrapper}' wrapper context option '{$name}'"
                    );
                }
            }
        }
        set_error_handler(array($this, 'connectionWarningsHandler'));
        $this->socket = stream_socket_client(
            $address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context
        );
        restore_error_handler();
        // if we fail to bind to a specified local address (see request #19515),
        // connection still succeeds, albeit with a warning. Throw an Exception
        // with the warning text in this case as that connection is unlikely
        // to be what user wants and as Curl throws an error in similar case.
        if ($this->connectionWarnings) {
            if ($this->socket) {
                fclose($this->socket);
            }
            $error = $errstr ? $errstr : implode("\n", $this->connectionWarnings);
            throw new HTTP_Request2_ConnectionException(
                "Unable to connect to {$address}. Error: {$error}", 0, $errno
            );
        }
    }

    /**
     * Destructor, disconnects socket
     */
    public function __destruct()
    {
        fclose($this->socket);
    }

    /**
     * Wrapper around fread(), handles global request timeout
     *
     * @param int $length Reads up to this number of bytes
     *
     * @return   string Data read from socket
     * @throws   HTTP_Request2_MessageException     In case of timeout
     */
    public function read($length)
    {
        if ($this->deadline) {
            stream_set_timeout($this->socket, max($this->deadline - time(), 1));
        }
        $data = fread($this->socket, $length);
        $this->checkTimeout();
        return $data;
    }

    /**
     * Reads until either the end of the socket or a newline, whichever comes first
     *
     * Strips the trailing newline from the returned data, handles global
     * request timeout. Method idea borrowed from Net_Socket PEAR package.
     *
     * @param int $bufferSize   buffer size to use for reading
     * @param int $localTimeout timeout value to use just for this call
     *                          (used when waiting for "100 Continue" response)
     *
     * @return   string Available data up to the newline (not including newline)
     * @throws   HTTP_Request2_MessageException     In case of timeout
     */
    public function readLine($bufferSize, $localTimeout = null)
    {
        $line = '';
        while (!feof($this->socket)) {
            if (null !== $localTimeout) {
                stream_set_timeout($this->socket, $localTimeout);
            } elseif ($this->deadline) {
                stream_set_timeout($this->socket, max($this->deadline - time(), 1));
            }

            $line .= @fgets($this->socket, $bufferSize);

            if (null === $localTimeout) {
                $this->checkTimeout();

            } else {
                $info = stream_get_meta_data($this->socket);
                // reset socket timeout if we don't have request timeout specified,
                // prevents further calls failing with a bogus Exception
                if (!$this->deadline) {
                    $default = (int)@ini_get('default_socket_timeout');
                    stream_set_timeout($this->socket, $default > 0 ? $default : PHP_INT_MAX);
                }
                if ($info['timed_out']) {
                    throw new HTTP_Request2_MessageException(
                        "readLine() call timed out", HTTP_Request2_Exception::TIMEOUT
                    );
                }
            }
            if (substr($line, -1) == "\n") {
                return rtrim($line, "\r\n");
            }
        }
        return $line;
    }

    /**
     * Wrapper around fwrite(), handles global request timeout
     *
     * @param string $data String to be written
     *
     * @return int
     * @throws HTTP_Request2_MessageException
     */
    public function write($data)
    {
        if ($this->deadline) {
            stream_set_timeout($this->socket, max($this->deadline - time(), 1));
        }
        $written = fwrite($this->socket, $data);
        $this->checkTimeout();
        // http://www.php.net/manual/en/function.fwrite.php#96951
        if ($written < strlen($data)) {
            throw new HTTP_Request2_MessageException('Error writing request');
        }
        return $written;
    }

    /**
     * Tests for end-of-file on a socket
     *
     * @return bool
     */
    public function eof()
    {
        return feof($this->socket);
    }

    /**
     * Sets request deadline
     *
     * @param int $deadline Exception will be thrown if request continues
     *                      past this time
     * @param int $timeout  Original request timeout value, to use in
     *                      Exception message
     */
    public function setDeadline($deadline, $timeout)
    {
        $this->deadline = $deadline;
        $this->timeout  = $timeout;
    }

    /**
     * Turns on encryption on a socket
     *
     * @throws HTTP_Request2_ConnectionException
     */
    public function enableCrypto()
    {
        $modes = array(
            STREAM_CRYPTO_METHOD_TLS_CLIENT,
            STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
            STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
            STREAM_CRYPTO_METHOD_SSLv2_CLIENT
        );

        foreach ($modes as $mode) {
            if (stream_socket_enable_crypto($this->socket, true, $mode)) {
                return;
            }
        }
        throw new HTTP_Request2_ConnectionException(
            'Failed to enable secure connection when connecting through proxy'
        );
    }

    /**
     * Throws an Exception if stream timed out
     *
     * @throws HTTP_Request2_MessageException
     */
    protected function checkTimeout()
    {
        $info = stream_get_meta_data($this->socket);
        if ($info['timed_out'] || $this->deadline && time() > $this->deadline) {
            $reason = $this->deadline
                ? "after {$this->timeout} second(s)"
                : 'due to default_socket_timeout php.ini setting';
            throw new HTTP_Request2_MessageException(
                "Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT
            );
        }
    }

    /**
     * Error handler to use during stream_socket_client() call
     *
     * One stream_socket_client() call may produce *multiple* PHP warnings
     * (especially OpenSSL-related), we keep them in an array to later use for
     * the message of HTTP_Request2_ConnectionException
     *
     * @param int    $errno  error level
     * @param string $errstr error message
     *
     * @return bool
     */
    protected function connectionWarningsHandler($errno, $errstr)
    {
        if ($errno & E_WARNING) {
            array_unshift($this->connectionWarnings, $errstr);
        }
        return true;
    }
}
?>


<?php
namespace Sab\Application\Bridge;

use Bridge\Application\ApplicationBridge;
use Bridge\Application\RouteInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\App;

/**
 * Bridge between a SlimApplication and a Standard Application defined in ApplicationBrdige
 */
class SlimBridge extends ApplicationBridge {
    private $app;

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

    /**
     * Register a new route with the given verbs.
     *
     * @param  string  $methods
     * @param  string  $uri
     * @param  \Closure|array|string  $action
     * @return void
     */

    public function addRoute(RouteInterface $route) {
        if (!$route->isValid()) {
            //perhaps some log?
            return;
        }

        $routeValue = $route->getAction()->getValue();
        $this->app->map(
            [strtolower($route->getMethod()->getValue())],
            $route->getUri()->getValue(),
            function (
                RequestInterface $request,
                ResponseInterface $response,
                $params
            ) use ($routeValue) {
                $handler = $this->get($routeValue);
                return $handler->execute($request, $response, $params);
            }
        );
    }
}


<?php

namespace Reaction\Rbac\Migrations;

use Reaction;
use Reaction\Db\ConnectionInterface;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Rbac\DbManager;
use Reaction\Db\Migration;

/**
 * Adds index on `user_id` column in `auth_assignment` table for performance reasons.
 *
 * @see https://github.com/yiisoft/yii2/pull/14765
 */
class m170907_052038_rbac_add_index_on_auth_assignment_user_id extends Migration
{
    public $column = 'user_id';
    public $index = 'auth_assignment_user_id_idx';

    /**
     * @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;
    }

    /**
     * {@inheritdoc}
     */
    public function safeUp(ConnectionInterface $connection)
    {
        $authManager = $this->getAuthManager();
        return $this->createIndex($this->index, $authManager->assignmentTable, $this->column);
    }

    /**
     * {@inheritdoc}
     */
    public function safeDown(ConnectionInterface $connection)
    {
        $authManager = $this->getAuthManager();
        return $this->dropIndex($this->index, $authManager->assignmentTable);
    }
}


<?php namespace Arcanedev\NoCaptcha\Utilities;

use Arcanedev\NoCaptcha\Contracts\Utilities\AttributesInterface;
use Arcanedev\NoCaptcha\Exceptions\InvalidArgumentException;
use Arcanedev\NoCaptcha\NoCaptcha;

/**
 * Class     Attributes
 *
 * @package  Arcanedev\NoCaptcha\Utilities
 * @author   ARCANEDEV <arcanedev.maroc@gmail.com>
 */
class Attributes implements AttributesInterface
{
    /* ------------------------------------------------------------------------------------------------
     |  Properties
     | ------------------------------------------------------------------------------------------------
     */
    /**
     * Attribute collection.
     *
     * @var array
     */
    protected $items    = [];

    /**
     * Defaults attributes.
     *
     * @var array
     */
    protected $defaults = [];

    /* ------------------------------------------------------------------------------------------------
     |  Constructor
     | ------------------------------------------------------------------------------------------------
     */
    /**
     * Attributes constructor.
     *
     * @param  array  $defaults
     */
    public function __construct(array $defaults = [])
    {
        $this->defaults = array_filter($defaults);
    }

    /* ------------------------------------------------------------------------------------------------
     |  Getters & Setters
     | ------------------------------------------------------------------------------------------------
     */
    /**
     * Get all items.
     *
     * @param  string  $siteKey
     *
     * @return array
     */
    protected function getItems($siteKey)
    {
        return array_merge(
            $this->getDefaultAttributes($siteKey),
            $this->items
        );
    }

    /**
     * Get Default attributes.
     *
     * @param  string  $siteKey
     *
     * @return array
     */
    private function getDefaultAttributes($siteKey)
    {
        return [
            'class'        => 'g-recaptcha',
            'data-sitekey' => $siteKey,
        ];
    }

    /**
     * Set items.
     *
     * @param  array  $items
     *
     * @return self
     */
    private function setItems(array $items)
    {
        $this->items = array_merge($this->defaults, $items);

        $this->checkAttributes();

        return $this;
    }

    /**
     * Get an item value by name.
     *
     * @param  string  $name
     *
     * @return string
     */
    private function getItem($name)
    {
        if ( ! $this->hasItem($name)) {
            return null;
        }

        return $this->items[$name];
    }

    /**
     * Set an item.
     *
     * @param  string  $name
     * @param  string  $value
     *
     * @return self
     */
    private function setItem($name, $value)
    {
        $this->items[$name] = $value;

        return $this;
    }

    /**
     * Get image type attribute.
     *
     * @return array
     */
    public function getImageAttribute()
    {
        return [self::ATTR_TYPE => 'image'];
    }

    /**
     * Get audio type attribute.
     *
     * @return array
     */
    public function getAudioAttribute()
    {
        return [self::ATTR_TYPE => 'audio'];
    }

    /* ------------------------------------------------------------------------------------------------
     |  Main functions
     | ------------------------------------------------------------------------------------------------
     */
    /**
     * Build attributes.
     *
     * @param  string  $siteKey
     * @param  array   $items
     *
     * @return string
     */
    public function build($siteKey, array $items = [])
    {
        $this->setItems($items);

        $output = [];

        foreach ($this->getItems($siteKey) as $key => $value) {
            $output[] = trim($key) . '="' . trim($value) . '"';
        }

        return implode(' ', $output);
    }

    /**
     * Prepare the name and id attributes.
     *
     * @param  string|null  $name
     *
     * @return array
     *
     * @throws \Arcanedev\NoCaptcha\Exceptions\InvalidArgumentException
     */
    public function prepareNameAttribute($name)
    {
        if (is_null($name)) return [];

        if ($name === NoCaptcha::CAPTCHA_NAME) {
            throw new InvalidArgumentException(
                'The captcha name must be different from "' . NoCaptcha::CAPTCHA_NAME . '".'
            );
        }

        return array_combine(['id', 'name'], [$name, $name]);
    }

    /* ------------------------------------------------------------------------------------------------
     |  Check functions
     | ------------------------------------------------------------------------------------------------
     */
    /**
     * Check attributes.
     */
    private function checkAttributes()
    {
        $this->checkTypeAttribute();
        $this->checkThemeAttribute();
        $this->checkSizeAttribute();
    }

    /**
     * Check type attribute.
     */
    private function checkTypeAttribute()
    {
        $this->checkDataAttribute(self::ATTR_TYPE, 'image', ['image', 'audio']);
    }

    /**
     * Check theme attribute.
     */
    private function checkThemeAttribute()
    {
        $this->checkDataAttribute(self::ATTR_THEME, 'light', ['light', 'dark']);
    }

    /**
     * Check size attribute.
     */
    private function checkSizeAttribute()
    {
        $this->checkDataAttribute(self::ATTR_SIZE, 'normal', ['normal', 'compact']);
    }

    /**
     * Check data Attribute.
     *
     * @param  string  $name
     * @param  string  $default
     * @param  array   $available
     */
    private function checkDataAttribute($name, $default, array $available)
    {
        $item = $this->getItem($name);

        if ( ! is_null($item)) {
            $item = (is_string($item) and in_array($item, $available))
                ? strtolower(trim($item))
                : $default;

            $this->setItem($name, $item);
        }
    }

    /**
     * Check if has an item.
     *
     * @param  string  $name
     *
     * @return bool
     */
    private function hasItem($name)
    {
        return array_key_exists($name, $this->items);
    }
}


<?php

namespace ROH\Util;

use ReflectionClass;
use Exception;

class Injector
{
    /**
     * Singleton instance
     *
     * @var Injector
     */
    protected static $instance;

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

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

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

    /**
     * Get singleton instance
     *
     * @return Injector
     */
    public static function getInstance()
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }

        return static::$instance;
    }

    public function __construct()
    {
        $this->singleton(static::class, $this);
    }

    /**
     * Resolve contract
     *
     * @param mixed $contract
     * @param array $args
     * @return mixed
     */
    public function resolve($contract, array $args = [])
    {
        // return contract if contract is signature of function
        if (is_callable($contract)) {
            return $contract;
        } elseif (is_string($contract)) {
            return $this->resolveClass($contract, $args);
        } elseif (is_array($contract) && isset($contract[0])) {
            $realContract = $contract[0];
            $realArgs = (new Options(isset($contract[1]) ? $contract[1] : []))
                ->merge($args)
                ->toArray();

            return $this->resolveClass($realContract, $realArgs);
        } else {
            return $contract;
        }
    }

    protected function resolveClass($contract, array $args = [])
    {
        $contract = $this->resolveAlias($contract);

        if (isset($this->singletons[$contract])) {
            return $this->singletons[$contract];
        } elseif (isset($this->delegators[$contract])) {
            $delegator = $this->delegators[$contract];
            return $delegator($args);
        }

        $refClass = new ReflectionClass($contract);
        if (!$refClass->isInstantiable()) {
            throw new InjectorException('Injector cannot resolve contract, ' . $contract . ' is not instantiable');
        }

        $argAsParams = [];

        $constructor = $refClass->getConstructor();
        if (null !== $constructor) {
            $parameters = $constructor->getParameters();
            foreach ($parameters as $index => $parameter) {
                $name = $parameter->getName();
                $atName = '@' . $name;
                $class = $parameter->getClass();
                $isOptional = $parameter->isOptional();
                $argAsParamSet = false;
                $lastError = null;

                if (isset($args[$name]) || array_key_exists($name, $args)) {
                    $argAsParam = $args[$name];
                    $argAsParamSet = true;
                } elseif (isset($args[$atName]) && ($className = $args[$atName])) {
                    $argAsParam = $this->resolveClass($className);
                    $argAsParamSet = true;
                } elseif (isset($class)) {
                    $argContract = $this->resolveAlias($class->getName());
                    if (isset($this->singletons[$argContract])) {
                        $argAsParam = $this->singletons[$argContract];
                        $argAsParamSet = true;
                    } elseif (isset($this->delegators[$argContract])) {
                        $delegator = $this->delegators[$argContract];
                        $argAsParam = $delegator($args);
                        $argAsParamSet = true;
                    } elseif ($isOptional) {
                        break;
                    } else {
                        try {
                            $argAsParam = $this->resolveClass($argContract);
                            $argAsParamSet = true;
                        } catch (InjectorException $e) {
                            $lastError = $e;
                        }
                    }
                } elseif ($isOptional) {
                    break;
                }

                if (!$argAsParamSet) {
                    throw $lastError ?: new InjectorException('Unresolved parameter #' . $index . ' ($' . $name . ') of ' . $contract);
                } else {
                    $argAsParams[] = $argAsParam;
                }
            }
        }

        return $refClass->newInstanceArgs($argAsParams);
    }

    protected function resolveAlias($contract)
    {
        if (isset($this->aliases[$contract])) {
            return $this->resolveAlias($this->aliases[$contract]);
        } else {
            return $contract;
        }
    }

    /**
     * Add singleton
     *
     * @param string  $contract
     * @param mixed $value
     * @return Injector
     */
    public function singleton(string $contract, $value)
    {
        $this->singletons[$contract] = $value;
        return $this;
    }

    /**
     * Delegate to delegator factory function
     *
     * @param string $contract
     * @param callable $delegator
     * @return Injector
     */
    public function delegate(string $contract, $delegator)
    {
        $this->delegators[$contract] = $delegator;
        return $this;
    }

    /**
     * Alias contract as other object
     *
     * @param string $contract
     * @param mixed $alias
     * @return Injector
     */
    public function alias(string $contract, $alias)
    {
        $this->aliases[$contract] = $alias;
        return $this;
    }

    public function __debugInfo()
    {
        return [
            'singletons' => array_keys($this->singletons),
            'delegators' => array_keys($this->delegators),
            'aliases' => $this->aliases,
        ];
    }
}


<?php

/**
* Jin Framework
* Diatem
*/

namespace Jin2\Form\Components;

/**
 * Composant <select multiple>
 */
class SelectMultiple extends AbstractComponent
{

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

  /**
   * @var array  Valeurs sélectionnées. (Tableau de la forme array('value',...))
   */
  protected $selectedValues = array();

  /**
   * @var array Attributs ajoutés sur select
   */
  protected $selectattributes = array();

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

  /**
  * Rendu du composant
  * @return string
  */
  public function render()
  {
    $optionHtml = static::getAssetContent('option');

    $addContent = '';
    foreach ($this->values as $k => $option) {
      $ac = $optionHtml;
      $attributes = '';
      if (count($option['attributes']) > 0) {
        foreach ($option['attributes'] as $att_k => $att_v) {
          $attributes .= ' '.$att_k.'="'.$att_v.'"';
        }
      }
      $ac = str_replace('%value%', $option['value'], $ac);
      $ac = str_replace('%attributes%', $attributes, $ac);
      $ac = str_replace('%label%', $k, $ac);

      $selected = false;
      if (array_search($option['value'], $this->selectedValues) !== false) {
        $selected = true;
      }

      if ($selected) {
        $ac = str_replace('%selected%', 'selected="selected"', $ac);
      } else {
        $ac = str_replace('%selected%', '', $ac);
      }

      $addContent .= $ac;
    }

    $html = parent::render();
    $strAttributes = '';
    foreach ($this->selectattributes as $key => $value) {
      $strAttributes .= ' ' . $key . '="' . $value . '"';
    }
    $html = str_replace('%selectattributes%', $strAttributes, $html);
    $html = str_replace('%items%', $addContent, $html);

    return $html;
  }

  /**
   * Ajoute un nouvel attribut sur le select
   *
   * @param  string $attributeName   Nom de l'attribut
   * @param  string $attributeValue  Value de l'attribut
   * @return boolean                 Retourne FALSE si cet atribut était déjà ajouté
   */
  public function addSelectAttribute($attributeName, $attributeValue)
  {
    if (!array_key_exists($attributeName, $this->selectattributes)) {
      $this->selectattributes[$attributeName] = $attributeValue;
      return true;
    }
    return false;
  }

  /**
   * Supprime un attribut ajouté sur le select
   *
   * @param string $attributeName Nom de l'attribut
   * @return boolean              Retourne FALSE si cet attribut n'était pas ajouté
   */
  public function removeSelectAttribute($attributeName)
  {
    if (isset($this->selectattributes[$attributeName])) {
      unset($this->selectattributes[$attributeName]);
      return true;
    }
    return false;
  }

  /**
   * Retourne un tableau des attributs ajoutés
   *
   * @return array
   */
  public function getSelectAttributes()
  {
    return $this->selectattributes;
  }

  /**
   * Ajoute un choix dans la liste
   *
   * @param string $value      Valeur du choix
   * @param string $label      Label affiché
   * @param array  $attributes Attributs supplémentaires pour l'option
   */
  public function addValue($value, $label, $attributes = array())
  {
    $this->values[$label] = array(
      'value'      => $value,
      'attributes' => $attributes
    );
  }

  /**
   * Définit les valeurs du SelectMultiple
   *
   * @param array $values Tableau de valeurs (clé/valeur) ex. array('label'=>'val','label','val');
   */
  public function setValues($values)
  {
    if (count($values) > 0) {
      foreach ($values as $label => $value) {
        $this->addValue($value, $label);
      }
    }
  }

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

}


<?php

namespace Orbt\StyleMirror\Resource;

use Orbt\ResourceMirror\Resource\Collection;

/**
 * Queue for resources to be collected once.
 */
class SingleUseQueue
{
    protected $queue;
    protected $added;

    public function __construct()
    {
        $this->queue = new Collection();
        $this->added = array();
    }

    /**
     * Adds a resource to the queue.
     *
     * @param \Orbt\ResourceMirror\Resource\Resource $resource
     */
    public function add($resource)
    {
        if (!isset($this->added[$path = $resource->getPath()])) {
            $this->queue->add($resource);
            $this->added[$path] = true;
        }
    }

    /**
     * Returns and empties the current queue.
     */
    public function flush()
    {
        $queue = $this->queue;
        $this->queue = new Collection();
        return $queue;
    }
}


<?php

declare(strict_types = 1);

namespace Speicher210\BusinessHours\Day;

use Speicher210\BusinessHours\Day\Time\Time;
use Speicher210\BusinessHours\Day\Time\TimeBuilder;
use Speicher210\BusinessHours\Day\Time\TimeInterval;
use Speicher210\BusinessHours\Day\Time\TimeIntervalInterface;

/**
 * Build a DayInterface concrete implementation.
 */
final class DayBuilder
{
    /**
     * Create a new Day.
     *
     * @param integer $dayOfWeek The day of week.
     * @param array $openingIntervals The opening intervals.
     * @return Day
     */
    public static function fromArray($dayOfWeek, array $openingIntervals): Day
    {
        $intervals = [];
        foreach ($openingIntervals as $interval) {
            if ($interval instanceof TimeIntervalInterface) {
                $intervals[] = $interval;
            } elseif (\is_array($intervals)) {
                $intervals[] = new TimeInterval(
                    TimeBuilder::fromString($interval[0]),
                    TimeBuilder::fromString($interval[1])
                );
            }
        }

        $day = new Day($dayOfWeek, $intervals);
        $dayIntervals = $day->getOpeningHoursIntervals();
        /** @var TimeIntervalInterface $dayInterval */
        $dayInterval = \reset($dayIntervals);
        if (self::isIntervalAllDay($dayInterval->getStart(), $dayInterval->getEnd())) {
            return new AllDay($dayOfWeek);
        }

        return $day;
    }

    /**
     * Create a DayInterface object from an array.
     *
     * @param array $data The day data.
     * @return DayInterface
     */
    public static function fromAssociativeArray(array $data): DayInterface
    {
        if (!isset($data['openingIntervals'], $data['dayOfWeek']) || !\is_array($data['openingIntervals'])) {
            throw new \InvalidArgumentException('Array is not valid.');
        }

        $openingIntervals = [];
        foreach ($data['openingIntervals'] as $openingInterval) {
            if (!isset($openingInterval['start'], $openingInterval['end'])) {
                throw new \InvalidArgumentException('Array is not valid.');
            }
            $start = TimeBuilder::fromArray($openingInterval['start']);
            $end = TimeBuilder::fromArray($openingInterval['end']);
            if (self::isIntervalAllDay($start, $end)) {
                return new AllDay($data['dayOfWeek']);
            }

            $openingIntervals[] = new TimeInterval($start, $end);
        }

        return new Day($data['dayOfWeek'], $openingIntervals);
    }

    /**
     * Check if an interval array is all day.
     *
     * @param Time $start The start time.
     * @param Time $end The end time.
     * @return boolean
     */
    private static function isIntervalAllDay(Time $start, Time $end): bool
    {
        if ($start->getHours() !== 0 || $start->getMinutes() !== 0 || $start->getSeconds() !== 0) {
            return false;
        }

        if ($end->getHours() !== 24 || $end->getMinutes() !== 0 || $end->getSeconds() !== 0) {
            return false;
        }

        return true;
    }
}


<?php

/*
 * This file is part of the Crowdin library.
 *
 * (c) Julien Janvier
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Jjanvier\Library\Crowdin\Formatter;

use \SplFileInfo;

class YamlFormatter implements FormatterInterface
{
    /**
     * {@inheritdoc}
     */
    public function clean(SplFileInfo $file)
    {
        $array = file($file->getRealPath());

        if (count($array)) {
            // Crowdin adds --- on the beginning of every Yaml during the export.
            if (1 === preg_match("/^---/", $array[0])) {
                unset($array[0]);
            }

            file_put_contents($file->getRealPath(), $array);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function addHeader(SplFileInfo $file, $header)
    {
        $content = file_get_contents($file->getRealPath());
        $content = $header.$content;
        file_put_contents($file->getRealPath(), $content);
    }
}


<?php
/*
 * This file is part of the Skeetr package.
 *
 * (c) Máximo Cuadros <mcuadros@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Skeetr\Client\HTTP;

use http\Message;
use http\Cookie;
use UnexpectedValueException;

class Request extends Message
{
    private $rpcMethod;
    private $timestamp;
    private $url;
    private $method;
    private $version;
    private $post = array();
    private $get = array();
    private $server = array();
    private $remote = array();
    private $cookies = array();

    public function __construct()
    {
        parent::__construct();
        $this->setType(Message::TYPE_REQUEST);
    }

    /**
     * Configure the request based on a JSON, usually received on the workload
     * from a GearmanJob from the nginx.
     *
     * @param  string  $json
     * @return boolean
     */
    public static function fromArray(Array $data)
    {
        $request = new static();

        if (!isset($data['body']) || !isset($data['request'])) {
            throw new UnexpectedValueException(
                'Unexpected data, invalid data'
            );
        }

        $body = $data['body'];
        $params = $data['request'];

        $request->setTimestamp(microtime(true));

        if (isset($params['RequestURI'])) {
            $request->setRequestUrl($params['RequestURI']);
        }

        if (isset($params['Method'])) {
            $request->setRequestMethod($params['Method']);
        }

        if (isset($params['Header']) && is_array($params['Header'])) {
            $headers = $params['Header'];

            if (isset($params['Host'])) {
                $headers['Host'] = [$params['Host']];
            }

            $request->setHeaders($headers);

            //Malformed cookies will return a fatal error
            $cookies = $cookies = new Cookie($request->getHeader('Cookie'));
            if ($cookies) {
                $request->setCookies($cookies);
            }
        }

        if (isset($params['URL']['RawQuery'])) {
            parse_str($params['URL']['RawQuery'], $queryFields);
            $request->setQueryFields($queryFields);
        }

        if (isset($params['Host']) && isset($params['Proto'])) {
            $info = parse_url($params['Host']);
            $info['proto'] = $params['Proto'];

            $request->setServerInfo($info);
        }

        if (isset($params['RemoteAddr'])) {
            $info = parse_url($params['RemoteAddr']);
            $request->setRemoteInfo($info);
        }

        if (strlen($body)) {
            parse_str($body, $postFields);
            $request->setPostFields($postFields);
        }

        return $request;
    }

    /**
     * Sets the remote client info
     *
     * @param float $timestamp microtimestamp
     */
    public function setTimestamp($timestamp)
    {
        $this->timestamp = $timestamp;
        $this->setServerGlobal('REQUEST_TIME', (int) $timestamp);
        $this->setServerGlobal('REQUEST_TIME_FLOAT', $timestamp);
    }

    /**
     * Sets the remote client info
     *
     * @param string $info mandatory keys: addr and port
     */
    public function setRemoteInfo(array $info)
    {
        $this->remote = $info;
        $this->setServerGlobal('REMOTE_ADDR', (string) $info['host']);
        $this->setServerGlobal('REMOTE_PORT', (string) $info['port']);
    }

    /**
     * Sets the server info
     *
     * @param string $info mandatory keys: name, addr, port and proto
     */
    public function setServerInfo(array $info)
    {
        $this->server = $info;

        if (isset($info['name']) && $info['name']) $name = (string) $info['name'];
        else $name = sprintf('%s:%s', $info['host'], $info['port']);

        $this->setServerGlobal('SERVER_NAME', $name);

        $this->setServerGlobal('SERVER_ADDR', (string) $info['host']);
        $this->setServerGlobal('SERVER_PORT', (string) $info['port']);
        $this->setServerGlobal('SERVER_PROTOCOL', (string) $info['proto']);

        //TODO: Version Server
        $this->setServerGlobal('SERVER_SOFTWARE', 'Skeetr/0.0.2');
    }

    /**
     * Sets the headers.
     *
     * @param array $headers associative array containing the new HTTP headers
     */
    public function setHeaders(array $headers)
    {
        parent::addHeaders($headers);

        $this->setServerGlobal('HTTP_HOST', (string) $this->getHeader('Host')[0]);
        $this->setServerGlobal('HTTP_ACCEPT', (string) $this->getHeader('Accept')[0]);
        $this->setServerGlobal('HTTP_CONNECTION', (string) $this->getHeader('Connection')[0]);
        $this->setServerGlobal('HTTP_USER_AGENT', (string) $this->getHeader('User-Agent')[0]);
        $this->setServerGlobal('HTTP_ACCEPT_ENCODING', (string) $this->getHeader('Accept-Encoding')[0]);
        $this->setServerGlobal('HTTP_ACCEPT_LANGUAGE', (string) $this->getHeader('Accept-Language')[0]);
        $this->setServerGlobal('HTTP_ACCEPT_CHARSET', (string) $this->getHeader('Accept-Charset')[0]);
        $this->setServerGlobal('HTTP_CACHE_CONTROL', (string) $this->getHeader('Cache-Control')[0]);
        $this->setServerGlobal('HTTP_COOKIE', (string) $this->getHeader('Cookie')[0]);
    }

    /**
     * Sets the method.
     *
     * @param string $method
     */
    public function setRequestMethod($method)
    {
        parent::setRequestMethod($method);
        $this->setServerGlobal('REQUEST_METHOD', $method);
    }

    /**
     * Sets URL
     *
     * @param string $url
     */
    public function setRequestUrl($url)
    {
        parent::setRequestUrl($url);
        $this->setServerGlobal('REQUEST_URI', $url);
    }

    /**
     * Sets POST fields
     *
     * @param array $fields
     */
    public function setPostFields(array $fields)
    {
        $this->post = $fields;

        $body = new Message\Body();
        $body->append(http_build_query($fields));
        parent::setBody($body);

        $_POST = $fields;
        $_REQUEST = array_merge($_GET, $_POST);
    }

    /**
     * Sets POST files
     *
     * @param array $fields
     */
    public function setPostFiles()
    {
        $_FILES = array();
        throw new \Exception('Not implemented');
    }

    /**
     * Sets GET fields
     *
     * @param array $fields
     */
    public function setQueryFields(array $fields)
    {
        $this->get = $fields;

        $this->setServerGlobal('QUERY_STRING', $this->getQueryData());

        $_GET = $fields;
        $_REQUEST = array_merge($_GET, $_POST);
    }

    /**
     * Sets cookies
     *
     * @param array $cookies
     */
    public function setCookies(Cookie $cookies)
    {
        $data = $cookies->toArray();
        $this->cookies = $data['cookies'];
        $_COOKIE = $this->cookies;
    }

    /**
     * Get timestamp of the request
     *
     * @return float
     */
    public function getTimestamp()
    {
        return $this->timestamp;
    }

    /**
     * Get remote user info
     *
     * @return array
     */
    public function getRemoteInfo()
    {
        return $this->remote;
    }

    /**
     * Get server info
     *
     * @return array
     */
    public function getServerInfo()
    {
        return $this->server;
    }

    /**
     * Get headers
     *
     * @return array
     */
    public function getHeaders()
    {
        return parent::getHeaders();
    }

    /**
     * Get a header by name
     *
     * @param  string $header
     * @return string
     */
    public function getHeader($header, $into_class = null)
    {
        $header = parent::getHeader($header);

        if (!is_array($header)) {
            return [$header];
        }

        return $header;
    }

    /**
     * Get method
     *
     * @return string
     */
    public function getRequestMethod()
    {
        return parent::getRequestMethod();
    }

    /**
     * Get URL
     *
     * @return string
     */
    public function getRequestUrl()
    {
        return parent::getRequestUrl();
    }

    /**
     * Get POST fields
     *
     * @return array
     */
    public function getPostFields()
    {
        return $this->post;
    }

    /**
     * Get GET fields
     *
     * @return array
     */
    public function getQueryFields()
    {
        return $this->get;
    }

    /**
     * Get the current query data in form of an urlencoded query string.
     *
     * @return string
     */
    public function getQueryData()
    {
        return http_build_query($this->get);
    }

    /**
     * Get POST files
     *
     * @return array
     */
    public function getPostFiles()
    {
        throw new \Exception('Not implemented');
    }

    /**
     * Get cookies
     *
     * @return array
     */
    public function getCookies()
    {
       return $this->cookies;
    }

    private function setServerGlobal($key, $value)
    {
        $_SERVER[$key] = $value;
    }

    /**
     * Returns a array with the values of this Request
     *
     * @return array
     */
    public function toArray()
    {
        return array(
            'url' => $this->getRequestUrl(),
            'method' => $this->getRequestMethod(),
            'headers' => $this->getHeaders(),
            'post' => $this->getPostFields(),
            'get' => $this->getQueryFields(),
            'server' => $this->getServerInfo(),
            'remote' => $this->getRemoteInfo()
        );
    }

    /**
     * Returns a string with the values of this Request
     *
     * @param  boolean $default if TRUE setDefaults() is called
     * @return string
     */
    public function toString($deprecated = false)
    {
        return (string) $this;
    }

    /**
     * Returns a JSON with the values of this Request
     *
     * @return string
     */
    public function toJSON()
    {
        return json_encode($this->toArray());
    }
}


<?php

namespace Pacificnm\Controller\Hydrator;

use Zend\Hydrator\ClassMethods;
use Pacificnm\Controller\Entity\Entity;

class Hydrator extends ClassMethods
{

    /**
     * @param string $underscoreSeparatedKeys
     */
    public function __construct($underscoreSeparatedKeys = true)
    {
        parent::__construct($underscoreSeparatedKeys);
    }

    /**
     * {@inheritdoc}
     *
     * @see \Zend\Stdlib\Hydrator\ClassMethods::hydrate()
     */
    public function hydrate(array $data, $object)
    {
        if (! $object instanceof Entity) {
            return $object;
        }

        parent::hydrate($data, $object);

        $moduleEntity = parent::hydrate($data, new \Pacificnm\Module\Entity\Entity());

        $object->setModuleEntity($moduleEntity);

        return $object;
    }

    /**
     * {@inheritdoc}
     *
     * @see \Zend\Stdlib\Hydrator\ClassMethods::extract()
     */
    public function extract($object)
    {
        if (! $object instanceof Entity) {
            return $object;
        }

        $data = parent::extract($object);

        unset($data['module_entity']);

        return $data;
    }

}