<?php
/**
 * Created by PhpStorm.
 * User: alexandre
 * Date: 18/01/17
 * Time: 21:33
 */

namespace Gosyl\CommonBundle\Twig;

class Modal extends \Twig_Extension {
    /**
     * @var array
     */
    protected $aOptions;

    /**
     * @var string
     */
    protected $idModal = 'myModal';

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

    public function getFunctions() {
        return array(
            new \Twig_SimpleFunction('modal', array($this, 'modalFunction'), array('is_safe' => array('html')))
        );
    }

    /**
     * $aOptions ['footer' => [
     *               'text' => [],
     *               'buttons' => [
     *                   [
     *                       'id' => "",
     *                       'class' => ["", ""] | "",
     *                       'forClose' => true|false,
     *                       'label' => ""
     *                   ],
     *                   [...],
     *               ]
     *           ],
     *           'options' => [
     *              'id' => "",
     *              'js' => [
     *                  'backdrop' => 'static'|false
     *                  'keyboard' => boolean,
     *                  'show' => boolean
     *              ],
     *              'class' => [
     *                  'modal' => ['class1', 'class2', ...],
     *                  'modal-dialog' => ['class1', 'class2', ...]
     *              ]
     *           ]
     *       ]
     *
     * @param string $sTitle
     * @param string $sBody
     * @param array $aOptions
     * @return string
     */
    public function modalFunction($sTitle = '', $sBody = '', array $aOptions = array()) {
        $this->aOptions = $aOptions;

        if (array_key_exists('options', $this->aOptions)) {
            if (array_key_exists('id', $this->aOptions['options'])) {
                $this->idModal = $this->aOptions['options']['id'];
            }

            if(array_key_exists('class', $this->aOptions['options'])) {
                //$this->classModal = $this->aOptions['options']['class'];
                $this->classModal['modal'] = isset($this->aOptions['options']['class']['modal']) ? $this->aOptions['options']['class']['modal'] : [];
                $this->classModal['modal-dialog'] = isset($this->aOptions['options']['class']['modal-dialog']) ? $this->aOptions['options']['class']['modal-dialog'] : [];
            } else {
                $this->classModal['modal'] = [];
                $this->classModal['modal-dialog'] = [];
            }
        }

        $sContenu = '
classModal['modal'])) .'" id="' . $this->idModal . '" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">';
        $sContenu .= '
classModal['modal-dialog'])) .'" role="document">';
        $sContenu .= '
';

        $sContenu .= $this->_getHeader($sTitle);
        $sContenu .= $this->_getBody($sBody);
        $sContenu .= $this->_getFooter();

        $sContenu .= '
';
        $sContenu .= '
';
        $sContenu .= '
';
        $sContenu .= $this->_getJs();
        return $sContenu;
    }

    public function getName() {
        return 'twig.extension.modal';
    }

    protected function _getBody($sBody) {
        return '
' . $sBody . '
';
    }

    protected function _getFooter() {
        $sContenu = '';

        if (count($this->aOptions) != 0 && array_key_exists('footer', $this->aOptions)) {
            $sContenu .= '
';
            $aFooterContenu = $this->aOptions['footer'];
            if (array_key_exists('text', $aFooterContenu)) {
                $sContenu .= $this->_getFooterText($aFooterContenu['text']);
            }

            if (array_key_exists('buttons', $aFooterContenu)) {
                $sContenu .= $this->_getFooterButtons($aFooterContenu['buttons']);
            }
            $sContenu .= '
';
        }

        return $sContenu;
    }

    protected function _getFooterButtonClass(array $aButton) {
        $sContenu = '';

        if (array_key_exists('class', $aButton)) {
            if (is_string($aButton['class'])) {
                $aButton['class'] = array($aButton['class']);
            }

            if (is_array($aButton['class'])) {
                foreach ($aButton['class'] as $sClass) {
                    $sContenu .= ' ' . $sClass;
                }
            }
        }

        return $sContenu;
    }

    protected function _getFooterData(array $aButton) {
        $sContenu = '';

        if (array_key_exists('forClose', $aButton)) {
            if ($aButton['forClose']) {
                $sContenu .= ' data-dismiss="modal"';
            }
        }

        return $sContenu;
    }

    protected function _getFooterButtons(array $aButtons) {
        $sContenu = '';

        foreach ($aButtons as $aButton) {
            $sContenu .= '<button type="button" id="' . $aButton['id'] . '" class="btn' . $this->_getFooterButtonClass($aButton) . '"' . $this->_getFooterData($aButton) . '>' . $aButton['label'] . '</button>';
        }

        return $sContenu;
    }

    protected function _getFooterText(array $aTexts) {
        $sContenu = '';

        foreach ($aTexts as $text) {
            $sContenu .= '
' . $text . '
';
        }

        return $sContenu;
    }

    protected function _getHeader($sTitle) {
        $sContenu = '
';
        $sContenu .= '<button type="button" class="close" data-dismiss="modal" aria-label="Fermer">
            ×
        </button>';
        $sContenu .= '
' . $sTitle . '
';

        $sContenu .= '
';
        return $sContenu;
    }

    protected function _getJs() {
        $sContenu = '';
        if (array_key_exists('options', $this->aOptions)) {
            if (array_key_exists('js', $this->aOptions['options'])) {
                $sContenu .= '';
        }

        return $sContenu;
    }
}


<?php
/**
 * This file is part of the Hephaistos project management API.
 *
 * As each files provides by the CSCFA, this file is licensed
 * under the MIT license.
 *
 * PHP version 5.6
 *
 * @category Trait
 * @package  Hephaistos
 * @author   matthieu vallance <matthieu.vallance@cscfa.fr>
 * @license  MIT <https://opensource.org/licenses/MIT>
 * @link     http://cscfa.fr
 */
namespace CSDT\CollectionsBundle\TraitCollection;

/**
 * Map collection trait
 *
 * This trait define the method logic
 * for the methods of the map collection.
 *
 * @category Trait
 * @package  Hephaistos
 * @author   matthieu vallance <matthieu.vallance@cscfa.fr>
 * @license  MIT <https://opensource.org/licenses/MIT>
 * @link     http://cscfa.fr
 */
trait MapCollectionTrait
{
    /**
     * Has
     *
     * This method check if the given key exist
     * in the current content set. It return
     * true if the key is find. False otherwise.
     *
     * @param mixed $key The key to search
     *
     * @return boolean
     */
    public function has($key)
    {
        return array_key_exists($key, $this->content);
    }

    /**
     * Get
     *
     * This method is used to get the content of
     * the specified index if exist. It return
     * null if the index does not contain anything
     * or if it does not exist.
     *
     * @param mixed $key The index whence get the content
     *
     * @return mixed|null
     */
    public function get($key)
    {
        if ($this->has($key)) {
            return $this->content[$key];
        }

        return null;
    }

    /**
     * Set
     *
     * This method set a specific key with a value.
     *
     * @param mixed $key   The key where insert the value
     * @param mixed $value The value to insert
     *
     * @return MapCollectionInterface
     */
    public function set($key, $value)
    {
        $this->content[$key] = $value;
        return $this;
    }

    /**
     * Set all
     *
     * Setting a list of key value into an
     * associative array.
     *
     * @param array $assocArray The associative array to insert
     *
     * @return MapCollectionInterface
     */
    public function setAll(array $assocArray)
    {
        foreach ($assocArray as $key => $value) {
            $this->set($key, $value);
        }

        return $this;
    }

    /**
     * Remove
     *
     * Remove a specified key. It return the
     * value contained into the key.
     *
     * @param mixed $key The key to remove
     *
     * @return mixed
     */
    public function remove($key)
    {
        $returnValue = $this->get($key);
        $this->content = array_diff_key($this->content, array_flip(array($key)));
        return $returnValue;
    }

    /**
     * Remove all
     *
     * This method allow to remove a set of key. It return
     * an array of removed value.
     *
     * @param array $keys The set of key to remove
     *
     * @return array
     */
    public function removeAll(array $keys)
    {
        $comparison = array_flip($keys);

        $returnValues = array_intersect_key($this->content, $comparison);
        $this->content = array_diff_key($this->content, $comparison);
        return $returnValues;
    }
}


<?php
/**
 * Created by PhpStorm.
 * User: bennet
 * Date: 02.10.18
 * Time: 13:00
 */

namespace BIND;

use BIND\classes\Zone;

class BIND {

    private $host;
    private $port;
    private $https;
    private $path;

    /**
     * BIND constructor.
     * @param String $host The Host of the API
     * @param int $port The Port of the API
     */
    public function __construct(String $host, int $port = 5000, $https = false) {
        $this->host = $host;
        $this->port = $port;
        $this->https = $https;
    }

    /**
     * Get the Port that is set
     * @return int
     */
    public function getPort(): int {
        return $this->port;
    }

    /**
     * Get the Host that is set
     * @return String
     */
    public function getHost(): String {
        return $this->host;
    }

    /**
     * @return bool
     */
    public function isHttps(): bool {
        return $this->https;
    }

