<?php

// +----------------------------------------------------------------------
// | date: 2015-09-09
// +----------------------------------------------------------------------
// | OssAdapter.php: oss上传
// +----------------------------------------------------------------------
// | Author: yangyifan <yangyifanphp@gmail.com>
// +----------------------------------------------------------------------

namespace Ikodota\Upload\Oss;

use League\Flysystem\Adapter\AbstractAdapter;
use League\Flysystem\Config;
use Yangyifan\Upload\Functions\FileFunction;
use Exception;
use OSS\OssClient;
use OSS\Core\OssException;

class OssAdapter extends  AbstractAdapter
{

    const FILE_TYPE_FILE    = 'file';//类型是文件
    const FILE_TYPE_DIR     = 'dir';//类型是文件夹

    /**
     * 配置信息
     *
     * @var
     */
    protected $config;

    /**
     * oss client 上传对象
     *
     * @var OssClient
     */
    protected $upload;

    /**
     * 构造方法
     *
     * @param $config   配置信息
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function __construct($config)
    {
        $this->config   = $config;
        $this->bucket   = $this->config['bucket'];
        //设置路径前缀
        $this->setPathPrefix($this->config['transport'] . '://' . $this->config['bucket'] . '.' .  $this->config['endpoint']);
    }

    /**
     * 获得OSS client上传对象
     *
     * @return \OSS\OssClient
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    protected function getOss()
    {
        if (!$this->upload) {
            $this->upload = new OssClient(
                $this->config['accessKeyId'],
                $this->config['accessKeySecret'],
                $this->config['endpoint'],
                $this->config['isCName'],
                $this->config['securityToken']
            );

            //设置请求超时时间
            $this->upload->setTimeout($this->config['timeout']);

            //设置连接超时时间
            $this->upload->setConnectTimeout($this->config['connectTimeout']);
        }

        return $this->upload;
    }

    /**
     * 组合路径
     *
     * @param $path
     * @return string
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    protected function mergePath($path)
    {
        return trim($path, '/') . '/';
    }

    /**
     * 判断文件是否存在
     *
     * @param string $path
     * @return bool
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function has($path)
    {
        try {
            return $this->getOss()->doesObjectExist($this->bucket, $path) != false ? true : false;
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 读取文件
     *
     * @param $file_name
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function read($path)
    {
        try {
            return ['contents' => $this->getOss()->getObject($this->bucket, $path) ];
        }catch (OssException $e){

        }
        return false;

    }

    /**
     * 获得文件流
     *
     * @param string $path
     * @return array
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function readStream($path)
    {
        try {
            //获得一个临时文件
            $tmpfname       = FileFunction::getTmpFile();

            file_put_contents($tmpfname, $this->read($path)['contents'] );

            $handle         = fopen($tmpfname, 'r');

            //删除临时文件
            FileFunction::deleteTmpFile($tmpfname);

            return ['stream' => $handle];
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 写入文件
     *
     * @param $file_name
     * @param $contents
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function write($path, $contents, Config $config)
    {
        try {
            $this->getOss()->putObject($this->bucket, $path, $contents, $option = []);

            return true;
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 写入文件流
     *
     * @param string $path
     * @param resource $resource
     * @param array $config
     */
    public function writeStream($path, $resource, Config $config)
    {
        try{
            //获得一个临时文件
            $tmpfname       = FileFunction::getTmpFile();

            file_put_contents($tmpfname, $resource );

            $this->getOss()->uploadFile($this->bucket, $path, $tmpfname, $option = []);

            //删除临时文件
            FileFunction::deleteTmpFile($tmpfname);

            fclose($resource);

            return true;
        }
        catch (OssException $e){

        }
        return false;
    }

    /**
     * 更新文件
     *
     * @param string $path
     * @param string $contents
     * @param array $config
     */
    public function update($path, $contents, Config $config)
    {
        return $this->write($path, $contents, $config);
    }

    /**
     * 更新文件流
     *
     * @param string $path
     * @param resource $resource
     * @param array $config
     */
    public function updateStream($path, $resource, Config $config)
    {
        return $this->writeStream($path, $resource, $config);
    }

    /**
     * 列出目录文件
     *
     * @param string $directory
     * @param bool|false $recursive
     * @return array
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function listContents($directory = '', $recursive = false)
    {
        try{
            $directory = $directory == '' || $directory == '/' ? '' : $this->mergePath($directory);

            $options = [
                'delimiter' => '/' ,
                'prefix'    => $directory,
                'max-keys'  => $this->config['max_keys'],
                'marker'    => '',
            ];

            $result_obj = $this->getOss()->listObjects($this->bucket, $options);

            $file_list  = $result_obj->getObjectList();//文件列表
            $dir_list   = $result_obj->getPrefixList();//文件夹列表
            $data       = [];

            if (is_array($dir_list) && count($dir_list) > 0 ) {
                foreach ($dir_list as $key => $dir) {
                    $data[] = [
                        'path'      => $dir->getPrefix(),
                        'prefix'    => $options['prefix'],
                        'marker'    => $options['marker'],
                        'file_type' => self::FILE_TYPE_DIR
                    ];
                }
            }

            if (is_array($file_list) && count($file_list) > 0 ) {
                foreach ($file_list as $key => $file) {
                    if ($key == 0 ) {
                        $data[] = [
                            'path'      => $file->getKey(),
                            'prefix'    => $options['prefix'],
                            'marker'    => $options['marker'],
                            'file_type' => self::FILE_TYPE_DIR
                        ];
                    } else {
                        $data[] = [
                            'path'              => $file->getKey(),
                            'last_modified'     => $file->getLastModified(),
                            'e_tag'             => $file->getETag(),
                            'file_size'         => $file->getSize(),
                            'prefix'            => $options['prefix'],
                            'marker'            => $options['marker'],
                            'file_type'         => self::FILE_TYPE_FILE,
                        ];
                    }
                }
            }

            return $data;
        }catch (Exception $e){

        }
        return [];
    }

    /**
     * 获取资源的元信息，但不返回文件内容
     *
     * @param $path
     * @return array
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getMetadata($path)
    {
        try {
            $file_info = $this->getOss()->getObjectMeta($this->bucket, $path);
            if ( !empty($file_info) ) {
                return $file_info;
            }
        }catch (OssException $e) {

        }
        return false;
    }

    /**
     * 获得文件大小
     *
     * @param string $path
     * @return int
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getSize($path)
    {
        $file_info = $this->getMetadata($path);
        return $file_info != false && $file_info['content-length'] > 0 ? [ 'size' => $file_info['content-length'] ] : false;
    }

    /**
     * 获得文件Mime类型
     *
     * @param string $path
     * @return mixed string|null
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getMimetype($path)
    {
        $file_info = $this->getMetadata($path);
        return $file_info != false && !empty($file_info['content-type']) ? [ 'mimetype' => $file_info['content-type'] ] : false;
    }

    /**
     * 获得文件最后修改时间
     *
     * @param string $path
     * @return int 时间戳
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getTimestamp($path)
    {
        $file_info = $this->getMetadata($path);
        return $file_info != false && !empty($file_info['last-modified']) ? ['timestamp' => strtotime($file_info['last-modified']) ] : false;
    }

    /**
     * 获得文件模式 (未实现)
     *
     * @param string $path
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getVisibility($path)
    {
        return self::VISIBILITY_PUBLIC;
    }

    /**
     * 重命名文件
     *
     * @param $oldname
     * @param $newname
     * @return boolean
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function rename($path, $newpath)
    {
        try {
            /**
             * 如果是一个资源，请保持最后不是以“/”结尾！
             *
             */
            $path = rtrim($this->mergePath($path), '/');