    /**
     * @param string $method
     * @return mixed Response from the API
     */
    public function request($method = 'GET') {
        $ch = curl_init();
        $requestpath = ($this->isHttps() == true ? "https://" : "http://") . $this->getHost() . ":" . $this->getPort() . "/dns/" . $this->path;
        curl_setopt($ch, CURLOPT_URL, $requestpath);
        if ($method == "POST") {
            curl_setopt($ch, CURLOPT_POST, 1);
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);
        return json_decode($output);
    }

    /**
     * Get A Zone based on the Name
     * @param String $zone The Zone to be searched
     * @return Zone the Zone Object
     */
    public function getZone(String $zone) {
        $this->path = "zone/"  . $zone;
        $response = $this->request();

        return new Zone($response);
    }

    /** PUT OR POST
     * @param String $domain
     * @param int $ttl
     * @param String $recordType
     * @param String $value
     * @return bool
     */
    public function addRecord(String $domain, int $ttl, String $recordType, String $value) {
        return $this->manage($domain, $ttl, $recordType, $value);
    }

    /** DELETE METHOD
     * @param String $domain
     * @param int $ttl
     * @param String $recordType
     * @param String $value
     * @return bool
     */
    public function deleteRecord(String $domain, int $ttl, String $recordType, String $value) {
        return $this->manage($domain, $ttl, $recordType, $value, "DELETE");
    }

    /**
     * @param String $domain
     * @param int $ttl
     * @param String $recordType
     * @param String $value
     * @param String $method
     * @return bool if the reqest was a success
     */
    private function manage(String $domain, int $ttl, String $recordType, String $value, String $method = 'POST') {
        $this->path = "record/" . $domain . "/" . $ttl . "/" . $recordType . "/" . $value;
        $response = $this->request($method);
        if ($response->$domain == "DNS request successful") {
            return true;
        } else {
            return false;
        }
    }
}


<?php
namespace Soluble\Normalist\Synthetic;

use Soluble\Normalist\Driver;
use Soluble\Db\Sql\Select;
use Soluble\Schema\Source;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
use ArrayObject;

class TableManager
{
    /**
     *
     * @param Adapter $adapter
     */
    protected $adapter;

    /**
     *
     * @var Source\AbstractSchemaSource
     */
    protected $metadata;

    /**
     * Global table prefix
     * @var string
     */
    protected $table_prefix;

    /**
     *
     * @var \Zend\Db\Sql\Sql
     */
    protected $sql;

    /**
     *
     * @var Transaction
     */
    protected $transaction;

    /**
     *
     * @var \ArrayObject
     */
    protected $localTableCache;

    /**
     *
     * @var Driver\DriverInterface
     */
    protected $driver;

    /**
     *
     * @param Driver\DriverInterface $driver
     */
    public function __construct(Driver\DriverInterface $driver)
    {
        $this->localTableCache = new ArrayObject();
        $this->driver = $driver;
        $this->setDbAdapter($driver->getDbAdapter());

        $this->sql = new Sql($this->adapter);
    }

    /**
     * Return a synthetic table
     *
     * @param string $table_name table name
     *
     * @throws Exception\InvalidArgumentException if table name is not valid
     *
     * @return Table
     */
    public function table($table_name)
    {
        if (!is_string($table_name)) {
            throw new Exception\InvalidArgumentException(__METHOD__ . ": Table name must be a string");
        }

        if (!$this->localTableCache->offsetExists($table_name)) {
            $tables = $this->metadata()->getTables();
            if (!in_array($table_name, $tables)) {
                throw new Exception\TableNotFoundException(__METHOD__ . ": Table $table_name is not found in database, if table exists please make sure cache is updated.");
            }
            $table = new Table($table_name, $this);
            $this->localTableCache->offsetSet($table_name, $table);
        }
        return $this->localTableCache->offsetGet($table_name);
    }

    /**
     * Return a generic select
     *
     * @return Select
     */
    public function select()
    {
        $select = new Select();
        $select->setDbAdapter($this->adapter);
        return $select;
    }

    /**
     * Return a transaction object
     *
     * @return Transaction
     */
    public function transaction()
    {
        if ($this->transaction === null) {
            $this->transaction = new Transaction($this->adapter);
        }
        return $this->transaction;
    }

    /**
     * Return underlyng Zend\Db\Adapter\Adapter
     *
     * @return Adapter $adapter
     */
    public function getDbAdapter()
    {
        return $this->adapter;
    }

    /**
     * Set global table prefix
     *
     * @param string $table_prefix
     * @return TableManager
     */
    public function setTablePrefix($table_prefix)
    {
        $this->table_prefix = $table_prefix;
        return $this;
    }

    /**
     * Return global table prefix
     *
     * @return string
     */
    public function getTablePrefix()
    {
        return $this->table_prefix;
    }

    /**
     * Return prefixed table name
     *
     * @param string $table
     * @return string
     */
    public function getPrefixedTable($table)
    {
        return $this->table_prefix . $table;
    }

    /**
     * Return a metadata reader
     *
     * @return Source\AbstractSchemaSource
     */
    public function metadata()
    {
        if ($this->metadata === null) {
            $this->loadDefaultMetadata();
        }
        return $this->metadata;
    }

    /**
     * Set the database adapter
     *
     * @param Adapter $adapter
     * @return TableManager
     */
    protected function setDbAdapter(Adapter $adapter)
    {
        $this->adapter = $adapter;
        return $this;
    }

    /**
     * Return default metadata reader associated to an adapter
     *
     * @throws Exception\UnsupportedFeatureException
     */
    protected function loadDefaultMetadata()
    {
        $adapterName = $this->adapter->getPlatform()->getName();
        switch (strtolower($adapterName)) {
            case 'mysql':
                // supported
                break;
            default:
                throw new Exception\UnsupportedFeatureException(__METHOD__ . ":  Adapter '$adapterName' is not yet supported.");
        }
        $this->metadata = $this->driver->getMetadata();
    }

    /**
     *
     * @param Source\AbstractSchemaSource $metadata
     * @return TableManager
     */
    public function setMetadata(Source\AbstractSchemaSource $metadata)
    {
        $this->metadata = $metadata;
        return $this;
    }
}


<?php

namespace Sinpe\Cache;

use Psr\SimpleCache\CacheInterface;

/**
 * Class Assistant.
 *
 * 存储缓存的key值，使得缓存可管理，比如可用于缓存手工清除
 *
 * @author    wupinglong <18222544@qq.com>
 * @copyright 2018 Sinpe, Inc.
 *
 * @see      http://www.sinpe.com/
 */
class Assistant
{
    /**
     * 格式化标签的回调.
     *
     * @var Closure
     */
    private static $_normalize;

    /**
     * The cache manager.
     *
     * @var \Sinpe\Cache\Psr16Manager
     */
    protected $manager;

    /**
     * The tags.
     *
     * @var array
     */
    protected $tags;

    /**
     * The items.
     *
     * @var array
     */
    protected $items = [];

    /**
     * 支持自定义格式化tag如何转换为key.
     *
     * @param Closure $normalize 匿名函数
     */
    public static function setNormalize(Closure $normalize)
    {
        static::$_normalize = $normalize;
    }

    /**
     * Set the cache manager.
     *
     * @param \Sinpe\Cache\Psr16Manager $manager 缓存管理
     * @param string|array              $tags    标签
     */
    public function __construct($manager, $tags)
    {
        if (!$manager instanceof Psr16Manager) {
            throw new InvalidArgumentException(
                sprintf(
                    'Cache must be "%s", "%s" given',
                    CacheInterface::class,
                    is_object($manager) ? get_class($manager) : gettype($manager)
                )
            );
        }

        $this->manager = $manager;

        if (!is_string($tags) && !is_array($tags)) {
            throw new InvalidArgumentException(
                i18n(
                    'Tags must be string or string[], "%s" given',
                    gettype($tags)
                )
            );
        }

        $this->tags = (array) $tags;

        foreach ($this->tags as $tag) {
            $this->items[$tag] = $this->_getItemsByTag($tag);
        }
    }

    /**
     * Flush the cache.
     *
     * @return static
     */
    public function flushCache()
    {
        foreach ($this->tags as $tag) {
            $this->_removeCacheDatas($tag);
        }

        $this->items = [];

        return $this;
    }

    /**
     * Save the collection to cache.
     *
     * @return static
     */
    public function save()
    {
        foreach ($this->tags as $tag) {
            $this->_keepKeys($tag);
        }

        return $this;
    }

    /**
     * Add cached key.
     *
     * @param string $key 缓存的key
     *
     * @return static
     */
    public function add(string $key)
    {
        foreach ($this->items as  &$items) {
            array_push($items, $key);
        }

        return $this;
    }

    /**
     * Remove cached key.
     *
     * @param string $key 缓存的key
     *
     * @return static
     */
    public function remove(string $key)
    {
        foreach ($this->items as  &$items) {
            if ($pos = array_search($key, $items)) {
                array_splice($items, $pos, 1);
            }
        }

        return $this;
    }

    /**
     * 获取缓存key.
     *
     * @param string $tag 标签
     *
     * @return array
     */
    private function _getItemsByTag($tag)
    {
        $key = $this->normalizeTagForKey($tag);

        $result = $this->manager->get($key);
        // 缓存没有或者过期
        if (is_null($result)) {
            try {
                $result = Entity::where('key', '=', $key)->value('items');
            } catch (\Exception $e) {
                if ($this->manager->debug()) {
                    throw $e;
                } else {
                    $logger = $this->manager->logger();
                    if ($logger) {
                        $logger->warning($e->getMessage(), ['tag' => $tag, 'key' => $key]);
                    }
                }
            }
        }

        return is_null($result) ? [] : $result;
    }

    /**
     * Flush the cache data.
     *
     * @param string $tag 标签
     *
     * @return static
     */
    private function _removeCacheDatas($tag)
    {
        // 删除缓存的数据
        $this->manager->deleteMultiple($this->items[$tag]);

        $key = $this->normalizeTagForKey($tag);
        // 删除缓存键
        $this->manager->delete($key);
        // 删除数据库存储的键
        try {
            Entity::where('key', '=', $key)->delete();
        } catch (\Exception $e) {
            if ($this->manager->debug()) {
                throw $e;
            } else {
                $logger = $this->manager->logger();
                if ($logger) {
                    $logger->warning($e->getMessage(), ['tag' => $tag, 'key' => $key]);
                }
            }
        }

        return $this;
    }

    /**
     * 永久存储key.
     *
     * @param string $tag 标签
     *
     * @return static
     */
    private function _keepKeys($tag)
    {
        $key = $this->normalizeTagForKey($tag);
        $items = array_unique($this->items[$tag]);

        // 存入缓存
        $this->manager->set($key, $items, 999999999);
        // 永久存入数据库
        try {
            Entity::updateOrCreate(
                ['key' => $key],
                ['items' => $items]
            );
        } catch (\Exception $e) {
            // 不做任何处理
            if ($this->manager->debug()) {
                throw $e;
            } else {
                $logger = $this->manager->logger();
                if ($logger) {
                    $logger->warning($e->getMessage(), ['tag' => $tag, 'key' => $key]);
                }
            }
        }

        return $this;
    }

    /**
     * 格式化标签作为缓存key.
     *
     * @param string $tag 标签
     *
     * @return string
     */
    protected function normalizeTagForKey($tag)
    {
        if (!static::$_normalize) {
            static::$_normalize = function ($tag) {
                return 'cache::tags.'.$tag;
            };
        }

        return static::$_normalize($tag);
    }
}


<?php
namespace FzyCommon\Util;

use Zend\Json\Json;
use Zend\Http\Request;

/**
 * Wrapper for passing arrays of parameter values between services
 * Class Param
 * @package FzyCommon\Util
 */
class Params
{
    protected $params = array();

    public function __construct(array $params = null)
    {
        if (!empty($params)) {
            $this->params = $params;
        }
    }

    /**
     * If $key is not specified, will return entire param array
     * If $key is specified, will check the parameter array for key $key and
     * return the value if it exists, otherwise $default
     * @param  null       $key
     * @param  null       $default
     * @return array|null
     */
    public function get($key = null, $default = null)
    {
        if ($key === null) {
            return $this->params;
        }

        return $this->has($key) ? $this->params[$key] : $default;
    }

    /**
     * @param $key
     * @param array $default
     *
     * @return Params
     */
    public function getWrapped($key, $default = array())
    {
        return Params::create($this->get($key, $default));
    }

    /**
     * Additionally converts 1, "1", and "true" to true and 0, "0", and "false" to false
     * @param $key
     * @param  null $default
     * @return bool
     */
    public function getBoolean($key, $default = null)
    {
        $value = $this->get($key, $default);
        if (is_numeric($value)) {
            $value = intval($value);
        } elseif (is_string($value)) {
            $value = strtolower($value) == 'true' ? true : false;
        }

        return $value ? true : false;
    }

    /**
     * Set a specific key/value pair
     * @param $key
     * @param $value
     * @return $this
     */
    public function set($key, $value)
    {
        $this->params[$key] = $value;

        return $this;
    }

    /**
     * Remove a specific key/value pair
     * @param $key
     * @param $value
     * @return $this
     */
    public function remove($key)
    {
        unset($this->params[$key]);

        return $this;
    }

    /**
     * Overwrite entire param array
     * @param  array $params
     * @return $this
     */
    public function setAll(array $params)
    {
        $this->params = $params;

        return $this;
    }

    /**
     * Get entire param array
     * @param  array $params
     * @return $this
     */
    public function getAll()
    {
        return $this->params;
    }

    /**
     * Returns whether the key exists in this param array
     * @param $key
     * @return bool
     */
    public function has($key)
    {
        return isset($this->params[$key]);
    }

    /**
     * @param $key
     * @return bool
     */
    public function hasKey($key)
    {
        return array_key_exists($key, $this->params);
    }

    /**
     * Create a Param instance
     * @param  null                      $params
     * @param  null|Request              $request
     * @return Params
     * @throws \InvalidArgumentException
     */
    public static function create($params = null, Request $request = null)
    {
        if ($params === null) {
            return new Params();
        } elseif (is_array($params)) {
            return new Params($params);
        } elseif ($params instanceof \Traversable) {
            return new Params(self::extractParamsFromCollection($params));
        } elseif ($params instanceof \Zend\Mvc\Controller\Plugin\Params) {
            $results = array();
            /* @var $r \Zend\Http\Request */
            foreach (array(
                         $params->fromQuery(),
                         $params->fromPost(),
                         self::getBodyData($request),
                         $params->fromRoute(),
                         $params->fromFiles(),
                     ) as $collection) {
                $results = array_merge($results, $collection);
            }

            return new Params($results);
        } elseif ($params instanceof Param) {
            return new Params($params->get());
        }
        throw new \InvalidArgumentException("Unrecognized parameter collection");
    }

    public function slice(array $keys)
    {
        $slice = array();
        foreach ($keys as $key) {
            $slice[$key] = $this->get($key);
        }

        return $slice;
    }

    public function merge($data)
    {
        if ($data instanceof Params) {
            $this->params = array_merge($this->params, $data->get());
        } elseif (is_array($data)) {
            $this->params = array_merge($this->params, $data);
        } else {
            throw new \RuntimeException("Unable to merge parameter data. Expected array or another Params object.");
        }

        return $this;
    }

    protected static function getBodyData(Request $request = null)
    {
        $result = array();
        if ($request !== null) {
            $content = $request->getContent();
            if (!empty($content)) {
                try {
                    $result = Json::decode($content, Json::TYPE_ARRAY);
                } catch (\RuntimeException $e) {
                }
            }
        }

        return $result;
    }

    /**
     * Converts an iterable collection into a raw array
     * @param $collection
     * @return array
     */
    public static function extractParamsFromCollection($collection)
    {
        $result = array();
        foreach ($collection as $key => $value) {
            $result[$key] = $value;
        }

        return $result;
    }
}


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