            $this->getOss()->copyObject($this->bucket, $path, $this->bucket, rtrim($this->mergePath($newpath), '/'), []);
            $this->delete($path);
            return true;
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 复制文件
     *
     * @param $path
     * @param $newpath
     * @return boolean
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function copy($path, $newpath)
    {
        try {
            $this->getOss()->copyObject($this->bucket, $path, $this->bucket, $newpath, []);
            return true;
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 删除文件或者文件夹
     *
     * @param $path
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function delete($path)
    {
        try{
            $this->getOss()->deleteObject($this->bucket, $path);
            return true;
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 删除文件夹
     *
     * @param string $path
     * @return mixed
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function deleteDir($path)
    {
        try{
            //递归去删除全部文件
            $this->recursiveDelete($path);

            return true;
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 递归删除全部文件
     *
     * @param $path
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    protected function recursiveDelete($path)
    {
        $file_list = $this->listContents(rtrim($path, '/'));
        //如果当前文件夹文件不为空,则直接去删除文件夹
        if ( is_array($file_list) && count($file_list) > 0 ) {
            foreach ($file_list as $file) {
                if ($file['path'] == $path) {
                    continue;
                }
                if ($file['file_type'] == self::FILE_TYPE_FILE) {
                    $this->delete($file['path']);
                } else {
                    $this->recursiveDelete($file['path']);
                }
            }
        }
        $this->getOss()->deleteObject($this->bucket, $path);
    }

    /**
     * 创建文件夹
     *
     * @param string $dirname
     * @param array $config
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function createDir($dirname, Config $config)
    {
        try{
            $this->getOss()->createObjectDir($this->bucket, $dirname);
            return true;
        }catch (OssException $e){

        }
        return false;
    }

    /**
     * 设置文件模式 (未实现)
     *
     * @param string $path
     * @param string $visibility
     * @return bool
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function setVisibility($path, $visibility)
    {
        return true;
    }

}


<?php
/**
 * Class LogOutputAbstract
 *
 * @filesource   LogOutputAbstract.php
 * @created      04.01.2018
 * @package      chillerlan\Logger\Output
 * @author       Smiley <smiley@chillerlan.net>
 * @copyright    2018 Smiley
 * @license      MIT
 */

namespace chillerlan\Logger\Output;

use chillerlan\Logger\LogOptions;
use chillerlan\Settings\SettingsContainerInterface;

/**
 *
 */
abstract class LogOutputAbstract implements LogOutputInterface{

	/**
	 * @var \chillerlan\Logger\LogOptions
	 */
	protected $options;

	/**
	 * LogOutputAbstract constructor.
	 *
	 * @param \chillerlan\Settings\SettingsContainerInterface|null $options
	 */
	public function __construct(SettingsContainerInterface $options = null){
		$this->options = $options ?? new LogOptions;
	}

	/**
	 * @inheritdoc
	 */
	public function __destruct(){
		$this->close();
	}

	/**
	 * @inheritdoc
	 */
	public function close():LogOutputInterface{
		return $this;
	}

	/**
	 * @param string $level
	 * @param string $message
	 * @param array  $context
	 *
	 * @return mixed
	 */
	abstract protected function __log(string $level, string $message, array $context = []);

	/**
	 * @inheritdoc
	 */
	public function log(string $level, string $message, array $context = []){ // @todo: loglevel bitmask
		if((array_key_exists($level, $this::LEVELS) && $this::LEVELS[$level] >= $this::LEVELS[$this->options->minLogLevel]) || (!array_key_exists($level, $this::LEVELS) && !empty($level))){
			$this->__log($level, $message, $context);
		}
	}

	/**
	 * @param string     $level
	 * @param string     $message
	 * @param array|null $context
	 *
	 * @return string
	 */
	protected function message(string $level, string $message, array $context = null){
		return sprintf($this->options->consoleFormat, date($this->options->consoleDateFormat), $level, $message).PHP_EOL;
	}

}


<?php

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

class CreateQueueTable extends Migration {

    /**
     * Name of queue table.
     *
     * @var string
     */
    protected $table;

    /**
     * Initialize the migration instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->table = \Illuminate\Support\Facades\
            Config::get('queue.connections.mysql.table', 'queue');
    }

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
        /**
         * Since L4 doesn't support specifying collation for tables/text fields,
         * An empty table (only contains ID) is created first.
         */
        Schema::create($this->table, function($table)
        {
            $table->bigIncrements('ID');
        });

        /**
         * Table collation is specified with raw MySQL SQL statement.
         */
        $table_w_prefix = DB::getTablePrefix() . $this->table;
        DB::statement("ALTER TABLE `{$table_w_prefix}`
            DEFAULT CHARACTER SET ascii COLLATE ascii_general_ci;");

        /**
         * ... Then all the actual data fields are added.
         */
        Schema::table($this->table, function($table)
		{
		    $table->string('queue_name');
            $table->enum('status', ['deleted', 'pending', 'running']);
		    $table->integer('attempts')->unsigned();
		    $table->longText('payload');
		    $table->bigInteger('fireon');
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::dropIfExists($this->table);
	}

}


<?php

namespace Simples\Model;

use Simples\Data\Record;
use Simples\Error\SimplesRunTimeError;
use Simples\Kernel\Container;
use Simples\Model\Resource\ModelAggregation;
use Simples\Model\Resource\ModelHook;
use Simples\Model\Resource\ModelParser;
use Simples\Model\Resource\ModelTimestamp;
use Simples\Model\Resource\ModelPivot;
use Simples\Persistence\Field;

/**
 * Class AbstractModel
 * @package Simples\Model
 * @codingStandardsIgnoreStart
 */
abstract class ModelAbstract extends ModelContract
{
    /**
     * @trait ModelHook, ModelParser, ModelTimestamp, ModelAggregation, ModelPivot
     */
    use ModelHook, ModelParser, ModelTimestamp, ModelAggregation, ModelPivot;

    /**
     * Connection id
     * @var string
     */
    protected $connection;

    /**
     * Data source name
     * @var string
     */
    private $collection = '';

    /**
     * Collections parents created by extends
     * @var array
     */
    private $parents = [];

    /**
     * Collections parents created by extends
     * @var array
     */
    private $relationships = [];

    /**
     * Fields of model
     * @var array
     */
    protected $fields = [];

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

    /**
     * Key used to relationships and to represent the primary key database
     * @var string
     */
    private $primaryKey = '';

    /**
     * Field with a unique hash what can be used to find a record and can be
     * created by client
     * @var string
     */
    protected $hashKey = '_id';

    /**
     * Used to determine the order of reads
     * @var string
     */
    protected $order = '';

    /**
     * Fields to persist the creation object
     * @var array
     */
    protected $createKeys = [
        'at' => '_created_at',
        'by' => '_created_by'
    ];

    /**
     * Fields to persist details about the update
     * @var array
     */
    protected $updateKeys = [
        'at' => '_changed_at',
        'by' => '_changed_by'
    ];

    /**
     * Fields to persist details about the destroy
     * @var array
     */
    protected $destroyKeys = [
        'at' => '_destroyed_at',
        'by' => '_destroyed_by'
    ];

    /**
     * Field registered in Auth with the user logged in
     * @var string
     */
    protected $by = 'user';

    /**
     * Value to be used with unknown access
     * @var string
     */
    protected $visitor = 'visitor';

    /**
     * @codingStandardsIgnoreEnd
     * AbstractModel constructor to configure a new instance
     * @param string $connection (null)
     */
    public function __construct($connection = null)
    {
        parent::__construct($this->connection($connection));
    }

    /**
     * Configure the instance with reference properties
     * @param string $collection
     * @param string $primaryKey ('id')
     * @param string $relationship ('')
     * @return $this
     * @throws SimplesRunTimeError
     */
    protected function configure(string $collection, string $primaryKey = 'id', string $relationship = '')
    {
        if ($relationship) {
            $reference = get_parent_class($this);
            $call = 'construct';
            if (method_exists($reference, $call)) {
                $reference::$call();
            }
        }

        if ($this->collection) {
            $this->parents[$relationship] = clone $this;
            $this->add($relationship)->integer()->collection($collection)->update(false);
            if (!$relationship) {
                throw new SimplesRunTimeError("When extending one model you need give a name to relationship");
            }
        }
        $this->collection = $collection;
        $this->primaryKey = $primaryKey;

        $this->add($this->hashKey)->hashKey();
        foreach ([$this->destroyKeys, $this->createKeys, $this->updateKeys] as $keys) {
            foreach ($keys as $key => $name) {
                $this->add($name)->type($this->getTimestampType($key))->recover(false);
            }
        }
        $this->add($primaryKey)->primaryKey();

        return $this;
    }

    /**
     * @return $this
     */
    public static function instance()
    {
        return Container::instance()->make(static::class);
    }

    /**
     * Parse the connection name and choose a source to it
     * @param $connection
     * @return string
     * @throws SimplesRunTimeError
     */
    private function connection($connection): string
    {
        $this->connection = !is_null($connection) ? $connection : env('DEFAULT_DATABASE');
        if (!$this->connection) {
            throw new SimplesRunTimeError(
                "There is no `connection` to be used. Check .env file or configure the model property"
            );
        }
        return $this->connection;
    }

    /**
     * Recycle a destroyed record
     * @param array|Record $record (null)
     * @return Record
     */
    abstract public function recycle($record = null): Record;

    /**
     * Get total of records based on filters
     * @param Record $record
     * @return int
     */
    abstract public function count(Record $record): int;

    /**
     * @param string $name
     * @param string $type
     * @param array $options
     * @return Field
     */
    protected function add(string $name, string $type = '', array $options = []): Field
    {
        $field = new Field($this->collection, $name, $type, $options);
        $this->fields[$name] = $field;

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

    /**
     * Allow use this field like readonly in read filtering and getting it in record
     * @param string $name
     * @param string $relationship
     * @param array $options
     * @return Field
     * @throws SimplesRunTimeError
     */
    protected function import(string $name, string $relationship, array $options = []): Field
    {
        $source = $this->get($relationship);
        $reference = $source->getReferences();

        $class = off($reference, 'class');
        if (!class_exists($class)) {
            throw new SimplesRunTimeError("Cant not import '{$name}' from '{$class}'");
        }

        /** @var DataMapper $class */
        $import = $class::instance()->get($name);

        $options = array_merge($import->getOptions(), $options);

        $from = new Field($import->getCollection(), $name, $import->getType(), $options);
        $this->fields[$name] = $from->from($source);

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

    /**
     * @param string $name
     * @param string $relationship
     * @param string $target
     * @param array $operations (['*'])
     * @param string $local (null)
     */
    protected function pivot(
        string $name,
        string $relationship,
        string $target,
        array $operations = ['*'],
        string $local = null
    ) {
        $this->add($name)->array()->readonly();
        $this->relationships[] = [
            'operations' => $operations,
            'type' => 'pivot',
            'local' => $local ? $local : $this->getPrimaryKey(),
            'source' => $name,
            'relationship' => $relationship,
            'target' => $target,
        ];
    }

    /**
     * @param string $name
     * @return Field
     */
    final public function get(string $name): Field
    {
        return off($this->fields, $name);
    }

    /**
     * @param string $name
     * @return bool
     */
    final public function has(string $name): bool
    {
        return isset($this->fields[$name]);
    }

    /**
     * @param string $source
     * @param string $target
     */
    public function map(string $source, string $target)
    {
        $this->maps[$source] = $target;
    }

    /**;
     *
     * @param string $action
     * @param bool $strict
     * @return array
     */
    final public function getFields(string $action = '', bool $strict = true): array
    {
        $methods = [
            Action::CREATE => 'isCreate',
            Action::READ => 'isRead',
            Action::UPDATE => 'isUpdate',
            Action::RECOVER => 'isRecover',
        ];
        $method = off($methods, $action, '');

        return $this->filterFields($this->getCollection(), $method, $strict);
    }

    /**
     * @return string
     */
    final public function hashKey(): string
    {
        return uniqid();
    }

    /**
     * @return array
     */
    final public function getParents(): array
    {
        return $this->parents;
    }

    /**
     * @return string
     */
    final public function getCollection(): string
    {
        return $this->collection;
    }

    /**
     * @return array
     */
    final public function getRelationships(): array
    {
        return $this->relationships;
    }

    /**
     * @return string
     */
    final public function getPrimaryKey(): string
    {
        return $this->primaryKey;
    }

    /**
     * @return string
     */
    final public function getHashKey(): string
    {
        return $this->hashKey;
    }
}


<?php
/*
 * This file is part of the Invite Wsapi Library
 *
 * (c) Invite Networks Inc. <info@invitenetworks.com>
 *
 * For the full copyright and license information,
 * please view the LICENSE file that was distributed
 * with this source code.
 */
namespace Invite\Component\Cisco\Wsapi\Client;

use Invite\Component\Cisco\Wsapi\Exception\SoapTimeoutException;

/**
 * INVITE Cisco IOS WS API Soap Client
 *
 * @category   API
 * @author     Josh Whiting <josh@invitenetworks.com>
 * @version    Release: @package_version@
 * @since      Class available since Release 1.1.0
 */
class WsApiClient extends \SoapClient
{

    /**
     * Cisco UC Gateway API Provider namespace injected from calling method.
     *
     * @var type
     */
    protected $namespace;

    /**
     * Override SOAP client then call.
     *
     * Had to get creative with this one. The controller must have the added
     * "namespace" var, then take it out and call the SOAP Client parent.
     *
     * @param type $wsdl
     * @param type $options
     * @param type $namespace
     */
    function __construct($wsdl, $options, $namespace)
    {
        parent::__construct($wsdl, $options);
        $this->namespace = $namespace;
    }

    /**
     * Override PHP SOAP Client __doRequest call to regex Cisco UC Gateway API XML data.
     *
     * NOTE: Leave the SOAP debug commands because they intercept the call better here.
     */
    function __doRequest($request, $location, $action, $version, $oneWay = 0)
    {
        $request1 = preg_replace('/<ns1:(\w+)/', '<$1 xmlns="' . $this->namespace . '"', $request, 1);
        $request2 = preg_replace('/<ns1:(\w+)/', '<$1', $request1);
        $request3 = str_replace(array('/ns1:', 'xmlns:ns1="' . $this->namespace . '"'), array('/', ''), $request2);

        $response = parent::__doRequest($request3, $location, $action, $version, $oneWay = 0);

        // *************** SOAP DEBUG COMMANDS **************
        //
        // --note: trace must be set to true on client request.
        //
        // echo "REQUEST HEADERS:\n
" . parent::__getLastRequestHeaders() . "\n
";
        // echo "REQUEST:\n
" . parent::__getLastRequest() . "\n
";
        // echo "RESPONSE HEADERS:\n
" . parent::__getLastResponseHeaders() . "\n
";
        // echo "RESPONSE:\n
" . parent::__getLastResponse() . "\n
";
        // var_dump(parent::__getFunctions());
        //
        // *************************************************

        return ($response);
    }

    public function __soapCall($function_name, $arguments, $options = NULL, $input_headers = NULL, &$output_headers = NULL)
    {
        $timeStart = microtime(true);
        try {
            $result = parent::__soapCall($function_name, $arguments, $options = NULL, $input_headers = NULL, $output_headers = NULL);
        } catch (\Exception $e) {
            $timeRequest = (microtime(true) - $timeStart);
            if (
                    $e->getMessage() == 'Error Fetching http headers' &&
                    ini_get('default_socket_timeout') < $timeRequest
            ) {
                throw new SoapTimeoutException(
                'Soap request most likly timed out.' .
                ' It took ' . $timeRequest .
                ' and the limit is ' . ini_get('default_socket_timeout')
                );
            }

            // E: Not a timeout, rethrow the original exception
            throw $e;
        }

        // No exception from the service or PHP
        return $result;
    }

}


<?php namespace Potter\Utils\Form\Fields;

use HtmlObject\Element;
use HtmlObject\Traits\Tag;
use Illuminate\Support\Collection;
use Potter\Utils\Form\Traits\Field;

class Select extends Tag
{
    use Field {
        Field::render as realRender;
    }

    protected $element = 'select';

    /**
     * @var null|string|array
     */
    protected $selected;

    /**
     * @var Collection
     */
    protected $choices;

    public function __construct($type, $name = null, $selected = null, $attributes = array())
    {
        $this->selected = $selected;
        $this->choices  = new Collection();

        if (isset($attributes['choices'])):
            $this->parseChoices($attributes['choices']);

            unset($attributes['choices']);
        endif;

        if ($type == 'multi-select'):
            $attributes['multiple'] = true;

            $name .= '[]';
        endif;

        $attributes['name'] = $name;

        array_forget($attributes, ['value', 'type']);

        $this->setTag('select', null, $attributes);
    }

    /**
     * @param $value
     *
     * @return $this
     */
    public function setSelected($value)
    {
        $this->selected = $value;

        return $this;
    }

    /**
     * @param array $choices
     *
     * @return $this
     */
    public function parseChoices(array $choices)
    {
        foreach ($choices as $value => $choice):
            $this->addChoice($choice, $value);
        endforeach;

        return $this;
    }

    /**
     * @param string|array $_choice
     * @param string       $_value
     *
     * @return $this
     */
    public function addChoice($_choice, $_value = null)
    {
        if (is_array($_choice)):
            $text  = array_get($_choice, 'label');
            $value = array_get($_choice, 'value');
            $atts  = array_except($_choice, ['label']);
        else:
            $text  = $_choice;
            $value = (is_null($_value)) ? $_choice : $_value;
            $atts  = ['value' => $value];
        endif;

        $choice = Element::create('option', $text);
        $choice->setAttributes($atts);

        if ($this->isSelected($value)) $choice->setAttribute('selected', 'selected');

        $this->choices->push($choice);

        return $this;
    }

    /**
     * @param $value
     *
     * @return bool
     */
    protected function isSelected($value)
    {
        if (is_array($this->selected)):
            return in_array($value, $this->selected);
        endif;

        return $this->selected == $value;
    }

    /**
     * @return string
     */
    public function render()
    {
        $value = $this->choices->all();

        $this->setValue($value);

        return $this->realRender();
    }

}


<?php
namespace elnebuloso\Flex\Converter;

/**
 * Class NamespaceClassnameToPath
 *
 * @author Jeff Tunessen <jeff.tunessen@gmail.com>
 */
class NamespaceClassnameToPath
{
    /**
     * convert namespaced classname to path
     *
     * @param string $string
     * @return string
     */
    public function convert($string)
    {
        $parts = [];

        foreach (explode('\\', trim($string, '\\')) as $name) {
            $name = strtolower(preg_replace('/([a-z])([A-Z])/', '$1-$2', $name));
            $parts[] = $name;
        }

        return implode('/', $parts);
    }
}


<?php namespace Shamiao\L4mysqlqueue\Queue\Jobs;

use Closure;
use Exception;
use DateTime;
use Carbon\Carbon;
use Illuminate\Container\Container;
use Illuminate\Support\Facades\DB;
use Illuminate\Queue\Jobs\Job;

class MysqlJob extends Job {

    /**
     * Name of queue table.
     *
     * @var string
     */
    protected $table;

    /**
     * Database id of the job.
     *
     * @var int
     */
    protected $id;

    /**
     * Full database record values of the job.
     *
     * @var array
     */
    protected $record;

    /**
     * The class name of the job.
     *
     * @var string
     */
    protected $job;

    /**
     * Raw data parameter of the job.
     *
     * @var mixed
     */
    protected $data;

    /**
     * Create a new job instance.
     *
     * @param  \Illuminate\Container\Container  $container
     * @param  int  $id
     * @param  \stdClass|null  $record
     * @return void
     */
    public function __construct(Container $container, $id, $record = null)
    {
        $this->table = \Illuminate\Support\Facades\
            Config::get('queue.connections.mysql.table', 'queue');

        $this->container = $container;
        $this->id = $id;
        if ($record === null) {
            $this->record = get_object_vars(DB::table($this->table)->find($id));
        } else { $this->record = get_object_vars($record); }

        $this->queue = $this->record['queue_name'];
        $payload_raw = json_decode($this->record['payload'], true);
        $this->job = $payload_raw['job'];
        $this->data = $payload_raw['data'];

        unset($this->deleted); // get rid of this fxxking property
    }

    /**
     * Fire the job.
     *
     * @return void
     */
    public function fire()
    {
        $this->record['attempts'] += 1;
        $this->record['status'] = 'running';
        DB::table($this->table)->where('ID', $this->id)->update([
            'attempts' => $this->record['attempts'],
            'status' => $this->record['status'],
        ]);

        $this->resolveAndFire(array('job' => $this->job, 'data' => $this->data));

        /**
         * Auto delete is implemented.
         * However, WTF is this AUTO DELETE ???
         * None of laravel builtin Job class implements it,
         * nor any document mentions it.
         */
        if ($this->autoDelete()) { $this->delete(); return; }

        /**
         * Auto release if job was not explicitly deleted/released.
         */
        if ($this->record['status'] == 'running') { $this->release(); }
    }

    /**
     * Release the job back into the queue.
     *
     * @param  int   $delay
     * @return void
     */
    public function release($delay = 0)
    {
        $this->record['status'] = 'pending';
        $this->record['fireon'] = Carbon::now()->addSeconds($delay)->getTimestamp();
        DB::table($this->table)->where('ID', $this->id)->update([
            'status' => $this->record['status'],
            'fireon' => $this->record['fireon'],
        ]);
    }

    /**
     * Get the number of times the job has been attempted.
     *
     * @return int
     */
    public function attempts()
    {
        return $this->record['attempts'];
    }

    /**
     * Get the raw body string for the job.
     *
     * @return string
     */
    public function getRawBody()
    {
        return $this->record['payload'];
    }

    /**
     * Delete the job from the queue.
     *
     * @return void
     */
    public function delete()
    {
        $this->record['status'] = 'deleted';
        DB::table($this->table)->where('ID', $this->id)->update([
            'status' => $this->record['status'],
        ]);
    }

    /**
     * Determine if the job has been deleted.
     *
     * @return bool
     */
    public function isDeleted()
    {
        return $this->record['status'] == 'deleted' ? true : false;
    }

    /**
     * Get the job identifier.
     *
     * @return int
     */
    public function getJobId()
    {
        return $this->id;
    }

}


<?php
namespace Zf2FileUploader\Filter\Thumbnail;

use Imagine\Image\BoxInterface;

class PathFilterFactory implements PathFilterFactoryInterface
{
    /**
     * @param array | BoxInterface $data
     *
     * @throws \Zf2FileUploader\Filter\Thumbnail\Exception\InvalidArgumentException
     * @return PathFilter
     */
    public function getPathFilter($data)
    {
        if ($data instanceof BoxInterface) {
            $width = $data->getWidth();
            $height = $data->getHeight();
        } else if (func_num_args() > 1) {
            list($width, $height) = func_get_args();
        } else if ((is_array($data) && array_key_exists('width', $data) && array_key_exists('height', $data)) ||
                   preg_match('/^(?P<width>[0-9]+)x(?P<height>[0-9]+)$/', $data, $data)) {
            $width = $data['width'];
            $height = $data['height'];
        } else {
            throw new Exception\InvalidArgumentException("Could not retrieve width and height from data");
        }

        return new PathFilter($width, $height);
    }
}


<?php
namespace Zf2FileUploader\View\Strategy;

use Zend\View\Renderer\RendererInterface;
use Zf2FileUploader\View\Model\UploaderModelInterface;
use Zf2FileUploader\View\Renderer\FactoryRenderer;
use Zf2Libs\View\Strategy\UploaderStrategy as BaseUploaderStrategy;
use Zend\View\ViewEvent;

class UploaderStrategy extends BaseUploaderStrategy
{
    /**
     * @var FactoryRenderer
     */
    protected $rendererFactory;

    /**
     * Constructor
     *
     * @param  FactoryRenderer $rendererFactory
     */
    public function __construct(FactoryRenderer $rendererFactory)
    {
        $this->rendererFactory = $rendererFactory;
    }

    /**
     * Detect if we should use the UploaderRenderer based on model type and/or
     * Accept header
     *
     * @param  ViewEvent $e
     * @return null | RendererInterface
     */
    public function selectRenderer(ViewEvent $e)
    {
        $model = $e->getModel();

        if (!$model instanceof UploaderModelInterface) {
            return null;
        }

        $this->renderer = $this->rendererFactory
                               ->createRenderer($e->getRequest()
                                                  ->getQuery());

        // JsonModel found
        return $this->renderer;
    }
}


<?php namespace Impleri\Toolbox\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\File;

/**
 * Toolbox Routes Command
 */
class RoutesCommand extends Command
{
    /**
     * The console command name.
     * @var string
     */
    protected $name = 'toolbox:routes';

    /**
     * The console command description.
     * @var string
     */
    protected $description = 'Append the default Confide controller routes to the routes.php';

    /**
     * Execute the console command.
     */
    public function fire()
    {
        $this->line('');
        $this->info('Routes file: app/routes.php');

        $message = 'This will rebuild routes.php with all of the packages that'
            . ' subscribe to the `toolbox.routes` event.';
        $this->comment($message);
        $this->line('');

        if ($this->confirm('Proceed with the rebuild? [Yes|no]')) {
            $this->line('');

            $this->info('Backing up routes.php ...');
            // Remove the last backup if it exists
            if (File::exists('app/routes.bak.php')) {
                File::delete('app/routes.bak.php');
            }

            // Back up the existing file
            if (File::exists('app/routes.php')) {
                File::move('app/routes.php', 'app/routes.bak.php');
            }

            // Generate new routes
            $this->info('Generating routes...');
            $routes = Event::fire('toolbox.routes');

            // Save new file
            $this->info('Saving new routes.php...');
            if ($routes && !empty($routes)) {
                $routes = $this->getHeader() . implode("\n", $routes);
                File::put('app/routes.php', $routes);
                $this->info('Process completed!');
            } else {
                $this->error('Nothing to save!');
            }

            // Done!
            $this->line('');
        }
    }

    /**
     * Get Header
     *
     * Provide the header for routes.php
     * @return string Routes.php header
     */
    private function getHeader()
    {
        return "<?php \n/**\n * Application Routes\n * \n * This file is auto-generated by toolbox. Don't forget to re-edit this of/when you regenerate it.\n */\n\n";
    }
}


<?php namespace Potter\Taxonomy;

use Illuminate\Support\Str;
use Potter\Post\Type;

class Create
{

   /**
    * @var string
    */
   protected $name;

   /**
    * @var string
    */
   protected $singular;

   /**
    * @var string
    */
   protected $plural;
   /**
    * @var string
    */
   protected $route;

   /**
    * @var bool
    */
   protected $hierarchical = false;

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

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

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

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

   /**
    * @param string $name
    * @param string $singular
    * @param string $plural
    * @param string $hierarchical
    * @param array  $args
    * @param bool   $autoRegister
    */
   public function __construct($name = null, $singular = null, $plural = null, $hierarchical = null, $args = [], $autoRegister = true)
   {
      $this->setTaxName($name);
      $this->setSingular($singular);
      $this->setPlural($plural);

      if (is_bool($hierarchical)) $this->hierarchical = (bool)$hierarchical;

      $this->setArgs($args);

      if ($autoRegister) add_action('init', array($this, 'registerTaxonomy'));
   }

   /**
    * @param $name
    *
    * @return $this
    */
   public function setTaxName($name)
   {
      if (!empty($name)) $this->name = $name;

      if (empty($this->name)):
         $class      = get_class($this);
         $this->name = str_replace('Tax', '', $class);
         $this->name = str_replace('Taxonomy', '', $this->name);
         $this->name = Str::snake($this->name);
      endif;

      return $this;
   }

   /**
    * @param $singular
    *
    * @return $this
    */
   public function setSingular($singular)
   {
      if (!empty($singular)) $this->singular = $singular;

      if (empty($this->singular)) $this->singular = Str::title($this->name);

      return $this;
   }

   /**
    * @param $plural
    *
    * @return $this
    */
   public function setPlural($plural)
   {
      if (!empty($plural)) $this->plural = $plural;

      if (empty($this->plural)) $this->plural = Str::plural($this->singular);

      return $this;
   }

   /**
    * @param array $customizations
    *
    * @return $this
    */
   public function setArgs($customizations = array())
   {
      $defaults = [
         'label'        => $this->plural,
         'labels'       => $this->getLabels(),
         'hierarchical' => $this->hierarchical,
      ];

      if (!empty($this->route)):
         $defaults['rewrite'] = ['slug' => $this->route, 'with_front' => true];
      endif;

      $defaults = wp_parse_args($customizations, $defaults);

      $this->args = wp_parse_args($this->args, $defaults);

      return $this;
   }

   /**
    * @param array|string|Type $post_types
    *
    * @return $this
    */
   public function assignPostType($post_types)
   {
      if (!is_array($post_types)) $post_types = [$post_types];

      foreach ($post_types as &$post_type):
         if ($post_type instanceof Type) $post_type = $post_type->getPostType();
      endforeach;

      $this->post_types = array_merge($this->post_types, $post_types);

      return $this;
   }

   /**
    * @return array
    */
   protected function getLabels()
   {
      $labels = [
         'name'                       => __($this->plural),
         'singular_name'              => __($this->singular),
         'search_items'               => __('Search') . ' ' . $this->plural,
         'popular_items'              => __('Popular') . ' ' . $this->plural,
         'all_items'                  => __('All') . ' ' . $this->plural,
         'parent_item'                => __('Parent') . ' ' . $this->singular,
         'parent_item_colon'          => __('Parent') . ' ' . $this->singular . ':',
         'edit_item'                  => __('Edit') . ' ' . $this->singular,
         'update_item'                => __('Update') . ' ' . $this->singular,
         'add_new_item'               => __('Add') . ' ' . $this->singular,
         'new_item_name'              => __('New') . ' ' . $this->singular . ' Name',
         'separate_items_with_commas' => __('Separate') . ' ' . strtolower($this->plural) . ' ' . __('with commas'),
         'add_or_remove_items'        => __('Add or remove') . ' ' . strtolower($this->plural),
         'choose_from_most_used'      => __('Choose from the most used') . ' ' . strtolower($this->plural),
         'menu_name'                  => __($this->plural)
      ];

      return $this->labels = wp_parse_args($this->labels, $labels);
   }

   public function registerTaxonomy()
   {
      register_taxonomy($this->name, $this->post_types, $this->args);
   }
}


<?php
namespace Potter;

use OPT;
use Potter\Post\Query;
use Potter\Post\QueryModel;
use Potter\Theme\Features;
use Potter\Utils\Metabox;

class Potter
{
    /**
     * @var PotterCore
     */
    private static $potter;
    private static $features;

    /**
     * @param PotterCore $potterCore
     * @param Features   $features
     */
    public function __construct(PotterCore $potterCore, Features $features)
    {
        self::$potter = $potterCore;
        self::$features = $features;

        $this->registerWidgets();
    }

    private function registerWidgets()
    {
        $widgets = self::core()->getWidgets()->toArray();
        self::features()->addWidget($widgets);
    }

    /**
     * @return PotterCore
     */
    public static function core()
    {
        return self::$potter;
    }

    /**
     * @param string $name
     *
     * @return QueryModel
     */
    public static function model($name)
    {
        $_PostType = self::core()->getModels()->get($name);

        $query = new QueryModel($_PostType);

        return $query;
    }

    /**
     * @param string $postType
     * @param array  $args
     *
     * @return Query
     */
    public static function query($postType, $args = array())
    {

        $query = new Query($args, $postType);

        return $query;
    }

    /**
     * @return Features
     */
    public static function features()
    {
        return self::$features;
    }

    /**
     * @param array $attributes
     * @param array $fields
     * @param bool  $autoRegister
     *
     * @return Metabox
     */
    public static function makeMetabox(array $attributes, array $fields = array(), $autoRegister = true)
    {
        return new Metabox($attributes, $fields, $autoRegister);
    }

    /**
     * @param string $name
     * @param null   $default
     *
     * @return null|string
     */
    public static function OPT($name, $default = null)
    {
        return OPT::get($name, $default);
    }
}


<?php

/**
 * (c) 2018 Interlutions
 */

namespace App;

/**
 * Class BadConfigurationBag
 *
 * @package App
 * @author Timon F.
 */
class BadConfigurationBag {

    /**
     * @const mixed[]|array default values
     */
    const DEFAULT_CONFIGURATION = array(
        "database_connection" => NULL
    );

    /**
     * @var array
     */
    var $configuration = [];

    /**
     * Constructor
     *
     * @param $configuration
     * @throws \Exception
     */
    function BadConfigurationBag($configuration = array()) {
        if (!is_array($configuration) || empty($configuration)) throw new \Exception("Config missing");

        $this->configuration = array_merge($configuration, self::DEFAULT_CONFIGURATION);
    }

    /**
     * get
     *
     * @param string $configurationKey
     * @return mixed
     */
    public function get($configurationKey) {
        if (!isset($this->configuration[$configurationKey])) {
            var_dump($this->configuration);
            trigger_error("\"$configurationKey\" not set", E_NOTICE);
            return false;
        }

        return($this->configuration[$configurationKey]);
    }

    /**
     * set
     *
     * @param $configurationKey
     * @param $value
     * @return void
     */
    public function set($configurationKey, $value) {
        $this->configuration[$configurationKey] = $value;
    }
}


<?php
namespace Mouf\Doctrine\ORM;

use Doctrine\ORM\EntityManager as DoctrineEntityManager;
use Doctrine\ORM\ORMInvalidArgumentException;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\Configuration;
use Doctrine\Common\EventManager;
use Doctrine\ORM\ORMException;
use Mouf\Validator\MoufValidatorInterface;
use Mouf\Validator\MoufValidatorResult;

/**
 * This is a very simple wrapper around Doctrine's EntityManager that exposes its contructor as "public".
 * This allows calling the constructor directly using Mouf.
 *
 * @author Xavier HUBERTY <x.huberty@gmail.com>
 */
class ResetableEntityManager extends DoctrineEntityManager
{
    private $conn;
    private $config;
    private $eventManager;
    private $entityManager;
    private $entityManagerClassName;

    const ENTITY_MANAGER_CLOSED = "The EntityManager is closed.";

    /**
     * @param Connection $conn
     * @param Configuration $config
     * @param EventManager $eventManager
     * @param EntityManager $entityManager
     * @throws ORMException
     */
    public function __construct(Connection $conn, Configuration $config, EventManager $eventManager, $entityManagerClassName = 'Doctrine\\ORM\\EntityManager')
    {
        $this->conn = $conn;
        $this->config = $config;
        $this->eventManager = $eventManager;
        $this->entityManagerClassName = $entityManagerClassName;
        $this->resetEntityManager();
    }

    /**
     * @return mixed
     */
    public function getEntityManager()
    {
        return $this->entityManager;
    }

    /**
     * {@inheritDoc}
     */
    public function getConnection()
    {
        try{
            return $this->entityManager->getConnection();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Gets the metadata factory used to gather the metadata of classes.
     *
     * @return \Doctrine\ORM\Mapping\ClassMetadataFactory
     */
    public function getMetadataFactory()
    {
        try{
            return $this->entityManager->getMetadataFactory();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getExpressionBuilder()
    {
        try{
            return $this->entityManager->getExpressionBuilder();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function beginTransaction()
    {
        try{
            $this->entityManager->beginTransaction();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getCache()
    {
        try{
            return $this->entityManager->getCache();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function transactional($func)
    {
        try{
            $this->entityManager->transactional($func);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function commit()
    {
        try{
            $this->entityManager->commit();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function rollback()
    {
        try{
            $this->entityManager->rollback();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Returns the ORM metadata descriptor for a class.
     *
     * The class name must be the fully-qualified class name without a leading backslash
     * (as it is returned by get_class($obj)) or an aliased class name.
     *
     * Examples:
     * MyProject\Domain\User
     * sales:PriceRequest
     *
     * Internal note: Performance-sensitive method.
     *
     * @param string $className
     *
     * @return \Doctrine\ORM\Mapping\ClassMetadata
     */
    public function getClassMetadata($className)
    {
        try{
            return $this->entityManager->getClassMetadata($className);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function createQuery($dql = '')
    {
        try{
            return $this->entityManager->createQuery($dql);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function createNamedQuery($name)
    {
        try{
            return $this->entityManager->createNamedQuery($name);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function createNativeQuery($sql, ResultSetMapping $rsm)
    {
        try{
            return $this->entityManager->createNativeQuery($sql, $rsm);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function createNamedNativeQuery($name)
    {
        try{
            return $this->entityManager->createNamedNativeQuery($name);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function createQueryBuilder()
    {
        try{
            return $this->entityManager->createQueryBuilder();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Flushes all changes to objects that have been queued up to now to the database.
     * This effectively synchronizes the in-memory state of managed objects with the
     * database.
     *
     * If an entity is explicitly passed to this method only this entity and
     * the cascade-persist semantics + scheduled inserts/removals are synchronized.
     *
     * @param null|object|array $entity
     *
     * @return void
     *
     * @throws \Doctrine\ORM\OptimisticLockException If a version check on an entity that
     *         makes use of optimistic locking fails.
     */
    public function flush($entity = null)
    {
        try{
            return $this->entityManager->flush($entity);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Finds an Entity by its identifier.
     *
     * @param string       $entityName  The class name of the entity to find.
     * @param mixed        $id          The identity of the entity to find.
     * @param integer|null $lockMode    One of the \Doctrine\DBAL\LockMode::* constants
     *                                  or NULL if no specific lock mode should be used
     *                                  during the search.
     * @param integer|null $lockVersion The version of the entity to find when using
     *                                  optimistic locking.
     *
     * @return object|null The entity instance or NULL if the entity can not be found.
     *
     * @throws OptimisticLockException
     * @throws ORMInvalidArgumentException
     * @throws TransactionRequiredException
     * @throws ORMException
     */
    public function find($entityName, $id, $lockMode = null, $lockVersion = null)
    {
        try{
            return $this->entityManager->find($entityName, $id, $lockMode, $lockVersion);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getReference($entityName, $id)
    {
        try{
            return $this->entityManager->getReference($entityName, $id);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getPartialReference($entityName, $identifier)
    {
        try{
            return $this->entityManager->getPartialReference($entityName, $identifier);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Clears the EntityManager. All entities that are currently managed
     * by this EntityManager become detached.
     *
     * @param string|null $entityName if given, only entities of this type will get detached
     *
     * @return void
     */
    public function clear($entityName = null)
    {
        try{
            return $this->entityManager->clear($entityName);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function close()
    {
        try{
            return $this->entityManager->close();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Tells the EntityManager to make an instance managed and persistent.
     *
     * The entity will be entered into the database at or before transaction
     * commit or as a result of the flush operation.
     *
     * NOTE: The persist operation always considers entities that are not yet known to
     * this EntityManager as NEW. Do not pass detached entities to the persist operation.
     *
     * @param object $entity The instance to make managed and persistent.
     *
     * @return void
     *
     * @throws ORMInvalidArgumentException
     */
    public function persist($entity)
    {
        try{
            return $this->entityManager->persist($entity);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Removes an entity instance.
     *
     * A removed entity will be removed from the database at or before transaction commit
     * or as a result of the flush operation.
     *
     * @param object $entity The entity instance to remove.
     *
     * @return void
     *
     * @throws ORMInvalidArgumentException
     */
    public function remove($entity)
    {
        try{
            return $this->entityManager->remove($entity);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Refreshes the persistent state of an entity from the database,
     * overriding any local changes that have not yet been persisted.
     *
     * @param object $entity The entity to refresh.
     *
     * @return void
     *
     * @throws ORMInvalidArgumentException
     */
    public function refresh($entity)
    {
        try{
            return $this->entityManager->refresh($entity);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Detaches an entity from the EntityManager, causing a managed entity to
     * become detached.  Unflushed changes made to the entity if any
     * (including removal of the entity), will not be synchronized to the database.
     * Entities which previously referenced the detached entity will continue to
     * reference it.
     *
     * @param object $entity The entity to detach.
     *
     * @return void
     *
     * @throws ORMInvalidArgumentException
     */
    public function detach($entity)
    {
        try{
            return $this->entityManager->detach($entity);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Merges the state of a detached entity into the persistence context
     * of this EntityManager and returns the managed copy of the entity.
     * The entity passed to merge will not become associated/managed with this EntityManager.
     *
     * @param object $entity The detached entity to merge into the persistence context.
     *
     * @return object The managed copy of the entity.
     *
     * @throws ORMInvalidArgumentException
     */
    public function merge($entity)
    {
        try{
            return $this->entityManager->merge($entity);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     *
     * @todo Implementation need. This is necessary since $e2 = clone $e1; throws an E_FATAL when access anything on $e:
     * Fatal error: Maximum function nesting level of '100' reached, aborting!
     */
    public function copy($entity, $deep = false)
    {
        try{
            return $this->entityManager->copy($entity, $deep);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function lock($entity, $lockMode, $lockVersion = null)
    {
        try{
            return $this->entityManager->lock($entity, $lockMode, $lockVersion);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Gets the repository for an entity class.
     *
     * @param string $entityName The name of the entity.
     *
     * @return \Doctrine\ORM\EntityRepository The repository class.
     */
    public function getRepository($entityName)
    {
        try{
            return $this->entityManager->getRepository($entityName);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Determines whether an entity instance is managed in this EntityManager.
     *
     * @param object $entity
     *
     * @return boolean TRUE if this EntityManager currently manages the given entity, FALSE otherwise.
     */
    public function contains($entity)
    {
        try{
            return $this->entityManager->contains($entity);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getEventManager()
    {
        return $this->eventManager;
    }

    /**
     * {@inheritDoc}
     */
    public function getConfiguration()
    {
        return $this->config;
    }

    /**
     * {@inheritDoc}
     */
    public function isOpen()
    {
        try{
            return $this->entityManager->isOpen();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getUnitOfWork()
    {
        try{
            return $this->entityManager->getUnitOfWork();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getHydrator($hydrationMode)
    {
        try{
            return $this->entityManager->getHydrator($hydrationMode);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function newHydrator($hydrationMode)
    {
        try{
            return $this->entityManager->newHydrator($hydrationMode);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getProxyFactory()
    {
        try{
            return $this->entityManager->getProxyFactory();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function initializeObject($obj)
    {
        try{
            return $this->entityManager->initializeObject($obj);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * Factory method to create EntityManager instances.
     *
     * @param mixed         $conn         An array with the connection parameters or an existing Connection instance.
     * @param Configuration $config       The Configuration instance to use.
     * @param EventManager  $eventManager The EventManager instance to use.
     *
     * @return EntityManager The created EntityManager.
     *
     * @throws \InvalidArgumentException
     * @throws ORMException
     */
    public static function create($conn, Configuration $config, EventManager $eventManager = null)
    {
        try{
            return self::getEntityManager()->create($conn, $config, $eventManager);
        } catch(ORMException $e) {
            if (!self::getEntityManager()->isOpen()) {
                self::resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getFilters()
    {
        try{
            return $this->entityManager->getFilters();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function isFiltersStateClean()
    {
        try{
            return $this->entityManager->isFiltersStateClean();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    /**
     * {@inheritDoc}
     */
    public function hasFilters()
    {
        try{
            return $this->entityManager->hasFilters();
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                $this->resetEntityManager();
            }
            throw $e;
        }
    }

    protected function resetEntityManager() {
        $entityManagerClassName = $this->entityManagerClassName;
        $this->entityManager = new $entityManagerClassName($this->conn, $this->config, $this->eventManager);
    }

    public function __call($method, $args) {
        try{
            // TODO: check that protected methods are not exposed.
            return call_user_func_array(array($this->entityManager, $method), $args);
        } catch(ORMException $e) {
            if (!$this->entityManager->isOpen()) {
                // Let's reset the entityManager instance if it is closed.
                $this->resetEntityManager();
            }
            throw $e;
        }
    }
}


<?php
namespace Potter\Theme;

class Features
{
    protected $imagesSize   = array();
    protected $menus        = array();
    protected $themeSupport = array();
    protected $postSupport  = array();
    protected $sidebars     = array();
    protected $widgets      = array();
    protected $css          = array();
    protected $js           = array();
    protected $jsEnqueue    = array();
    protected $jQueryCDN
                            = array(
            'cdn_url'   => null,
            'fallback'  => null,
            'migrate'   => null,
            'in_footer' => false,
        );
    protected $customLoginLogo
                            = array(
            'logo_url' => null,
            'style'    => array()
        );

    public static $jQueryCDN_URL       = '//ajax.googleapis.com/ajax/libs/jquery/%1s/jquery.min.js';
    public static $GOOGLE_ANALYTICS_ID = false;
    public static $add_jquery_fallback = false;

    public function __construct()
    {
        add_action('after_setup_theme', array($this, '_after_setup_theme'));

        add_action('widgets_init', array($this, '_widgets_init'));

        add_action('wp_enqueue_scripts', array($this, '_wp_enqueue_scripts'), 100);

        add_action('wp_footer', array($this, '_google_analytics'), 20);

        add_action('login_enqueue_scripts', array($this, '_login_enqueue_scripts'));

    }

    /**
     * @param string $location
     * @param string $description
     *
     * @return $this
     */
    public function addMenu($location, $description)
    {
        $this->menus[$location] = $description;

        return $this;
    }

    /**
     * @param string $name
     * @param int    $width
     * @param int    $height
     * @param bool   $crop
     *
     * @return $this
     */
    public function addImageSize($name, $width = 0, $height = 0, $crop = false)
    {
        $size = array(
            'name'   => $name,
            'width'  => $width,
            'height' => $height,
            'crop'   => $crop
        );

        $this->imagesSize[] = $size;

        return $this;
    }

    /**
     * @param string $feature
     * @param array  $arguments
     *
     * @return $this
     */
    public function addThemeSupport($feature, $arguments = array())
    {
        $this->themeSupport[$feature] = $arguments;

        return $this;
    }

    /**
     * @param string $post_type
     * @param string $feature
     *
     * @return $this
     */
    public function addPostTypeSupport($post_type, $feature)
    {
        $this->postSupport[$post_type] = $feature;

        return $this;
    }

    /**
     * @param array $sidebar
     *
     * @return $this
     */
    public function addSidebar(array $sidebar)
    {
        $this->sidebars[] = $sidebar;

        return $this;
    }

    /**
     * @param string|array $widget
     *
     * @return $this
     */
    public function addWidget($widget)
    {
        if (is_array($widget)):
            $this->widgets = array_merge($this->widgets, $widget);
        else:
            $this->widgets[] = $widget;
        endif;

        return $this;
    }

    /**
     * @param string $handle
     * @param bool   $src
     * @param array  $deps
     * @param null   $ver
     * @param string $media
     *
     * @return $this
     */
    public function addCss($handle, $src = false, $deps = array(), $ver = null, $media = 'all')
    {
        $this->css[] = array(
            'handle' => $handle,
            'src'    => $this->prepUrl($src),
            'deps'   => $deps,
            'ver'    => $ver,
            'media'  => $media
        );

        return $this;
    }

    /**
     * @param string $handle
     * @param string $src
     * @param array  $deps
     * @param bool   $ver
     * @param bool   $in_footer
     *
     * @return $this
     */
    public function addJs($handle, $src, $deps = array(), $ver = null, $in_footer = false)
    {
        $this->js[] = array(
            'handle'    => $handle,
            'src'       => $this->prepUrl($src),
            'deps'      => $deps,
            'ver'       => $ver,
            'in_footer' => $in_footer
        );

        $this->addJsEnqueue($handle);

        return $this;
    }

    /**
     * @param string $handle
     * @param string $src
     * @param array  $deps
     * @param bool   $ver
     *
     * @return $this
     */
    public function addJsToFooter($handle, $src, $deps = array(), $ver = null)
    {
        return $this->addJs($handle, $src, $deps, $ver, true);
    }

    /**
     * @param string $handle
     * @param string $src
     * @param array  $deps
     * @param bool   $ver
     *
     * @return $this
     */
    public function addJsToHead($handle, $src, $deps = array(), $ver = null)
    {
        return $this->addJs($handle, $src, $deps, $ver, null);
    }

    /**
     * @param string $handle
     * @param bool   $src
     * @param array  $deps
     * @param bool   $ver
     * @param bool   $in_footer
     *
     * @return $this
     */
    public function addJsEnqueue($handle, $src = false, $deps = array(), $ver = false, $in_footer = false)
    {
        $this->jsEnqueue[] = array(
            'handle'    => $handle,
            'src'       => $src,
            'deps'      => $deps,
            'ver'       => $ver,
            'in_footer' => $in_footer
        );

        return $this;
    }

    /**
     * @param string $version
     * @param string $fallback
     * @param string $migrate
     * @param bool   $in_footer
     *
     * @return $this
     */
    public function setJqueryCDNSupport($version, $fallback = null, $migrate = null, $in_footer = false)
    {
        $cdnUrl = sprintf(self::$jQueryCDN_URL, $version);

        $this->jQueryCDN['cdn_url'] = $cdnUrl;
        $this->jQueryCDN['fallback'] = ($fallback) ? $this->prepUrl($fallback) : null;
        $this->jQueryCDN['migrate'] = ($migrate) ? $this->prepUrl($migrate) : null;
        $this->jQueryCDN['in_footer'] = $in_footer;

        return $this;
    }

    /**
     * @param string $id
     *
     * @return $this
     */
    public function setGoogleAnalytcsID($id)
    {
        self::$GOOGLE_ANALYTICS_ID = $id;

        return $this;
    }

    /**
     * @param string $logo
     * @param array  $style
     *
     * @return $this
     */
    public function setLoginLogo($logo, $style = array())
    {
        $this->customLoginLogo['logo_url'] = $this->prepUrl($logo);
        $this->customLoginLogo['style'] = $style;

        return $this;
    }

    public function _google_analytics()
    {
        $GOOGLE_ANALYTICS_ID = self::$GOOGLE_ANALYTICS_ID;

        if (!empty($GOOGLE_ANALYTICS_ID)) {
            echo <<< EOT
<script>
	(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
	function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
	e=o.createElement(i);r=o.getElementsByTagName(i)[0];
	e.src='//www.google-analytics.com/analytics.js';
	r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
	ga('create','{$GOOGLE_ANALYTICS_ID}');ga('send','pageview');
</script>
EOT;
        }
    }

    public function _after_setup_theme()
    {
        // Menus
        foreach ($this->menus as $location => $description):
            register_nav_menu($location, $description);
        endforeach;

        // Images
        foreach ($this->imagesSize as $size):
            add_image_size($size['name'], $size['width'], $size['height'], $size['crop']);
        endforeach;

        // Theme Support
        foreach ($this->themeSupport as $feature => $args):
            if (empty($args)):
                add_theme_support($feature);
            else:
                add_theme_support($feature, $args);
            endif;
        endforeach;

        // Post Type Support
        foreach ($this->postSupport as $post_type => $feature):
            add_post_type_support($post_type, $feature);
        endforeach;
    }

    public function _widgets_init()
    {
        foreach ($this->widgets as $widget):
            register_widget($widget);
        endforeach;

        foreach ($this->sidebars as $sidebar):
            register_sidebar($sidebar);
        endforeach;
    }

    public function _wp_enqueue_scripts()
    {
        // jQueryCDN
        if (!empty($this->jQueryCDN['cdn_url'])):
            $jquery_in_footer = $this->jQueryCDN['in_footer'];
            wp_deregister_script('jquery');
            wp_register_script('jquery', $this->jQueryCDN['cdn_url'], false, null, $jquery_in_footer);
            wp_enqueue_script('jquery');

            // Fallback
            if (!empty($this->jQueryCDN['fallback'])):
                add_filter('script_loader_src', array($this, '_jquery_local_fallback'), 10, 2);
            endif;

            // Migrate
            if (!empty($this->jQueryCDN['migrate'])):
                wp_register_script('jquery-migrate', $this->jQueryCDN['migrate'], false, null, $jquery_in_footer);
                wp_enqueue_script('jquery-migrate');
            endif;
        endif;

        //CSS
        foreach ($this->css as $css):
            wp_enqueue_style($css['handle'], $css['src'], $css['deps'], $css['ver'], $css['media']);
        endforeach;
        //JS
        foreach ($this->js as $js):
            wp_register_script($js['handle'], $js['src'], $js['deps'], $js['ver'], $js['in_footer']);
        endforeach;
        //JS Enqueue
        foreach ($this->jsEnqueue as $enqueue):
            wp_enqueue_script(
                $enqueue['handle'],
                $enqueue['src'],
                $enqueue['deps'],
                $enqueue['ver'],
                $enqueue['in_footer']
            );
        endforeach;
    }

    public function _login_enqueue_scripts()
    {
        if (!empty($this->customLoginLogo['logo_url'])):
            $logo = $this->customLoginLogo['logo_url'];
            $style = $this->customLoginLogo['style'];

            $output = array('<style> body.login div#login h1 a{ background-image: url(' . $logo . '); ');
            foreach ($style as $key => $value):
                $output[] = "{$key}: {$value}; ";
            endforeach;
            $output[] = '} </style>';

            echo implode('', $output);
        endif;
    }

    public function _jquery_local_fallback($src, $handle = null)
    {
        if (self::$add_jquery_fallback):
            echo '<script>window.jQuery||document.write(\'<script src="' . $this->jQueryCDN['fallback'] .
                '"><\/script>\')</script>' . "\n";
            self::$add_jquery_fallback = false;
        endif;

        if ($handle === 'jquery'):
            self::$add_jquery_fallback = true;
        endif;

        return $src;
    }

    /**
     * @param array $data
     *
     * @return $this
     */
    public function setJsEnqueue(array $data)
    {
        $this->jsEnqueue = array();

        $default = array(
            'src'       => false,
            'deps'      => array(),
            'ver'       => false,
            'in_footer' => false
        );

        if ($this->ArrayIsMulti($data)):
            foreach ($data as $enqueue):
                $this->jsEnqueue[] = wp_parse_args($enqueue, $default);
            endforeach;
        else:
            foreach ($data as $handle):
                $this->jsEnqueue[] = wp_parse_args(array('handle' => $handle), $default);
            endforeach;
        endif;

        return $this;
    }

    /**
     * @param $array
     *
     * @return bool
     */
    private function ArrayIsMulti(array $array)
    {
        foreach ($array as $v) {
            if (is_array($v)) return true;
        }

        return false;
    }

    /**
     * @param string $path
     *
     * @return string
     */
    private function prepUrl($path)
    {
        $info = parse_url($path);

        if (!isset($info['host'])):
            return theme_url($info['path']);
        endif;

        return cleanURI($path);
    }
}


<?php

// +----------------------------------------------------------------------
// | date: 2015-09-09
// +----------------------------------------------------------------------
// | UpyunAdapter.php: 又拍云上传实现
// +----------------------------------------------------------------------
// | Author: yangyifan <yangyifanphp@gmail.com>
// +----------------------------------------------------------------------

namespace Ikodota\Upload\Upyun;

use League\Flysystem\Adapter\AbstractAdapter;
use League\Flysystem\Config;
use Yangyifan\Upload\Functions\FileFunction;
use Exception;

class UpyunAdapter extends  AbstractAdapter
{
    /**
     * 配置信息
     *
     * @var
     */
    protected $config;

    /**
     * upyun上传对象
     *
     * @var UpYun
     */
    protected $upload;

    /**
     *
     * 文件类型
     *
     */
    const FILE_TYPE_FILE    = 'file';//文件类型为文件
    const FILE_TYPE_FOLDER  = 'folder';//文件类型是文件夹

    /**
     * 构造方法
     *
     * @param $config   配置信息
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function __construct($config)
    {
        $this->config   = $config;

        //设置路径前缀
        $this->setPathPrefix($this->config['transport'] . '://' . $this->config['domain']);
    }

    /**
     * 获得Upyun上传对象
     *
     * @return UpYun
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    protected function getUpyun()
    {
        if (!$this->upload) {
            $this->upload = new UpYun(
                $this->config['bucket'],//空间名称
                $this->config['username'],//用户名
                $this->config['password'],//密码
                $this->config['endpoint'],//线路
                $this->config['timeout']//超时时间
            );
        }
        return $this->upload;
    }

    /**
     * 重写组合upyun合肥路径
     *
     * @param $path
     * @return string
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    protected function mergePath($path)
    {
        return '/' . trim($path, '/');
    }

    /**
     * 判断文件是否存在
     *
     * @param string $path
     * @return bool
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function has($path)
    {
        return $this->getMetadata($path) != false ? true : false;
    }

    /**
     * 读取文件
     *
     * @param $file_name
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function read($path)
    {
        return ['contents' => file_get_contents($this->applyPathPrefix($path)) ];
    }

    /**
     * 获得文件流
     *
     * @param string $path
     * @return array
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function readStream($path)
    {
        //获得一个临时文件
        $tmpfname       = FileFunction::getTmpFile();

        file_put_contents($tmpfname, file_get_contents($this->applyPathPrefix($path)) );

        $handle = fopen($tmpfname, 'r');

        //删除临时文件
        FileFunction::deleteTmpFile($tmpfname);

        return ['stream' => $handle];
    }

    /**
     * 写入文件
     *
     * @param $file_name
     * @param $contents
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function write($path, $contents, Config $config)
    {
        return $this->getUpyun()->writeFile($this->mergePath($path), $contents, $auto_mkdir = true);
    }

    /**
     * 写入文件流
     *
     * @param string $path
     * @param resource $resource
     * @param array $config
     */
    public function writeStream($path, $resource, Config $config)
    {
        $status = $this->getUpyun()->writeFile($this->mergePath($path), $resource, true);
        fclose($resource);

        return $status;
    }

    /**
     * 更新文件
     *
     * @param string $path
     * @param string $contents
     * @param array $config
     */
    public function update($path, $contents, Config $config)
    {
        return $this->write($path, $contents, $config);
    }

    /**
     * 更新文件流
     *
     * @param string $path
     * @param resource $resource
     * @param array $config
     */
    public function updateStream($path, $resource, Config $config)
    {
        return $this->writeStream($path, $resource, $config);
    }

    /**
     * 列出目录文件
     *
     * @param string $directory
     * @param bool|false $recursive
     * @return array
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function listContents($directory = '', $recursive = false)
    {
        try{
            //组合目录
            $directory  = $this->mergePath($directory);

            $file_list = $this->getUpyun()->getList($directory);

            if (is_array($file_list) && count($file_list) > 0 ) {
                foreach ($file_list as &$file) {
                    $file['path']   = ltrim($directory, '/') . DIRECTORY_SEPARATOR . $file['name'];
                }
            }
            return $file_list;
        }catch (Exception $e){

        }
        return [];
    }

    /**
     * 获取资源的元信息，但不返回文件内容
     *
     * @param $path
     * @return array
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getMetadata($path)
    {
        try {
            $file_info = $this->getUpyun()->getFileInfo($path);
            if ( !empty($file_info) ) {
                return $file_info;
            }
        }catch (Exception $exception){
            //调试信息
            //echo $exception->getMessage();
        }
        return false;
    }

    /**
     * 获得文件大小
     *
     * @param string $path
     * @return int
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getSize($path)
    {
        $file_info = $this->getMetadata($path);
        return $file_info != false && $file_info['x-upyun-file-size'] > 0 ? [ 'size' => $file_info['x-upyun-file-size'] ] : false;
    }

    /**
     * 获得文件Mime类型
     *
     * @param string $path
     * @return mixed string|null
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getMimetype($path)
    {
        //创建一个临时文件
        $tmp_file = FileFunction::getTmpFile();

        file_put_contents($tmp_file, $this->readStream($path)['stream']);

        $mime_type = FileFunction::getFileMimeType($tmp_file);

        //删除临时文件

        FileFunction::deleteTmpFile($tmp_file);

        return ['mimetype' => $mime_type];
    }

    /**
     * 获得文件最后修改时间
     *
     * @param string $path
     * @return int 时间戳
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getTimestamp($path)
    {
        $file_info = $this->getMetadata($path);
        return $file_info != false && !empty($file_info['x-upyun-file-date']) ? ['timestamp' => $file_info['x-upyun-file-date'] ] : false;
    }

    /**
     * 获得文件模式 (未实现)
     *
     * @param string $path
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function getVisibility($path)
    {
        return self::VISIBILITY_PUBLIC;
    }

    /**
     * 重命名文件
     *
     * @param $oldname
     * @param $newname
     * @return boolean
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function rename($path, $newpath)
    {
        $newpath = $this->mergePath($newpath);

        $this->writeStream($newpath, $this->readStream($path)['stream'], new Config() );

        $this->delete($path);

        return true;
    }

    /**
     * 复制文件
     *
     * @param $path
     * @param $newpath
     * @return boolean
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function copy($path, $newpath)
    {
        $this->writeStream($this->mergePath($newpath), $this->readStream($this->mergePath($path))['stream'], new Config() );

        return true;
    }

    /**
     * 删除文件或者文件夹
     *
     * @param $path
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function delete($path)
    {
        return $this->getUpyun()->delete($this->mergePath($path));
    }

    /**
     * 删除文件夹
     *
     * @param string $path
     * @return mixed
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function deleteDir($path)
    {
        if ( $this->has($path) ) {
            //递归删除全部子文件
            $this->recursiveDeleteDir($path);
            return true;
        }
        return false;
    }

    /**
     * 递归删除全部文件夹
     *
     * @param $path
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    protected function recursiveDeleteDir($path)
    {
        $path = $this->mergePath($path);
        $file_list = $this->listContents($path);

        if ( is_array($file_list) && count($file_list) > 0 ) {
            foreach ($file_list as $file) {
                //如果是文件，则把文件删除
                if ($file['type'] == self::FILE_TYPE_FILE) {
                    $this->delete($path . $this->pathSeparator . $file['name']);
                } else {
                    $this->recursiveDeleteDir($path . $this->pathSeparator . $file['name']);
                }
            }
        }
        $this->getUpyun()->rmDir($path);
    }

    /**
     * 创建文件夹
     *
     * @param string $dirname
     * @param array $config
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function createDir($dirname, Config $config)
    {
        $this->getUpyun()->makeDir($this->mergePath($dirname));
        return true;
    }

    /**
     * 设置文件模式 (未实现)
     *
     * @param string $path
     * @param string $visibility
     * @return bool
     * @author yangyifan <yangyifanphp@gmail.com>
     */
    public function setVisibility($path, $visibility)
    {
        return true;
    }

}


<?php
/*
 * This file is part of the Invite Wsapi Library
 *
 * (c) Invite Networks Inc. <info@invitenetworks.com>
 *
 * For the full copyright and license information,
 * please view the LICENSE file that was distributed
 * with this source code.
 */
namespace Invite\Component\Cisco\Wsapi\Server;

use Invite\Component\Cisco\Wsapi\Model\XcdrListenerInterface;
use Invite\Component\Cisco\Wsapi\Request\XcdrRequest;

/**
 * XcdrServer
 *
 * Process all Wsapi Xcdr SOAP Requests.
 *
 * @author Josh Whiting <josh@invitenetworks.com>
 */
class WsapiServer
{

    /**
     * Xcdr Soap Webservice method.
     */
    public function processXcdr(XcdrListenerInterface $listener, array$options = array())
    {
        $xcdrRequest = new XcdrRequest($listener, $options);
        $schema = $xcdrRequest->getSchema();

        ini_set("soap.wsdl_cache_enabled", "0");

        $soapServer = new \SoapServer(null, array(
            'uri' => $schema,
            'soap_version' => SOAP_1_2,
        ));

        $soapServer->setObject($xcdrRequest);

        try {
            ob_start();
            $soapServer->handle();
        } catch (\Exception $e) {
            return array(
                'status' => 'error',
                'type' => 'soap_fault',
                'code' => $e->getCode(),
                'message' => $e->getMessage(),
                'class' => get_class($this)
            );
        }

        $result = $this->filterResponse(ob_get_clean(), $schema, 'xcdr');

        return array(
            'status' => 'success',
            'result' => $result
        );
    }

    protected function filterResponse($result, $schema, $type)
    {
        $result1 = preg_replace('/<ns1:(\w+)/', '<$1 xmlns="' . $schema . '"', $result, 1);
        $result2 = preg_replace('/<\/ns1:(\w+)/', '</$1', $result1);
        $result3 = preg_replace('/<rpc:result.*rpc:result>/', '', $result2);
        $result4 = preg_replace('/Solicit' . ucfirst($type) . 'ProbingResponse/', 'Response' . ucfirst($type) . 'Probing', $result3);
        $result5 = preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $result4);
        $result6 = preg_replace('/<env:Envelope(?s).*<env:Body(?s).*soap-rpc">/', '<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Header/><soapenv:Body>', $result5);
        $result7 = preg_replace('/<\/env:Envelope>/', '</soapenv:Envelope>', $result6);
        $result8 = preg_replace('/<\/env:Body>/', '</soapenv:Body>', $result7);
        $result9 = preg_replace('/\senv:encodingStyle.*soap-encoding"/', '', $result8);
        $result10 = preg_replace('/Solicit' . ucfirst($type) . 'ProviderUnRegisterResponse/', 'Response' . ucfirst($type) . 'ProviderUnRegister', $result9);

        return $result10;
    }

}