/**
 * @package    Zend_Cache
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
abstract class Zend_Cache
{

    /**
     * Standard frontends
     *
     * @var array
     */
    public static $standardFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page');

    /**
     * Standard backends
     *
     * @var array
     */
    public static $standardBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform',
                                            'Xcache', 'TwoLevels', 'WinCache', 'ZendServer_Disk', 'ZendServer_ShMem');

    /**
     * Standard backends which implement the ExtendedInterface
     *
     * @var array
     */
    public static $standardExtendedBackends = array('File', 'Apc', 'TwoLevels', 'Memcached', 'Libmemcached', 'Sqlite', 'WinCache');

    /**
     * Only for backward compatibility (may be removed in next major release)
     *
     * @var array
     * @deprecated
     */
    public static $availableFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page');

    /**
     * Only for backward compatibility (may be removed in next major release)
     *
     * @var array
     * @deprecated
     */
    public static $availableBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform', 'Xcache', 'WinCache', 'TwoLevels');

    /**
     * Consts for clean() method
     */
    const CLEANING_MODE_ALL              = 'all';
    const CLEANING_MODE_OLD              = 'old';
    const CLEANING_MODE_MATCHING_TAG     = 'matchingTag';
    const CLEANING_MODE_NOT_MATCHING_TAG = 'notMatchingTag';
    const CLEANING_MODE_MATCHING_ANY_TAG = 'matchingAnyTag';

    /**
     * Factory
     *
     * @param mixed  $frontend        frontend name (string) or Zend_Cache_Frontend_ object
     * @param mixed  $backend         backend name (string) or Zend_Cache_Backend_ object
     * @param array  $frontendOptions associative array of options for the corresponding frontend constructor
     * @param array  $backendOptions  associative array of options for the corresponding backend constructor
     * @param boolean $customFrontendNaming if true, the frontend argument is used as a complete class name ; if false, the frontend argument is used as the end of "Zend_Cache_Frontend_[...]" class name
     * @param boolean $customBackendNaming if true, the backend argument is used as a complete class name ; if false, the backend argument is used as the end of "Zend_Cache_Backend_[...]" class name
     * @param boolean $autoload if true, there will no require_once for backend and frontend (useful only for custom backends/frontends)
     * @throws Zend_Cache_Exception
     * @return Zend_Cache_Core|Zend_Cache_Frontend
     */
    public static function factory($frontend, $backend, $frontendOptions = array(), $backendOptions = array(), $customFrontendNaming = false, $customBackendNaming = false, $autoload = false)
    {
        if (is_string($backend)) {
            $backendObject = self::_makeBackend($backend, $backendOptions, $customBackendNaming, $autoload);
        } else {
            if ((is_object($backend)) && (in_array('Zend_Cache_Backend_Interface', class_implements($backend)))) {
                $backendObject = $backend;
            } else {
                self::throwException('backend must be a backend name (string) or an object which implements Zend_Cache_Backend_Interface');
            }
        }
        if (is_string($frontend)) {
            $frontendObject = self::_makeFrontend($frontend, $frontendOptions, $customFrontendNaming, $autoload);
        } else {
            if (is_object($frontend)) {
                $frontendObject = $frontend;
            } else {
                self::throwException('frontend must be a frontend name (string) or an object');
            }
        }
        $frontendObject->setBackend($backendObject);
        return $frontendObject;
    }

    /**
     * Backend Constructor
     *
     * @param string  $backend
     * @param array   $backendOptions
     * @param boolean $customBackendNaming
     * @param boolean $autoload
     * @return Zend_Cache_Backend
     */
    public static function _makeBackend($backend, $backendOptions, $customBackendNaming = false, $autoload = false)
    {
        if (!$customBackendNaming) {
            $backend  = self::_normalizeName($backend);
        }
        if (in_array($backend, Zend_Cache::$standardBackends)) {
            // we use a standard backend
            $backendClass = 'Zend_Cache_Backend_' . $backend;
            // security controls are explicit
            require_once str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php';
        } else {
            // we use a custom backend
            if (!preg_match('~^[\w\\\\]+$~D', $backend)) {
                Zend_Cache::throwException("Invalid backend name [$backend]");
            }
            if (!$customBackendNaming) {
                // we use this boolean to avoid an API break
                $backendClass = 'Zend_Cache_Backend_' . $backend;
            } else {
                $backendClass = $backend;
            }
            if (!$autoload) {
                $file = str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php';
                if (!(self::_isReadable($file))) {
                    self::throwException("file $file not found in include_path");
                }
                require_once $file;
            }
        }
        return new $backendClass($backendOptions);
    }

    /**
     * Frontend Constructor
     *
     * @param string  $frontend
     * @param array   $frontendOptions
     * @param boolean $customFrontendNaming
     * @param boolean $autoload
     * @return Zend_Cache_Core|Zend_Cache_Frontend
     */
    public static function _makeFrontend($frontend, $frontendOptions = array(), $customFrontendNaming = false, $autoload = false)
    {
        if (!$customFrontendNaming) {
            $frontend = self::_normalizeName($frontend);
        }
        if (in_array($frontend, self::$standardFrontends)) {
            // we use a standard frontend
            // For perfs reasons, with frontend == 'Core', we can interact with the Core itself
            $frontendClass = 'Zend_Cache_' . ($frontend != 'Core' ? 'Frontend_' : '') . $frontend;
            // security controls are explicit
            require_once str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php';
        } else {
            // we use a custom frontend
            if (!preg_match('~^[\w\\\\]+$~D', $frontend)) {
                Zend_Cache::throwException("Invalid frontend name [$frontend]");
            }
            if (!$customFrontendNaming) {
                // we use this boolean to avoid an API break
                $frontendClass = 'Zend_Cache_Frontend_' . $frontend;
            } else {
                $frontendClass = $frontend;
            }
            if (!$autoload) {
                $file = str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php';
                if (!(self::_isReadable($file))) {
                    self::throwException("file $file not found in include_path");
                }
                require_once $file;
            }
        }
        return new $frontendClass($frontendOptions);
    }

    /**
     * Throw an exception
     *
     * Note : for perf reasons, the "load" of Zend/Cache/Exception is dynamic
     * @param  string $msg  Message for the exception
     * @throws Zend_Cache_Exception
     */
    public static function throwException($msg, Exception $e = null)
    {
        // For perfs reasons, we use this dynamic inclusion

        throw new Zend_Cache_Exception($msg, 0, $e);
    }

    /**
     * Normalize frontend and backend names to allow multiple words TitleCased
     *
     * @param  string $name  Name to normalize
     * @return string
     */
    protected static function _normalizeName($name)
    {
        $name = ucfirst(strtolower($name));
        $name = str_replace(array('-', '_', '.'), ' ', $name);
        $name = ucwords($name);
        $name = str_replace(' ', '', $name);
        if (stripos($name, 'ZendServer') === 0) {
            $name = 'ZendServer_' . substr($name, strlen('ZendServer'));
        }

        return $name;
    }

    /**
     * Returns TRUE if the $filename is readable, or FALSE otherwise.
     * This function uses the PHP include_path, where PHP's is_readable()
     * does not.
     *
     * Note : this method comes from Zend_Loader (see #ZF-2891 for details)
     *
     * @param string   $filename
     * @return boolean
     */
    private static function _isReadable($filename)
    {
        if (!$fh = @fopen($filename, 'r', true)) {
            return false;
        }
        @fclose($fh);
        return true;
    }

}


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

use \CarteBlanche\CarteBlanche;
use \CarteBlanche\Interfaces\DependencyLoaderInterface;

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

    /**
     * Instance loader
     *
     * @param   array                       $config
     * @param   \CarteBlanche\App\Container $container
     * @return  object
     */
    public function load(array $config = null, \CarteBlanche\App\Container $container)
    {
        $config = $container->get('kernel')->getPath('default_em');
        if (empty($db_path)) {
            $db_dir = $container->get('kernel')->getPath('var_dir').'db'.DIRECTORY_SEPARATOR;
            $db_path = $container->get('kernel')->getPath('var_path').'db'.DIRECTORY_SEPARATOR;
            $container->get('kernel')->addPath('db_dir', $db_dir);
            $container->get('kernel')->addPath('db_path', $db_path, true, true);
        }
//      $_altdb = $this->container->get('request')->getUrlArg('altdb');
//      return \AutoObject\AutoObjectMapper::getEntityManager( $_altdb );
        return \CarteBlanche\Library\AutoObject\AutoObjectMapper::getEntityManager('default');
/*
        $dbname = getContainer()->get('request')->getUrlArg('altdb');
        if (empty($dbname)) $dbname = 'default';
        $dbfile = $this->kernel->registry->getStackEntry('db_name', $dbname.'_db', 'config');
        return new \Lib\Database( _ROOTPATH._DBDIR.$dbfile, 0666 );
*/
    }

}

// Endfile


<?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\Container\Annotations;

use Valkyrja\Annotations\Annotation;
use Valkyrja\Annotations\AnnotationsParser;
use Valkyrja\Annotations\NativeAnnotations;
use Valkyrja\Application;
use Valkyrja\Container\Service as ContainerService;
use Valkyrja\Container\ServiceContext as ContainerContextService;
use Valkyrja\Support\Providers\Provides;

/**
 * Class ContainerAnnotations.
 *
 * @author Melech Mizrachi
 */
class NativeContainerAnnotations extends NativeAnnotations implements ContainerAnnotations
{
    use Provides;

    /**
     * THe services annotation type.
     *
     * @var string
     */
    protected $servicesAnnotationType = 'Service';

    /**
     * The service alias annotation type.
     *
     * @var string
     */
    protected $aliasServicesAnnotationType = 'ServiceAlias';

    /**
     * The service context annotation type.
     *
     * @var string
     */
    protected $contextServicesAnnotationType = 'ServiceContext';

    /**
     * Get the services.
     *
     * @param string[] $classes The classes
     *
     * @throws \ReflectionException
     *
     * @return \Valkyrja\Container\Service[]
     */
    public function getServices(string ...$classes): array
    {
        return $this->getAllClassesAnnotationsByType(
            $this->servicesAnnotationType,
            ...$classes
        );
    }

    /**
     * Get the alias services.
     *
     * @param string[] $classes The classes
     *
     * @throws \ReflectionException
     *
     * @return \Valkyrja\Container\Annotations\ServiceContext[]
     */
    public function getAliasServices(string ...$classes): array
    {
        return $this->getAllClassesAnnotationsByType(
            $this->aliasServicesAnnotationType,
            ...$classes
        );
    }

    /**
     * Get the context services.
     *
     * @param string[] $classes The classes
     *
     * @throws \ReflectionException
     *
     * @return \Valkyrja\Container\ServiceContext[]
     */
    public function getContextServices(string ...$classes): array
    {
        return $this->getAllClassesAnnotationsByType(
            $this->contextServicesAnnotationType,
            ...$classes
        );
    }

    /**
     * Get all annotations for a class and its members by type.
     *
     * @param string   $type       The type
     * @param string[] ...$classes The classes
     *
     * @throws \ReflectionException
     *
     * @return array
     */
    protected function getAllClassesAnnotationsByType(string $type, string ...$classes): array
    {
        $annotations = [];

        // Iterate through all the classes
        foreach ($classes as $class) {
            // Get all the annotations for each class and iterate through them
            /** @var \Valkyrja\Annotations\Annotation $annotation */
            foreach ($this->classAndMembersAnnotationsType(
                $type,
                $class
            ) as $annotation) {
                $this->setServiceProperties($annotation);

                // If this annotation is a service
                if ($type === $this->servicesAnnotationType) {
                    /* @var \Valkyrja\Container\Annotations\Service $annotation */
                    $annotations[] =
                        $this->getServiceFromAnnotation($annotation);

                    continue;
                }

                // If this annotation is a context service
                if ($type === $this->contextServicesAnnotationType) {
                    /* @var \Valkyrja\Container\Annotations\ServiceContext $annotation */
                    $annotations[] =
                        $this->getServiceContextFromAnnotation($annotation);

                    continue;
                }

                // Set the annotation in the annotations list
                $annotations[] = $annotation;
            }
        }

        return $annotations;
    }

    /**
     * Set the properties for a service annotation.
     *
     * @param Annotation $annotation
     *
     * @throws \ReflectionException
     *
     * @return void
     */
    protected function setServiceProperties(Annotation $annotation): void
    {
        if (null === $annotation->getProperty()) {
            $parameters =
                $this->getMethodReflection(
                    $annotation->getClass(),
                    $annotation->getMethod() ?? '__construct'
                )
                     ->getParameters();

            // Set the dependencies
            $annotation->setDependencies(
                $this->getDependencies(...$parameters)
            );
        }

        $annotation->setMatches();
    }

    /**
     * Get a service from a service annotation.
     *
     * @param Service $service The service annotation
     *
     * @return \Valkyrja\Container\Service
     */
    protected function getServiceFromAnnotation(Service $service): ContainerService
    {
        $containerService = new ContainerService();

        $containerService
            ->setDefaults($service->getDefaults())
            ->setSingleton($service->isSingleton())
            ->setId($service->getId())
            ->setName($service->getName())
            ->setClass($service->getClass())
            ->setProperty($service->getProperty())
            ->setMethod($service->getMethod())
            ->setStatic($service->isStatic())
            ->setFunction($service->getFunction())
            ->setMatches($service->getMatches())
            ->setDependencies($service->getDependencies())
            ->setArguments($service->getArguments());

        return $containerService;
    }

    /**
     * Get a service context from a service context annotation.
     *
     * @param ServiceContext $service The service context annotation
     *
     * @return \Valkyrja\Container\ServiceContext
     */
    protected function getServiceContextFromAnnotation(ServiceContext $service): ContainerContextService
    {
        $containerService = new ContainerContextService();

        $containerService
            ->setContextClass($service->getContextClass())
            ->setContextProperty($service->getContextProperty())
            ->setContextMethod($service->getContextMethod())
            ->setContextFunction($service->getContextFunction())
            ->setDefaults($service->getDefaults())
            ->setSingleton($service->isSingleton())
            ->setId($service->getId())
            ->setName($service->getName())
            ->setClass($service->getClass())
            ->setProperty($service->getProperty())
            ->setMethod($service->getMethod())
            ->setStatic($service->isStatic())
            ->setFunction($service->getFunction())
            ->setMatches($service->getMatches())
            ->setDependencies($service->getDependencies())
            ->setArguments($service->getArguments());

        return $containerService;
    }

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

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


<?php

namespace Reaction\Db;

use Reaction\Base\Component;
use Reaction\Cache\ExpiringCacheInterface;
use Reaction\Cache\ExtendedCacheInterface;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Exceptions\NotSupportedException;
use Reaction\Helpers\ArrayHelper;
use Reaction\Promise\ExtendedPromiseInterface;
use function Reaction\Promise\all;
use Reaction\Promise\LazyPromiseInterface;
use function Reaction\Promise\resolve;

/**
 * Class Database
 * @package Reaction\Db
 */
class Database extends Component implements DatabaseInterface, DbConnectionGetterInterface
{
    public $host = 'localhost';
    public $port = '5432';
    public $username;
    public $password;
    public $database;

    public $tablePrefix = '';

    /**
     * @var array Schema, QueryBuilder, Connection and Command classes config
     */
    public $componentsConfig = [];

    /**
     * @var int Schema cache duration in seconds
     */
    public $schemaCacheDuration = 3600;
    /**
     * @var bool Enable schema caching
     */
    public $schemaCacheEnable = true;
    /**
     * @var array Table names excluded from caching
     */
    public $schemaCacheExclude = [];
    /**
     * @var int Query cache duration
     */
    public $queryCacheDuration = 60;
    /**
     * @var string Cache component name
     */
    public $cacheComponent = 'arrayCacheDefault';
    /**
     * @var bool Enable query logging
     */
    public $enableLogging = false;
    /**
     * @var bool Enable query profiling
     */
    public $enableProfiling = false;
    /**
     * @var bool Enable savepoint support
     */
    public $enableSavepoint = false;

    protected $_queryBuilder;
    protected $_schema;
    protected $_cache;
    protected $_initialized = false;

    /**
     * @inheritdoc
     */
    public function init()
    {
        $this->componentsConfig = ArrayHelper::merge($this->getDefaultComponentsConfig(), $this->componentsConfig);
        parent::init();
    }

    /**
     * Get DB driver name
     * @return string
     */
    public function getDriverName() {
        return 'unknown';
    }

    /**
     * Get cache component
     * @return ExpiringCacheInterface|null
     */
    public function getCache() {
        if (!isset($this->_cache) && isset($this->cacheComponent)) {
            if ($this->cacheComponent instanceof ExtendedCacheInterface) {
                $this->_cache = $this->cacheComponent;
            } else {
                $this->_cache = \Reaction::create($this->cacheComponent);
            }
        }
        return $this->_cache;
    }

    /**
     * Get query builder
     * @return QueryBuilderInterface
     */
    public function getQueryBuilder() {
        if (!isset($this->_queryBuilder)) {
            /** @var QueryBuilderInterface $queryBuilder */
            $queryBuilder = $this->createComponent(QueryBuilderInterface::class);
            $this->_queryBuilder = $queryBuilder;
        }
        return $this->_queryBuilder;
    }

    /**
     * Get Schema
     * @return SchemaInterface
     */
    public function getSchema() {
        if (!isset($this->_schema)) {
            /** @var SchemaInterface $schema */
            $schema = $this->createComponent(SchemaInterface::class);
            $this->_schema = $schema;
        }
        return $this->_schema;
    }

    /**
     * Create command
     * @param string|null              $sql
     * @param array                    $params
     * @param ConnectionInterface|null $connection
     * @return CommandInterface
     */
    public function createCommand($sql = null, $params = [], $connection = null) {
        /** @var CommandInterface $command */
        $config = ['sql' => $sql, 'params' => $params, 'connection' => $connection];
        $command = $this->createComponent(CommandInterface::class, $config);
        return $command;
    }

    /**
     * Create ColumnSchemaInterface instance
     * @return ColumnSchemaInterface
     */
    public function createColumnSchema() {
        $colSchema = $this->createComponent(ColumnSchemaInterface::class, [], false);
        return $colSchema;
    }

    /**
     * Get dsn string for cache keys
     * @return string
     */
    public function getDsn() {
        return "tcp://{$this->username}:{$this->password}@{$this->host}:{$this->port}/" . $this->database;
    }

    /**
     * Quotes a string value for use in a query.
     * Note that if the parameter is not a string, it will be returned without change.
     * @param string $value string to be quoted
     * @return string the properly quoted string
     * @see http://php.net/manual/en/pdo.quote.php
     */
    public function quoteValue($value)
    {
        return $this->getSchema()->quoteValue($value);
    }

    /**
     * Quotes a table name for use in a query.
     * If the table name contains schema prefix, the prefix will also be properly quoted.
     * If the table name is already quoted or contains special characters including '(', '[[' and '{{',
     * then this method will do nothing.
     * @param string $name table name
     * @return string the properly quoted table name
     */
    public function quoteTableName($name)
    {
        return $this->getSchema()->quoteTableName($name);
    }

    /**
     * Quotes a column name for use in a query.
     * If the column name contains prefix, the prefix will also be properly quoted.
     * If the column name is already quoted or contains special characters including '(', '[[' and '{{',
     * then this method will do nothing.
     * @param string $name column name
     * @return string the properly quoted column name
     */
    public function quoteColumnName($name)
    {
        return $this->getSchema()->quoteColumnName($name);
    }

    /**
     * Processes a SQL statement by quoting table and column names that are enclosed within double brackets.
     * Tokens enclosed within double curly brackets are treated as table names, while
     * tokens enclosed within double square brackets are column names. They will be quoted accordingly.
     * Also, the percentage character "%" at the beginning or ending of a table name will be replaced
     * with [[tablePrefix]].
     * @param string $sql the SQL to be quoted
     * @return string the quoted SQL
     */
    public function quoteSql($sql)
    {
        return preg_replace_callback(
            '/(\\{\\{(%?[\w\-\. ]+%?)\\}\\}|\\[\\[([\w\-\. ]+)\\]\\])/',
            function($matches) {
                if (isset($matches[3])) {
                    return $this->quoteColumnName($matches[3]);
                }

                return str_replace('%', $this->tablePrefix, $this->quoteTableName($matches[2]));
            },
            $sql
        );
    }

    /**
     * Execute SQL statement string
     * @param string $sql Statement SQL string
     * @param array  $params Statement parameters
     * @param bool   $lazy Use lazy promise
     * @throws NotSupportedException
     * @return ExtendedPromiseInterface|LazyPromiseInterface
     */
    public function executeSql($sql, $params = [], $lazy = true) {
        throw new NotSupportedException("Query execution is not supported by this driver");
    }

    /**
     * Init callback. Called by parent container/service/component on init and must return a fulfilled Promise
     * @return ExtendedPromiseInterface
     */
    public function initComponent()
    {
        $promises = [];
        $schema = $this->getSchema();
        $promises[] = $schema->initComponent();
        return all($promises)->always(function() {
            $this->_initialized = true;
            if (!\Reaction::isConsoleApp()) {
                \Reaction::info('{class} initialized', ['class' => get_called_class()]);
            }
            return true;
        });
    }

    /**
     * Check that component was initialized earlier
     * @return bool
     */
    public function isInitialized()
    {
        return $this->_initialized;
    }

    /**
     * @return TransactionInterface
     */
    public function createTransaction() {
        $config = [];
        return $this->createComponent(TransactionInterface::class, $config);
    }

    /**
     * Get dedicated connection (Not used in shared pool)
     * @return ConnectionInterface
     */
    public function getDedicatedConnection() {
        throw new NotSupportedException("Dedicated connection is not supported");
    }

    /**
     * Get default components config
     * @return array
     */
    protected function getDefaultComponentsConfig() {
        return [
            'Reaction\Db\SchemaInterface' => 'Reaction\Db\Schema',
            'Reaction\Db\QueryBuilderInterface' => 'Reaction\Db\QueryBuilder',
            'Reaction\Db\CommandInterface' => 'Reaction\Db\Command',
            'Reaction\Db\ColumnSchemaInterface' => 'Reaction\Db\ColumnSchema',
            'Reaction\Db\ConnectionInterface' => 'Reaction\Db\Connection',
            'Reaction\Db\TransactionInterface' => 'Reaction\Db\Transaction',
        ];
    }

    /**
     * Create inner component
     * @param string $interface
     * @param array  $config
     * @param bool   $injectDb
     * @return QueryBuilderInterface|SchemaInterface|CommandInterface|ColumnSchemaInterface|ConnectionInterface|TransactionInterface
     * @throws null
     */
    protected function createComponent($interface, $config = [], $injectDb = true) {
        if (!isset($this->componentsConfig[$interface])) {
            $message = sprintf('Suitable component for interface "%s" not configured in "%s"', $interface, __CLASS__);
            throw new InvalidConfigException($message);
        }
        $className = $this->componentsConfig[$interface];
        $_config = is_array($className) ? $className : ['class' => $className];
        $_config = ArrayHelper::merge($_config, $config);
        if ($injectDb) {
            $_config = ArrayHelper::merge(['db' => $this], $_config);
        }
        return \Reaction::create($_config);
    }

    /**
     * Get Database if applicable
     * @see DbConnectionGetterInterface
     * @return DatabaseInterface|null
     */
    public function getDb()
    {
        return $this;
    }

    /**
     * Get Connection if applicable
     * @see DbConnectionGetterInterface
     * @return ConnectionInterface|null
     */
    public function getConnection()
    {
        return null;
    }
}


<?php

declare(strict_types=1);

/**
 * States.
 *
 * LICENSE
 *
 * This source file is subject to the MIT license and the version 3 of the GPL3
 * license that are bundled with this package in the folder licences
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to richarddeloge@gmail.com so we can send you a copy immediately.
 *
 *
 * @copyright   Copyright (c) 2009-2017 Richard Déloge (richarddeloge@gmail.com)
 *
 * @link        http://teknoo.software/states Project website
 *
 * @license     http://teknoo.software/license/mit         MIT License
 * @author      Richard Déloge <richarddeloge@gmail.com>
 */

namespace Teknoo\States\LifeCycle\Tokenization;

use Teknoo\States\LifeCycle\Event\EventInterface;
use Teknoo\States\LifeCycle\StatedClass\LifeCyclableInterface;

/**
 * Class Tokenizer
 * Tokenizer to generate tokens from an event.
 *
 * Generate all tokens from an event, to be used by the event dispatcher, namespace separator are converted
 * to underscore, and the class is lowerized.
 * - a base token from the canonical stated class name
 * - a token by enabled states : "basetoken:<state name>"
 * - a token by incoming states : "basetoken:+<state name>"
 * - a token by outgoing states : "basetoken:-<state name>"
 *
 * @copyright   Copyright (c) 2009-2017 Richard Déloge (richarddeloge@gmail.com)
 *
 * @link        http://teknoo.software/states Project website
 *
 * @license     http://teknoo.software/license/mit         MIT License
 * @author      Richard Déloge <richarddeloge@gmail.com>
 */
class Tokenizer implements TokenizerInterface
{
    /**
     * To get the token from a stated class.
     *
     * @param string $statedClassName
     * @param bool   $removeProxyName
     *
     * @return string
     */
    public function getStatedClassNameToken(string $statedClassName, $removeProxyName = false): string
    {
        $statedClassNamePart = \explode('\\', $statedClassName);
        if (true === $removeProxyName) {
            \array_pop($statedClassNamePart);
        }

        return \strtolower(\implode('_', $statedClassNamePart));
    }

    /**
     * To get the token from a stated class instance.
     *
     * @param LifeCyclableInterface $object
     *
     * @return string
     */
    public function getStatedClassInstanceToken(LifeCyclableInterface $object): string
    {
        $statedClassName = \get_class($object);

        return $this->getStatedClassNameToken($statedClassName, true);
    }

    /**
     * {@inheritdoc}
     */
    public function getToken(EventInterface $event): array
    {
        $object = $event->getObject();

        $statedClassName = $this->getStatedClassInstanceToken($object);
        $tokenList = [$statedClassName];

        foreach ($event->getEnabledStates() as $stateName) {
            //Extract short class name and check if this state is not already loaded
            $shortStateName = \ltrim(\substr($stateName, (int) \strrpos($stateName, '\\')), '\\');

            $tokenList[] = $statedClassName.':'.\strtolower($shortStateName);
        }

        foreach ($event->getIncomingStates() as $stateName) {
            //Extract short class name and check if this state is not already loaded
            $shortStateName = \ltrim(\substr($stateName, (int) \strrpos($stateName, '\\')), '\\');

            $tokenList[] = $statedClassName.':+'.\strtolower($shortStateName);
        }

        foreach ($event->getOutgoingStates() as $stateName) {
            //Extract short class name and check if this state is not already loaded
            $shortStateName = \ltrim(\substr($stateName, (int) \strrpos($stateName, '\\')), '\\');

            $tokenList[] = $statedClassName.':-'.\strtolower($shortStateName);
        }

        return $tokenList;
    }
}


<?php
/**
 * PEAR_REST_11 - implement faster list-all/remote-list command
 *
 * PHP versions 4 and 5
 *
 * @category   pear
 * @package    PEAR
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    CVS: $Id: 11.php 313023 2011-07-06 19:17:11Z dufuz $
 * @link       http://pear.php.net/package/PEAR
 * @since      File available since Release 1.4.3
 */

/**
 * For downloading REST xml/txt files
 */
require_once 'PEAR/REST.php';

/**
 * Implement REST 1.1
 *
 * @category   pear
 * @package    PEAR
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    Release: 1.9.4
 * @link       http://pear.php.net/package/PEAR
 * @since      Class available since Release 1.4.3
 */
class PEAR_REST_11
{
    /**
     * @var PEAR_REST
     */
    var $_rest;

    function PEAR_REST_11($config, $options = array())
    {
        $this->_rest = &new PEAR_REST($config, $options);
    }

    function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
    {
        $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
        if (PEAR::isError($categorylist)) {
            return $categorylist;
        }

        $ret = array();
        if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) {
            $categorylist['c'] = array($categorylist['c']);
        }

        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);

        foreach ($categorylist['c'] as $progress => $category) {
            $category = $category['_content'];
            $packagesinfo = $this->_rest->retrieveData($base .
                'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel);

            if (PEAR::isError($packagesinfo)) {
                continue;
            }

            if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) {
                continue;
            }

            if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) {
                $packagesinfo['pi'] = array($packagesinfo['pi']);
            }

            foreach ($packagesinfo['pi'] as $packageinfo) {
                if (empty($packageinfo)) {
                    continue;
                }

                $info     = $packageinfo['p'];
                $package  = $info['n'];
                $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false;
                unset($latest);
                unset($unstable);
                unset($stable);
                unset($state);

                if ($releases) {
                    if (!isset($releases['r'][0])) {
                        $releases['r'] = array($releases['r']);
                    }

                    foreach ($releases['r'] as $release) {
                        if (!isset($latest)) {
                            if ($dostable && $release['s'] == 'stable') {
                                $latest = $release['v'];
                                $state = 'stable';
                            }
                            if (!$dostable) {
                                $latest = $release['v'];
                                $state = $release['s'];
                            }
                        }

                        if (!isset($stable) && $release['s'] == 'stable') {
                            $stable = $release['v'];
                            if (!isset($unstable)) {
                                $unstable = $stable;
                            }
                        }

                        if (!isset($unstable) && $release['s'] != 'stable') {
                            $unstable = $release['v'];
                            $state = $release['s'];
                        }

                        if (isset($latest) && !isset($state)) {
                            $state = $release['s'];
                        }

                        if (isset($latest) && isset($stable) && isset($unstable)) {
                            break;
                        }
                    }
                }

                if ($basic) { // remote-list command
                    if (!isset($latest)) {
                        $latest = false;
                    }

                    if ($dostable) {
                        // $state is not set if there are no releases
                        if (isset($state) && $state == 'stable') {
                            $ret[$package] = array('stable' => $latest);
                        } else {
                            $ret[$package] = array('stable' => '-n/a-');
                        }
                    } else {
                        $ret[$package] = array('stable' => $latest);
                    }

                    continue;
                }

                // list-all command
                if (!isset($unstable)) {
                    $unstable = false;
                    $state = 'stable';
                    if (isset($stable)) {
                        $latest = $unstable = $stable;
                    }
                } else {
                    $latest = $unstable;
                }

                if (!isset($latest)) {
                    $latest = false;
                }

                $deps = array();
                if ($latest && isset($packageinfo['deps'])) {
                    if (!is_array($packageinfo['deps']) ||
                          !isset($packageinfo['deps'][0])
                    ) {
                        $packageinfo['deps'] = array($packageinfo['deps']);
                    }

                    $d = false;
                    foreach ($packageinfo['deps'] as $dep) {
                        if ($dep['v'] == $latest) {
                            $d = unserialize($dep['d']);
                        }
                    }

                    if ($d) {
                        if (isset($d['required'])) {
                            if (!class_exists('PEAR_PackageFile_v2')) {
                                require_once 'PEAR/PackageFile/v2.php';
                            }

                            if (!isset($pf)) {
                                $pf = new PEAR_PackageFile_v2;
                            }

                            $pf->setDeps($d);
                            $tdeps = $pf->getDeps();
                        } else {
                            $tdeps = $d;
                        }

                        foreach ($tdeps as $dep) {
                            if ($dep['type'] !== 'pkg') {
                                continue;
                            }

                            $deps[] = $dep;
                        }
                    }
                }

                $info = array(
                    'stable'      => $latest,
                    'summary'     => $info['s'],
                    'description' => $info['d'],
                    'deps'        => $deps,
                    'category'    => $info['ca']['_content'],
                    'unstable'    => $unstable,
                    'state'       => $state
                );
                $ret[$package] = $info;
            }
        }

        PEAR::popErrorHandling();
        return $ret;
    }

    /**
     * List all categories of a REST server
     *
     * @param string $base base URL of the server
     * @return array of categorynames
     */
    function listCategories($base, $channel = false)
    {
        $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
        if (PEAR::isError($categorylist)) {
            return $categorylist;
        }

        if (!is_array($categorylist) || !isset($categorylist['c'])) {
            return array();
        }

        if (isset($categorylist['c']['_content'])) {
            // only 1 category
            $categorylist['c'] = array($categorylist['c']);
        }

        return $categorylist['c'];
    }

    /**
     * List packages in a category of a REST server
     *
     * @param string $base base URL of the server
     * @param string $category name of the category
     * @param boolean $info also download full package info
     * @return array of packagenames
     */
    function listCategory($base, $category, $info = false, $channel = false)
    {
        if ($info == false) {
            $url = '%s'.'c/%s/packages.xml';
        } else {
            $url = '%s'.'c/%s/packagesinfo.xml';
        }
        $url = sprintf($url,
                    $base,
                    urlencode($category));

        // gives '404 Not Found' error when category doesn't exist
        $packagelist = $this->_rest->retrieveData($url, false, false, $channel);
        if (PEAR::isError($packagelist)) {
            return $packagelist;
        }
        if (!is_array($packagelist)) {
            return array();
        }

        if ($info == false) {
            if (!isset($packagelist['p'])) {
                return array();
            }
            if (!is_array($packagelist['p']) ||
                !isset($packagelist['p'][0])) { // only 1 pkg
                $packagelist = array($packagelist['p']);
            } else {
                $packagelist = $packagelist['p'];
            }
            return $packagelist;
        }

        // info == true
        if (!isset($packagelist['pi'])) {
            return array();
        }

        if (!is_array($packagelist['pi']) ||
            !isset($packagelist['pi'][0])) { // only 1 pkg
            $packagelist_pre = array($packagelist['pi']);
        } else {
            $packagelist_pre = $packagelist['pi'];
        }

        $packagelist = array();
        foreach ($packagelist_pre as $i => $item) {
            // compatibility with r/<latest.txt>.xml
            if (isset($item['a']['r'][0])) {
                // multiple releases
                $item['p']['v'] = $item['a']['r'][0]['v'];
                $item['p']['st'] = $item['a']['r'][0]['s'];
            } elseif (isset($item['a'])) {
                // first and only release
                $item['p']['v'] = $item['a']['r']['v'];
                $item['p']['st'] = $item['a']['r']['s'];
            }

            $packagelist[$i] = array('attribs' => $item['p']['r'],
                                     '_content' => $item['p']['n'],
                                     'info' => $item['p']);
        }

        return $packagelist;
    }

    /**
     * Return an array containing all of the states that are more stable than
     * or equal to the passed in state
     *
     * @param string Release state
     * @param boolean Determines whether to include $state in the list
     * @return false|array False if $state is not a valid release state
     */
    function betterStates($state, $include = false)
    {
        static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
        $i = array_search($state, $states);
        if ($i === false) {
            return false;
        }
        if ($include) {
            $i--;
        }
        return array_slice($states, $i + 1);
    }
}
?>


<?php

namespace QCharts\ApiBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use QCharts\CoreBundle\Exception\InstanceNotFoundException;
use QCharts\CoreBundle\Exception\UserRoleException;

/**
 * Class UserController
 * @package QCharts\ApiBundle\Controller
 */
class UserController extends Controller
{
    /**
     * ApiDoc(
     *      description = "Returns the users and the information",
     *      parameters = {
     *          {
     *              "name" = "developer",
     *              "dataType" = "boolean",
     *              "required" = false,
     *              "description" = "Returns the users with the given role, not given returns all users"
     *          },
     *          {
     *              "name" = "_format",
     *              "dataType" = "string",
     *              "required" = false,
     *              "description" = "The response is by the requested format, options: json or xml"
     *          }
     *      },
     *      statusCodes = {
     *          200 = "Success",
     *          404 = "No users with the given query was found"
     *      }
     * )
     * @param Request $request
     * @return JsonResponse
     */
    public function getUsersAction(Request $request)
    {
        $authChecker = $this->get("security.authorization_checker");

        $roles = $this->getParameter('qcharts.user_roles');

        if (!$authChecker->isGranted($roles["super_admin"]))
        {
            return new JsonResponse(ApiController::getNotValidCredentials());
        }

        $userService = $this->get("qcharts.user_service");
        try
        {
            $role = $request->query->get('developer', null);
            $encoding = $request->query->get('_format', 'json');

            $userService->setEncoding($encoding);
            $userService->setRole($role);
            $users = $userService->getDetails($this->getUser());

            $response = new Response($users);
            $response->headers->set('Content-Type', "application/{$userService->getEncoding()}");
            return $response;
        }
        catch(InstanceNotFoundException $e)
        {
            return new JsonResponse([
                "status"=>$e->getCode(),
                "text"=>$e->getMessage()
            ]);
        }
    }

    /**
     * ApiDoc(
     *      description = "Promotes the given User with username",
     *      parameters = {
     *          {
     *              "name" = "username",
     *              "dataType" = "string",
     *              "required" = true,
     *              "description" = "Username to promote"
     *          }
     *      },
     *      statusCodes = {
     *          200 = "Success",
     *          201 = "Promotion was added",
     *          404 = "No users with the given query was found",
     *          500 = ""
     *      }
     * )
     * @param Request $request
     * @return JsonResponse
     */
    public function promoteAction(Request $request)
    {
        $authChecker = $this->get("security.authorization_checker");
        $roles = $this->getParameter('qcharts.user_roles');

        if (!$authChecker->isGranted($roles["super_admin"]))
        {
            return new JsonResponse(ApiController::getNotValidCredentials());
        }

        $options = [];
        try
        {
            $username = $request->request->get('username');
            $userService = $this->get("qcharts.user_service");
            $userService->promoteUser($username);
            $options = [
                "status" => 201,
                "textStatus"=>"User was successfully promoted"
            ];
        }
        catch (InstanceNotFoundException $e)
        {
            $options = [
                "status"=>$e->getCode(),
                "textStatus"=>$e->getMessage(),
            ];
        }
        catch (UserRoleException $e)
        {
            $options = [
                "status"=>$e->getCode(),
                "textStatus"=>$e->getMessage(),
            ];
        }
        finally
        {
            return new JsonResponse($options);
        }
    }

    /**
     *
     * ApiDoc(
     *      description = "Demotes the given User with username",
     *      parameters = {
     *          {
     *              "name" = "username",
     *              "dataType" = "string",
     *              "required" = true,
     *              "description" = "Username to demote"
     *          }
     *      },
     *      statusCodes = {
     *          200 = "Success",
     *          404 = "No users with the given query was found",
     *          405 = "User does not had the given role",
     *          500 = ""
     *      }
     * )
     * @param Request $request
     * @return JsonResponse
     */
    public function demoteAction(Request $request)
    {
        $authChecker = $this->get("security.authorization_checker");
        $roles = $this->getParameter('qcharts.user_roles');

        if (!$authChecker->isGranted($roles["super_admin"]))
        {
            return new JsonResponse(ApiController::getNotValidCredentials());
        }

        $options = [];
        $username = $request->request->get("username");
        try
        {
            $userService = $this->get("qcharts.user_service");
            $userService->demoteUser($username);
            $options = [
                "status" => 200,
                "textStatus"=>"User was successfully demoted",
                "username"=>$username
            ];
        }
        catch (InstanceNotFoundException $e)
        {
            $options = [
                "status"=>$e->getCode(),
                "textStatus"=>$e->getMessage(),
                "username"=>$username
            ];
        }
        catch (UserRoleException $e)
        {
            $options = [
                "status"=>$e->getCode(),
                "textStatus"=>$e->getMessage()
            ];
        }
        finally
        {
            return new JsonResponse($options);
        }
    }
}


<?php

namespace Ballen\Executioner;

/**
 * Executioner Process Execution Library
 * Executioner is a PHP library for executing system processes
 * and applications with the ability to pass extra arguments and read
 *  CLI output results.
 *
 * @author     Bobby Allen <ballen@bobbyallen.me>
 * @package    Ballen\Executioner
 * @license    http://opensource.org/licenses/MIT
 * @link       https://github.com/allebb/executioner
 */
use Ballen\Collection\Collection;

class Executioner
{

    /**
     * The full system path to the application/process you want to exectute.
     *
     * @var string
     */
    private $applicationPath;

    /**
     * Stores application arguments to be parsed with the application.
     *
     * @var Collection
     */
    private $applicationArguments;

    /**
     * Stores the CLI response.
     *
     * @var Collection
     */
    private $executionResponse;

    /**
     * Stores the CLI execution errors.
     *
     * @var Collection
     */
    private $executionErrors;

    /**
     * Execute the command using sudo?
     *
     * @var boolean
     */
    private $sudo = false;

    /**
     * Redirect stderr to stdout?
     *
     * @var boolean
     */
    private $stdError = false;

    /**
     * Executioner constructor.
     */
    public function __construct()
    {
        $this->applicationArguments = new Collection();
        $this->executionResponse = new Collection();
        $this->executionErrors = new Collection();
    }

    /**
     * Optional way to create new instance
     *
     * @param string $application The command to run.
     * @return Executioner
     */
    public static function make($application)
    {
        return (new Executioner())->setApplication($application);
    }

    /**
     * Adds an argument to be added to the execution string.
     *
     * @param string $argument
     * @return Executioner
     */
    public function addArgument($argument)
    {
        $this->applicationArguments->push($argument);
        return $this;
    }

    /**
     * Sets the application and path of which to be executed.
     *
     * @param string $application The full system path to the application to execute.
     * @return Executioner
     */
    public function setApplication($application)
    {
        $this->applicationPath = $application;
        return $this;
    }

    /**
     * Retrieves the compiled command.
     *
     * @return string
     */
    public function getCommand()
    {
        return $this->compileCommand();
    }

    /**
     * Compiles the command that will be executed
     *
     * @return string
     */
    private function compileCommand()
    {
        $command = '';

        if ($this->sudo) {
            $command = 'sudo ';
        }
        $command .= escapeshellcmd($this->applicationPath) . $this->generateArguments();
        if ($this->stdError) {
            $command .= ' 2>&1';
        }
        return $command;
    }

    /**
     * Generates a list of arguments to be appended onto the executed path.
     *
     * @return string The generated list of arguments.
     */
    protected function generateArguments()
    {
        $arguments = '';
        if (!$this->applicationArguments->isEmpty()) {
            $arguments = ' ' . $this->applicationArguments->implode();
        }
        return $arguments;
    }

    /**
     * Ensure that the process is called with 'sudo' (*NIX systems only)
     *
     * @param bool $enabled Enable (or disable) sudo.
     * @return Executioner
     */
    public function sudo($enabled = true)
    {
        $this->sudo = $enabled;
        return $this;
    }

    /**
     * Enable stderr redirection to stdout.
     *
     * @param boolean $enabled Enable (or disable) redirection to std.
     * @return Executioner
     */
    public function stderr($enabled = true)
    {
        $this->stdError = $enabled;
        return $this;
    }

    /**
     * Executes the process.
     *
     * @return array
     * @throws Exceptions\ExecutionException
     */
    private function executeProcess()
    {
        $command = $this->compileCommand();
        exec($command, $result, $status);
        if ($status > 0) {
            throw new Exceptions\ExecutionException('Unknown error occurred when attempting to execute: ' . $command . PHP_EOL);
        }
        return $result;
    }

    /**
     * Executes the application with configured arguments.
     *
     * @return Executioner
     * @throws Exceptions\ExecutionException
     */
    public function execute()
    {
        $this->executionResponse->reset()->push($this->executeProcess());
        return $this;
    }

    /**
     * Checks if the application/process is executable.
     *
     * @return boolean
     */
    protected function isExecutable()
    {
        return is_executable($this->applicationPath);
    }

    /**
     * Returns an array of class error messages.
     *
     * @return Collection Collection of error messages.
     */
    public function getErrors()
    {
        return $this->executionErrors;
    }

    /**
     * Returns the result (STDOUT) as an array.
     *
     * @return array Result text (STDOUT).
     */
    public function resultAsArray()
    {
        return $this->executionResponse->all()->toArray();
    }

    /**
     * Returns the result (STDOUT) as a JSON string.
     *
     * @return string Result text (STDOUT).
     */
    public function resultAsJSON()
    {
        return $this->executionResponse->all()->toJson();
    }

    /**
     * Returns the result (STDOUT) as seralized data.
     *
     * @return string Result text (STDOUT).
     */
    public function resultAsSerialized()
    {
        return serialize($this->executionResponse->all()->toArray());
    }

    /**
     * Returns the result (stdout) as a raw text string.
     *
     * @return string Result text (STDOUT).
     */
    public function resultAsText()
    {
        $buffer = '';
        foreach ($this->executionResponse->all()->toArray() as $stdout) {
            $buffer .= $stdout . PHP_EOL;
        }
        return $buffer;
    }
}


<?php

namespace Simples\Console;

use Simples\Helper\Directory;
use Simples\Helper\File;
use Simples\Helper\Text;
use Simples\Kernel\App;

/**
 * Class FileManager
 * @package Simples\Console
 */
class FileManager
{
    /**
     * @var string
     */
    private $namespace;

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

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

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

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

    /**
     * @var string
     */
    private $extension = '.tpl';

    /**
     * @var string
     */
    const LAYER_MODEL = 'model';

    /**
     * @var string
     */
    const LAYER_REPOSITORY = 'repository';

    /**
     * @var string
     */
    const LAYER_CONTROLLER = 'controller';

    /**
     * @var string
     */
    const LAYER_ALL = 'all';

    /**
     * FileManager constructor.
     * @param string $namespace
     * @param string $class
     * @param array $replacements
     */
    public function __construct(string $namespace, string $class, array $replacements)
    {
        $this->namespace = $namespace;
        $this->class = $class;
        $this->replacements = $replacements;
        $this->directory = path(true, App::config('app.src'));

        return $this;
    }

    /**
     * Generate streams of layer(s)
     * @param string $layer (self::LAYER_ALL)
     */
    public function execute(string $layer = 'all')
    {
        switch ($layer) {
            case self::LAYER_ALL:
                $streams = [self::LAYER_MODEL, self::LAYER_REPOSITORY, self::LAYER_CONTROLLER];
                break;
            default:
                $streams = [$layer];
        }

        $this->stream = [];
        foreach ($streams as $stream) {
            $template = dirname(__DIR__, 2) . '/' . TEMPLATE_DIR . '/' . $stream . $this->extension;
            $this->stream[$stream] = File::read($template);
        }

        if ($this->stream && is_array($this->stream)) {
            $this->replace();
            $this->save();
        }
    }

    /**
     * Write the template on disk
     * @return bool
     */
    private function save()
    {
        foreach ($this->stream as $key => $file) {
            $layer = ucwords($key);
            $namespace = Text::replace($this->namespace, '\\', '/');
            $root = Text::replace("{$this->directory}/{$namespace}/{$layer}", '//', '/');

            $success = true;
            if (!Directory::exists($root)) {
                $success = Directory::make($root);
            }
            if (!$success) {
                return false;
            }
            $class = $this->class . (($key !== 'model') ? $layer : '');

            $filename = "{$root}/{$class}.php";

            return !!File::write($filename, $file);
        }
        return false;
    }

    /**
     * Replace values on stream template
     * @return array
     */
    private function replace()
    {
        foreach ($this->stream as &$content) {
            foreach ($this->replacements as $field) {
                $content = Text::replace($content, $field['field'], $field['value']);
            }
        }
        return $this->stream;
    }
}