├── tests ├── _output │ └── .gitignore ├── _data │ └── dump.sql ├── unit │ ├── bootstrap.php │ ├── _bootstrap.php │ ├── AmqpTest.php │ ├── RedisTest.php │ ├── _config.amqp.php │ ├── _config.mysql.php │ ├── _config.redis.php │ ├── MysqlTest.php │ ├── BaseTestClass.php │ └── UnitTester.php ├── docker-test.sh ├── unit.suite.yml ├── _support │ └── UnitHelper.php └── _bootstrap.php ├── .gitignore ├── Exception.php ├── transports ├── Exception.php ├── Transport.php ├── AsyncRedisTransport.php ├── AsyncMysqlTransport.php └── AsyncAmqpTransport.php ├── test.sh ├── models ├── AsyncTask.php └── AsyncExecuteTask.php ├── docker-compose.yml ├── Dockerfile ├── codeception.yml ├── CHANGELOG.md ├── migrations └── m160401_090723_async.php ├── .travis.yml ├── LICENSE ├── composer.json ├── AsyncComponent.php ├── commands └── AsyncWorkerCommand.php ├── README.md └── composer.lock /tests/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | 4 | composer.phar 5 | vendor/ -------------------------------------------------------------------------------- /tests/_data/dump.sql: -------------------------------------------------------------------------------- 1 | /* Replace this file with actual dump of your database */ -------------------------------------------------------------------------------- /tests/unit/bootstrap.php: -------------------------------------------------------------------------------- 1 | redis->executeCommand('FLUSHDB'); 12 | } 13 | } -------------------------------------------------------------------------------- /tests/_bootstrap.php: -------------------------------------------------------------------------------- 1 | > /usr/local/etc/php/conf.d/amqp.ini 7 | 8 | ADD . /var/code 9 | 10 | CMD /var/code/tests/docker-test.sh -------------------------------------------------------------------------------- /codeception.yml: -------------------------------------------------------------------------------- 1 | actor: Tester 2 | paths: 3 | tests: tests 4 | log: tests/_output 5 | data: tests/_data 6 | helpers: tests/_support 7 | settings: 8 | bootstrap: _bootstrap.php 9 | suite_class: \PHPUnit_Framework_TestSuite 10 | colors: true 11 | memory_limit: 1024M 12 | modules: 13 | # config: 14 | # Db: 15 | # dsn: '' 16 | # user: '' 17 | # password: '' 18 | # dump: tests/_data/dump.sql 19 | -------------------------------------------------------------------------------- /tests/unit/_config.amqp.php: -------------------------------------------------------------------------------- 1 | 'test', 6 | 'basePath' => dirname(__DIR__), 7 | 'components' => [ 8 | 'async' => [ 9 | 'class' => 'bazilio\async\AsyncComponent', 10 | 'transportConfig' => [ 11 | 'host' => $host, 12 | 'vhost' => '/', 13 | 'exchangeName' => 'test' 14 | ] 15 | ] 16 | ] 17 | 18 | ]; -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 0.2.0 2 | ===== 3 | - Mysql transport support 4 | 5 | 0.0.5 6 | ===== 7 | - [Fix first message send in AMQP provider + travis ci](https://github.com/bazilio91/yii2-async/commit/961fc05bf4776509074c062f944124fe090e1b6f) 8 | 9 | 0.0.4 10 | ===== 11 | - [ExecuteAsyncTask instance support & arguments type hinting](https://github.com/bazilio91/yii2-async/commit/c20494322dae6ac588690ba7479cdc10fcc8ee2e) 12 | 13 | 0.0.3 14 | ===== 15 | - [sleep for AsyncExecuteTask, redis queue names fix](https://github.com/bazilio91/yii2-async/commit/7798da55d69658cfdee63cdbee92e1d430d96f8c) 16 | 17 | 0.0.2 18 | ===== 19 | - [Redis provider](https://github.com/bazilio91/yii2-async/commit/0e0caf108a7eee6062e979c6dd022dc717859558) -------------------------------------------------------------------------------- /tests/unit/_config.mysql.php: -------------------------------------------------------------------------------- 1 | 'test', 6 | 'basePath' => dirname(__DIR__), 7 | 'components' => [ 8 | 'db' => [ 9 | 'class' => 'yii\db\Connection', 10 | 'dsn' => "mysql:host=$host;dbname=async-test", 11 | 'username' => 'root', 12 | 'password' => '', 13 | 'charset' => 'utf8', 14 | ], 15 | 'async' => [ 16 | 'class' => 'bazilio\async\AsyncComponent', 17 | 'transportClass' => 'bazilio\async\transports\AsyncMysqlTransport', 18 | 'transportConfig' => [ 19 | 'connection' => 'db', 20 | ] 21 | ] 22 | ] 23 | 24 | ]; -------------------------------------------------------------------------------- /tests/unit/_config.redis.php: -------------------------------------------------------------------------------- 1 | 'test', 6 | 'basePath' => dirname(__DIR__), 7 | 'components' => [ 8 | 'redis' => [ 9 | 'class' => 'yii\redis\Connection', 10 | 'hostname' => $host, 11 | 'port' => 6379, 12 | 'database' => 5, 13 | 'connectionTimeout' => 1, 14 | 'dataTimeout' => 1, 15 | ], 16 | 'async' => [ 17 | 'class' => 'bazilio\async\AsyncComponent', 18 | 'transportClass' => 'bazilio\async\transports\AsyncRedisTransport', 19 | 'transportConfig' => [ 20 | 'connection' => 'redis', 21 | ] 22 | ], 23 | ] 24 | 25 | ]; -------------------------------------------------------------------------------- /tests/unit/MysqlTest.php: -------------------------------------------------------------------------------- 1 | migrationPath = '@tests/../migrations'; 18 | $migrateController->runAction('up', ['interactive' => 0]); 19 | 20 | self::$migrated = true; 21 | } 22 | 23 | public function loadFixtures($fixtures = null) 24 | { 25 | $this->migrate(); 26 | parent::loadFixtures($fixtures); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /migrations/m160401_090723_async.php: -------------------------------------------------------------------------------- 1 | createTable( 10 | '{{%async}}', 11 | [ 12 | 'id' => 'pk', 13 | 'data' => 'longblob', 14 | 'status' => 'int(1) UNSIGNED DEFAULT 0', 15 | 'queue' => 'varchar(255) NOT NULL' 16 | ] 17 | ); 18 | 19 | $this->createIndex('queue', '{{%async}}', 'queue'); 20 | $this->createIndex('queue_status', '{{%async}}', ['queue', 'status']); 21 | } 22 | 23 | public function down() 24 | { 25 | $this->dropIndex('queue', '{{%async}}'); 26 | $this->dropIndex('queue_status', '{{%async}}'); 27 | $this->dropTable('{{%async}}'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /transports/Transport.php: -------------------------------------------------------------------------------- 1 | > ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini 37 | # core framework: 38 | - travis_retry composer install --prefer-dist --no-interaction 39 | 40 | before_script: 41 | - mysql -e 'create database `async-test`;' 42 | 43 | script: 44 | - vendor/bin/codecept run 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Vasily Ostanin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bazilio/yii2-async", 3 | "description": "Provides translucent api for moving large tasks out of request context", 4 | "license": "MIT", 5 | "type": "yii2-extension", 6 | "authors": [ 7 | { 8 | "name": "Vasily Ostanin", 9 | "email": "bazilio91@gmail.com" 10 | } 11 | ], 12 | "minimum-stability": "alpha", 13 | "keywords": ["yii2", "async", "amqp", "rabbitmq", "tasks", "redis", "mysql"], 14 | "require": { 15 | "php": ">=5.4.0", 16 | "yiisoft/yii2": "*" 17 | }, 18 | "require-dev": { 19 | "phpunit/phpunit": "4.6.*", 20 | "yiisoft/yii2-codeception": "*", 21 | "codeception/codeception": "2.0.*", 22 | "pdezwart/php-amqp": "dev-master", 23 | "yiisoft/yii2-redis": "*", 24 | "kriswallsmith/spork": "dev-master" 25 | }, 26 | "autoload": { 27 | "psr-4": { 28 | "bazilio\\async\\": "" 29 | } 30 | }, 31 | "repositories": [{ 32 | "type": "package", 33 | "package": { 34 | "name": "pdezwart/php-amqp", 35 | "version": "dev-master", 36 | "source": { 37 | "url": "https://github.com/pdezwart/php-amqp", 38 | "type": "git", 39 | "reference": "origin/master" 40 | } 41 | } 42 | }] 43 | } 44 | -------------------------------------------------------------------------------- /AsyncComponent.php: -------------------------------------------------------------------------------- 1 | transport = new $this->transportClass($this->transportConfig); 25 | } 26 | 27 | /** 28 | * @param AsyncTask $task 29 | * @return bool|string 30 | * @throws Exception 31 | */ 32 | public function sendTask(AsyncTask $task) 33 | { 34 | if ($task->validate()) { 35 | return $this->transport->send(serialize($task), $task::$queueName); 36 | } else { 37 | throw new Exception(var_export($task->errors, true)); 38 | } 39 | } 40 | 41 | /** 42 | * @param $queueName 43 | * @param bool $wait Wait for task 44 | * @return AsyncTask|bool 45 | */ 46 | public function receiveTask($queueName, $wait = false) 47 | { 48 | return $this->transport->receive($queueName, $wait); 49 | } 50 | 51 | /** 52 | * @param AsyncTask $task 53 | * @return bool 54 | */ 55 | public function acknowledgeTask(AsyncTask $task) 56 | { 57 | return $this->transport->acknowledge($task); 58 | } 59 | 60 | /** 61 | * @param string $queueName 62 | * @return bool 63 | */ 64 | public function purge($queueName) 65 | { 66 | return $this->transport->purge($queueName); 67 | } 68 | 69 | /** 70 | * @return Transport 71 | */ 72 | public function getTransport() 73 | { 74 | return $this->transport; 75 | } 76 | } -------------------------------------------------------------------------------- /commands/AsyncWorkerCommand.php: -------------------------------------------------------------------------------- 1 | handleSignal(); 19 | /** @var AsyncTask $task */ 20 | while ($task = \Yii::$app->async->receiveTask($queueName ?: AsyncTask::$queueName)) { 21 | $this->checkSignal(); 22 | 23 | $this->processTask($task); 24 | 25 | if (($count !== null && !--$count) || $this->checkSignal()) { 26 | break; 27 | } 28 | } 29 | } 30 | 31 | /** 32 | * @param string|null $queueName 33 | * @param int|null $count tasks to process 34 | */ 35 | public function actionDaemon($queueName = null, $count = null) 36 | { 37 | /** @var AsyncTask $task */ 38 | while ($task = \Yii::$app->async->receiveTask($queueName ?: AsyncTask::$queueName, true)) { 39 | $this->handleSignal(); 40 | 41 | $task::$queueName = $queueName ?: AsyncTask::$queueName; 42 | $this->processTask($task); 43 | 44 | if (($count !== null && !--$count) || $this->checkSignal()) { 45 | break; 46 | } 47 | 48 | // we don't want to ignore SIGTERM while waiting for task 49 | $this->removeSignalHandler(); 50 | } 51 | } 52 | 53 | protected function processTask(AsyncTask $task) 54 | { 55 | $task->execute(); 56 | \Yii::$app->async->acknowledgeTask($task); 57 | 58 | } 59 | 60 | private function handleSignal() 61 | { 62 | if (!function_exists('pcntl_signal')) { 63 | return; 64 | } 65 | 66 | pcntl_signal( 67 | SIGTERM, 68 | function ($signo) { 69 | echo "This signal is called. [$signo] \n"; 70 | static::$state = -1; 71 | } 72 | ); 73 | } 74 | 75 | private function removeSignalHandler() 76 | { 77 | if (!function_exists('pcntl_signal')) { 78 | return; 79 | } 80 | 81 | pcntl_signal(SIGTERM, SIG_DFL); 82 | } 83 | 84 | private function checkSignal() 85 | { 86 | if (!function_exists('pcntl_signal')) { 87 | return false; 88 | } 89 | 90 | pcntl_signal_dispatch(); 91 | if (AsyncWorkerCommand::$state == -1) { 92 | return true; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /transports/AsyncRedisTransport.php: -------------------------------------------------------------------------------- 1 | connection = \Yii::$app->{$connectionConfig['connection']}; 22 | } 23 | 24 | public static function getQueueKey($queueName, $progress = false) 25 | { 26 | return "queue:$queueName" . ($progress ? ':progress' : null); 27 | } 28 | 29 | public static function getChannelKey($queueName) 30 | { 31 | return "channel:$queueName"; 32 | } 33 | 34 | /** 35 | * @param string $text 36 | * @param string $queueName 37 | * @return integer index in queue 38 | */ 39 | public function send($text, $queueName) 40 | { 41 | $return = $this->connection->executeCommand('LPUSH', [self::getQueueKey($queueName), $text]); 42 | return $return; 43 | } 44 | 45 | /** 46 | * @param string $queueName 47 | * @param bool $wait Wait for task 48 | * @return AsyncTask|bool 49 | * @throws Exception 50 | */ 51 | public function receive($queueName, $wait = false) 52 | { 53 | $params = [self::getQueueKey($queueName), self::getQueueKey($queueName, true)]; 54 | if ($wait) { 55 | $params[] = 0; 56 | } 57 | $message = $this->connection->executeCommand( 58 | ($wait ? 'BRPOPLPUSH' : 'RPOPLPUSH'), 59 | $params 60 | ); 61 | 62 | if (!$message) { 63 | return false; 64 | } 65 | 66 | if (!is_string($message)) { 67 | throw new Exception('Failed to assert message is a string: ' . var_export($message, true)); 68 | } 69 | 70 | /** 71 | * @var AsyncTask $task 72 | */ 73 | $task = unserialize($message); 74 | $task->message = $message; 75 | return $task; 76 | } 77 | 78 | /** 79 | * @param AsyncTask $task 80 | * @return bool 81 | */ 82 | public function acknowledge(AsyncTask $task) 83 | { 84 | return $this->connection->executeCommand( 85 | 'LREM', 86 | [self::getQueueKey($task::$queueName, true), -1, $task->message] 87 | ) === '1'; 88 | } 89 | 90 | /** 91 | * @param string $queueName 92 | * @return bool 93 | */ 94 | public function purge($queueName) 95 | { 96 | $this->connection->executeCommand('DEL', [self::getQueueKey($queueName)]); 97 | return true; 98 | } 99 | 100 | /** 101 | * @return bool 102 | * @throws Exception 103 | */ 104 | public function disconnect() 105 | { 106 | if ($this->connection) { 107 | $this->connection->close(); 108 | 109 | $this->connection = null; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /transports/AsyncMysqlTransport.php: -------------------------------------------------------------------------------- 1 | connection = \yii\di\Instance::ensure( 26 | \Yii::$app->{$connectionConfig['connection']}, 27 | \yii\db\Connection::className() 28 | ); 29 | } 30 | 31 | public static function getQueueKey($queueName, $progress = false) 32 | { 33 | return "queue:$queueName" . ($progress ? ':progress' : null); 34 | } 35 | 36 | /** 37 | * @param string $text 38 | * @param string $queueName 39 | * @return integer index in queue 40 | */ 41 | public function send($text, $queueName) 42 | { 43 | return $this->connection->createCommand()->insert( 44 | $this->tableName, 45 | [ 46 | 'queue' => self::getQueueKey($queueName), 47 | 'data' => $text, 48 | ] 49 | )->execute() == 1; 50 | } 51 | 52 | /** 53 | * @param string $queueName 54 | * @param bool $wait Wait for task 55 | * @return AsyncTask|bool 56 | * @throws Exception 57 | */ 58 | public function receive($queueName, $wait = false) 59 | { 60 | $transaction = $this->connection->beginTransaction(); 61 | 62 | $message = (new \yii\db\Query()) 63 | ->select('*') 64 | ->from($this->tableName) 65 | ->where(['status' => self::STATUS_NEW, 'queue' => self::getQueueKey($queueName)]) 66 | ->limit(1) 67 | ->one($this->connection); 68 | 69 | if (!$message || $this->connection->createCommand() 70 | ->update( 71 | $this->tableName, 72 | ['status' => self::STATUS_PROGRESS], 73 | [ 74 | 'id' => $message['id'], 75 | 'status' => self::STATUS_NEW, 76 | ] 77 | )->execute() !== 1 78 | ) { 79 | $transaction->rollBack(); 80 | return false; 81 | }; 82 | 83 | $transaction->commit(); 84 | 85 | /** 86 | * @var AsyncTask $task 87 | */ 88 | $task = unserialize($message['data']); 89 | $task->message = $message; 90 | return $task; 91 | } 92 | 93 | /** 94 | * @param AsyncTask $task 95 | * @return bool 96 | */ 97 | public function acknowledge(AsyncTask $task) 98 | { 99 | return $this->connection->createCommand()->delete( 100 | $this->tableName, 101 | [ 102 | 'id' => $task->message['id'], 103 | ] 104 | )->execute() == 1; 105 | } 106 | 107 | /** 108 | * @param string $queueName 109 | * @return bool 110 | */ 111 | public function purge($queueName) 112 | { 113 | $this->connection->createCommand()->delete( 114 | $this->tableName, 115 | [ 116 | 'queue' => $queueName 117 | ] 118 | ); 119 | return true; 120 | } 121 | 122 | /** 123 | * @return bool 124 | * @throws Exception 125 | */ 126 | public function disconnect() 127 | { 128 | if ($this->connection) { 129 | $this->connection->close(); 130 | 131 | $this->connection = null; 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /transports/AsyncAmqpTransport.php: -------------------------------------------------------------------------------- 1 | 'localhost', 29 | 'login' => 'guest', 30 | 'password' => 'guest', 31 | 'vhost' => 'yii', 32 | 'exchangeName' => 'yii' 33 | ]; 34 | 35 | function __construct($connectionConfig) 36 | { 37 | $this->connectionConfig = array_merge($this->connectionConfig, $connectionConfig); 38 | $this->getConnection(); 39 | } 40 | 41 | 42 | private function getConnection() 43 | { 44 | if (!$this->connection || !$this->connection->isConnected()) { 45 | $this->connection = new \AMQPConnection($this->connectionConfig); 46 | try { 47 | $this->connection->connect(); 48 | 49 | if (!$this->connection->isConnected()) { 50 | throw new Exception("Can't initialize connection to amqp server!"); 51 | } 52 | } catch (\AMQPConnectionException $e) { 53 | throw new Exception($e->getMessage()); 54 | } 55 | } 56 | 57 | return $this->connection; 58 | } 59 | 60 | private function getChannel() 61 | { 62 | if (!$this->channel || !$this->channel->isConnected()) { 63 | $this->channel = new \AMQPChannel($this->getConnection()); 64 | } 65 | 66 | return $this->channel; 67 | } 68 | 69 | private function getExchange() 70 | { 71 | if (!$this->exchange) { 72 | $this->exchange = new \AMQPExchange($this->getChannel()); 73 | $this->exchange->setFlags(AMQP_DURABLE); 74 | } 75 | 76 | return $this->exchange; 77 | } 78 | 79 | public function getQueue($queueName) 80 | { 81 | 82 | if (empty($this->queues[$queueName])) { 83 | $queue = new \AMQPQueue($this->getChannel()); 84 | $queue->setName($queueName); 85 | $queue->setFlags(AMQP_DURABLE); 86 | $queue->declareQueue(); 87 | $queue->bind('amq.direct', $this->routingKey); 88 | $this->queues[$queueName] = $queue; 89 | } 90 | 91 | return $this->queues[$queueName]; 92 | } 93 | 94 | /** 95 | * @return bool 96 | * @throws Exception 97 | */ 98 | public function disconnect() 99 | { 100 | if (!$this->connection->disconnect()) { 101 | throw new Exception('Could not disconnect!'); 102 | } 103 | 104 | $this->connection = null; 105 | 106 | return true; 107 | } 108 | 109 | /** 110 | * @param string $text 111 | * @param string $queueName 112 | * @throws Exception 113 | * @return bool|string false or message_id 114 | */ 115 | public function send($text, $queueName) 116 | { 117 | // create queue and exchange (if not exist) 118 | $this->getExchange(); 119 | $this->getQueue($queueName); 120 | 121 | $this->exchange->setName('amq.direct'); 122 | $attributes = ['message_id' => uniqid()]; 123 | $message = $this->exchange->publish($text, $queueName, AMQP_NOPARAM, $attributes); 124 | if (!$message) { 125 | throw new Exception("Error: Message '" . $message . "' was not sent.\n"); 126 | } 127 | 128 | return $attributes['message_id']; 129 | } 130 | 131 | /** 132 | * @param string $queueName 133 | * @param bool $wait Wait for task 134 | * @return AsyncTask|bool 135 | */ 136 | public function receive($queueName, $wait = false) 137 | { 138 | $message = $this->getQueue($queueName)->get(); 139 | 140 | if ($message) { 141 | $task = unserialize($message->getBody()); 142 | $task->message = $message; 143 | 144 | return $task; 145 | } 146 | 147 | return false; 148 | } 149 | 150 | /** 151 | * @param AsyncTask $task 152 | * @return bool 153 | */ 154 | public function acknowledge(AsyncTask $task) 155 | { 156 | $queue = $this->getQueue($task::$queueName); 157 | 158 | return $queue->ack($task->message->getDeliveryTag()); 159 | } 160 | 161 | /** 162 | * @param string $queueName 163 | * @return bool 164 | */ 165 | public function purge($queueName) 166 | { 167 | return $this->getQueue($queueName)->purge(); 168 | } 169 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | yii2-async 2 | ========= 3 | [![Build Status](https://travis-ci.org/bazilio91/yii2-async.svg?branch=master)](https://travis-ci.org/bazilio91/yii2-async) 4 | [![Latest Stable Version](https://poser.pugx.org/bazilio/yii2-async/v/stable)](https://packagist.org/packages/bazilio/yii2-async) 5 | [![Total Downloads](https://poser.pugx.org/bazilio/yii2-async/downloads)](https://packagist.org/packages/bazilio/yii2-async) 6 | [![Latest Unstable Version](https://poser.pugx.org/bazilio/yii2-async/v/unstable)](https://packagist.org/packages/bazilio/yii2-async) 7 | [![License](https://poser.pugx.org/bazilio/yii2-async/license)](https://packagist.org/packages/bazilio/yii2-async) 8 | 9 | Provides translucent api for moving large tasks out of request response 10 | 11 | Install: `php composer.phar require bazilio/yii2-async:dev-master` 12 | 13 | ##### Requirments: 14 | - php >=5.4 15 | - Transports: 16 | - `yii\db\Connection` 17 | - [php-amqp](https://github.com/pdezwart/php-amqp) 18 | - [yii2-redis](https://github.com/yiisoft/yii2-redis) 19 | 20 | ##### Using with AMQP: 21 | `php composer.phar require pdezwart/php-amqp:dev-master` 22 | 23 | main.php: 24 | ```php 25 | 'components' => [ 26 | 'async' => [ 27 | 'class' => 'bazilio\async\AsyncComponent', 28 | 'transportClass' => 'bazilio\async\transports\AsyncAmqpTransport', 29 | 'transportConfig' => [ 30 | 'host' => 'localhost', 31 | 'login' => 'guest', 32 | 'password' => 'guest', 33 | 'vhost' => 'yii', 34 | 'exchangeName' => 'yii' 35 | ] 36 | ] 37 | ] 38 | ``` 39 | 40 | 41 | ##### Using with Redis: 42 | `php composer.phar require yiisoft/yii2-redis:*` 43 | 44 | main.php: 45 | ```php 46 | 'components' => [ 47 | 'redis' => [ 48 | 'class' => 'yii\redis\Connection', 49 | 'hostname' => 'localhost', 50 | 'port' => 6379, 51 | 'database' => 0, 52 | 'dataTimeout' => -1, // important for daemon and blocking queries 53 | ], 54 | 'async' => [ 55 | 'class' => 'bazilio\async\AsyncComponent', 56 | 'transportClass' => 'bazilio\async\transports\AsyncRedisTransport', 57 | 'transportConfig' => [ 58 | 'connection' => 'redis', 59 | ] 60 | ] 61 | ] 62 | ``` 63 | 64 | ##### Using with MySQL (probably any sql, but tested only with mysql) 65 | 66 | main.php: 67 | ```php 68 | 'components' => [ 69 | 'db' => [ 70 | 'class' => 'yii\db\Connection', 71 | 'dsn' => 'mysql:host=localhost;dbname=yii2advenced', 72 | 'username' => 'root', 73 | 'password' => '', 74 | 'charset' => 'utf8', 75 | ], 76 | 'async' => [ 77 | 'class' => 'bazilio\async\AsyncComponent', 78 | 'transportClass' => 'bazilio\async\transports\AsyncMysqlTransport', 79 | 'transportConfig' => [ 80 | 'connection' => 'db', 81 | ] 82 | ] 83 | ] 84 | ``` 85 | 86 | Apply migrations: 87 | ```php 88 | ./yii migrate/up --migrationPath=@vendor/bazilio/yii2-async/migrations 89 | ``` 90 | 91 | ##### Usage: 92 | 93 | #### Create and send: 94 | Test class example: 95 | ```php 96 | class DownloadTask extends AsyncTask 97 | { 98 | public $url; 99 | public $file; 100 | public static $queueName = 'downloads'; 101 | 102 | public function execute() 103 | { 104 | return file_put_contents($this->file, file_get_contents($this->url)); 105 | } 106 | } 107 | 108 | // create task 109 | $task = new DownloadTask(['url' => 'http://localhost/', 'file' => '/tmp/localhost.html']); 110 | \Yii::$app->async->sendTask($task); 111 | ``` 112 | 113 | Or call external method: 114 | ```php 115 | $task = new AsyncExecuteTask([ 116 | 'class' => 'common\components\MyDownloaderComponent', 117 | 'method' => 'download', 118 | 'arguments' => ['url' => 'http://localhost/', 'file' => '/tmp/localhost.html'] 119 | ]); 120 | 121 | 122 | $task::$queueName = 'downloads'; 123 | 124 | if (YII_ENV !== 'prod') { 125 | $task->execute(); 126 | } else { 127 | Yii::$app->async->sendTask($task); 128 | } 129 | ``` 130 | 131 | #### Execute: 132 | 133 | Bash way: 134 | 135 | Fill console config: 136 | ```php 137 | 'controllerMap' => [ 138 | 'async-worker' => [ 139 | 'class' => 'bazilio\async\commands\AsyncWorkerCommand', 140 | ], 141 | ], 142 | ``` 143 | 144 | Run: 145 | ```bash 146 | # Process and exit on finish 147 | ./yii async-worker/execute downloads 148 | # Process and wait for new tasks (only redis) 149 | ./yii async-worker/daemon downloads 150 | ``` 151 | 152 | Code way: 153 | 154 | ```php 155 | while ($task = \Yii::$app->async->receiveTask('downloads')) { 156 | if ($task->execute()) { 157 | \Yii::$app->async->acknowledgeTask($task); 158 | } 159 | } 160 | ``` 161 | 162 | For more code examples look into tests: 163 | - [BaseTestClass](tests/unit/BaseTestClass.php) 164 | 165 | 166 | ###### Runing tests: 167 | ~~~ 168 | vendor/bin/codecept run 169 | ~~~ 170 | Or in Docker: 171 | ~~~ 172 | ./test.sh 173 | ~~~ 174 | -------------------------------------------------------------------------------- /models/AsyncExecuteTask.php: -------------------------------------------------------------------------------- 1 | class); 34 | } 35 | 36 | public function validateInstance($attribute, $params) 37 | { 38 | if (empty($this->$attribute)) { 39 | return; 40 | } 41 | 42 | if (!is_object($this->$attribute)) { 43 | $this->addError($attribute, "Instance should be an object, not a " . gettype($this->$attribute)); 44 | return; 45 | } 46 | 47 | $this->class = get_class($this->$attribute); 48 | } 49 | 50 | public function validateClass($attribute, $params) 51 | { 52 | if (!$this->getIsClassValid()) { 53 | $this->addError($attribute, "Class {$this->$attribute} does not exist"); 54 | } 55 | } 56 | 57 | public function validateMethod($attribute, $params) 58 | { 59 | if (!$this->getIsClassValid()) { 60 | return; 61 | } 62 | 63 | if (!isset(array_flip(get_class_methods($this->class))[$this->$attribute])) { 64 | $this->addError( 65 | $attribute, 66 | "Method {$this->$attribute} of class {$this->class} does not exist" 67 | ); 68 | } 69 | } 70 | 71 | public function validateArguments($attribute, $params) 72 | { 73 | if (!$this->getIsClassValid()) { 74 | return; 75 | } 76 | 77 | if (!isset(array_flip(get_class_methods($this->class))[$this->method])) { 78 | $this->addError( 79 | $attribute, 80 | "Can't validate attributes for not existing method {$this->method} of class {$this->class}" 81 | ); 82 | return; 83 | } 84 | 85 | $refFunc = new \ReflectionMethod($this->class, $this->method); 86 | $userArguments = array_keys($this->{$attribute}); 87 | $missingArguments = []; 88 | foreach ($refFunc->getParameters() as $param) { 89 | if (!$param->isOptional() && !in_array($param->getName(), $userArguments)) { 90 | $missingArguments[] = $param->getName(); 91 | } else { 92 | // Type hint 93 | // Notice that array hinting is not supported yet 94 | if ($param->getClass() 95 | && ( 96 | !is_object($this->{$attribute}[$param->getName()]) 97 | || get_class($this->{$attribute}[$param->getName()]) !== $param->getClass()->name 98 | ) 99 | ) { 100 | $this->addError( 101 | $attribute, 102 | "Method `{$this->method}` param `{$param->getName()}` " . 103 | "expects type `{$param->getClass()->name}` but got " . gettype($this->{$attribute}[$param->getName()]) 104 | ); 105 | } 106 | } 107 | } 108 | 109 | if (sizeof($missingArguments)) { 110 | $this->addError( 111 | $attribute, 112 | "Method `{$this->method}` missing required arguments: " . implode( 113 | ', ', 114 | $missingArguments 115 | ) 116 | ); 117 | } 118 | } 119 | 120 | /** 121 | * Returns the list of attribute names of the model. 122 | * @return array list of attribute names. 123 | */ 124 | public function attributeNames() 125 | { 126 | return [ 127 | 'instance', 128 | 'class', 129 | 'method', 130 | 'arguments' 131 | ]; 132 | } 133 | 134 | static function nope($return) 135 | { 136 | return $return; 137 | } 138 | 139 | public function execute() 140 | { 141 | if ($this->instance) { 142 | return call_user_func_array(array($this->instance, $this->method), $this->arguments); 143 | } else { 144 | return call_user_func_array(array($this->class, $this->method), $this->arguments); 145 | } 146 | } 147 | 148 | function __sleep() 149 | { 150 | return $this->attributeNames(); 151 | } 152 | } -------------------------------------------------------------------------------- /tests/unit/BaseTestClass.php: -------------------------------------------------------------------------------- 1 | id; 17 | } 18 | } 19 | 20 | class TestException extends \Exception 21 | { 22 | } 23 | 24 | class BlackHole 25 | { 26 | public static function run($param) 27 | { 28 | throw new TestException($param); 29 | } 30 | 31 | public static function hintArray(array $array) 32 | { 33 | 34 | } 35 | 36 | public static function hintClass(TestTask $param) 37 | { 38 | 39 | } 40 | } 41 | 42 | class BaseTestClass extends \yii\codeception\TestCase 43 | { 44 | public $appConfig = '@tests/unit/_config.amqp.php'; 45 | /** 46 | * @var \bazilio\async\AsyncComponent 47 | */ 48 | protected $async; 49 | 50 | public function setUp() 51 | { 52 | parent::setUp(); 53 | 54 | $this->async = \Yii::$app->async; 55 | 56 | // cleanup 57 | $this->async->purge(TestTask::$queueName); 58 | if ($this->async->receiveTask('wrong')) { 59 | $this->async->purge('wrong'); 60 | } 61 | } 62 | 63 | protected function tearDown() 64 | { 65 | parent::tearDown(); 66 | 67 | if (\Yii::$app) { 68 | $this->async = \Yii::$app->async; 69 | 70 | // cleanup 71 | $this->async->purge(TestTask::$queueName); 72 | if ($this->async->receiveTask('wrong')) { 73 | $this->async->purge('wrong'); 74 | } 75 | } 76 | } 77 | 78 | 79 | public function testPurge() 80 | { 81 | $task = new TestTask(); 82 | $this->async->sendTask($task); 83 | 84 | $task = $this->async->receiveTask(TestTask::$queueName); 85 | $this->assertEquals(TestTask::className(), get_class($task)); 86 | 87 | $this->assertTrue($this->async->purge(TestTask::$queueName)); 88 | $this->assertFalse($this->async->receiveTask(TestTask::$queueName)); 89 | 90 | $this->assertTrue($this->async->acknowledgeTask($task)); 91 | } 92 | 93 | public function testLifeCycle() 94 | { 95 | $task = new TestTask(); 96 | $task->id = uniqid(); 97 | 98 | $this->async->sendTask($task); 99 | 100 | /** @var TestTask $rTask */ 101 | $rTask = $this->async->receiveTask(TestTask::$queueName); 102 | $this->assertInstanceOf(TestTask::className(), $rTask); 103 | 104 | $this->assertEquals($task->id, $rTask->execute()); 105 | 106 | $this->assertTrue($this->async->acknowledgeTask($rTask)); 107 | 108 | $this->assertFalse($this->async->receiveTask(TestTask::$queueName)); 109 | } 110 | 111 | public function testAsyncExecuteTaskAgainstClass() 112 | { 113 | $aTask = new AsyncExecuteTask(); 114 | $aTask->setAttributes( 115 | [ 116 | 'class' => 'bazilio\async\tests\unit\BlackHole', 117 | 'method' => 'run', 118 | 'arguments' => ['param' => 'through the space'] 119 | ] 120 | ); 121 | 122 | $this->async->sendTask($aTask); 123 | 124 | $rTask = $this->async->receiveTask($aTask::$queueName); 125 | $this->assertInstanceOf('bazilio\async\models\AsyncExecuteTask', $rTask); 126 | 127 | try { 128 | $rTask->execute(); 129 | } catch (TestException $e) { 130 | $this->assertEquals($e->getMessage(), 'through the space'); 131 | $this->assertTrue($this->async->acknowledgeTask($rTask)); 132 | return; 133 | } 134 | 135 | $this->fail('BlackHole method wasn\'t called.'); 136 | } 137 | 138 | public function testAsyncExecuteTaskAgainstInstance() 139 | { 140 | $instance = new TestTask(['id' => 1]); 141 | 142 | $aTask = new AsyncExecuteTask(); 143 | $aTask->setAttributes( 144 | [ 145 | 'instance' => $instance, 146 | 'method' => 'execute', 147 | ] 148 | ); 149 | 150 | $this->async->sendTask($aTask); 151 | 152 | $rTask = $this->async->receiveTask($aTask::$queueName); 153 | $this->assertInstanceOf('bazilio\async\models\AsyncExecuteTask', $rTask); 154 | 155 | 156 | $this->assertEquals(1, $rTask->execute()); 157 | } 158 | 159 | public function testArgumentsTypeHintingArrayValidation() 160 | { 161 | $this->markTestSkipped('Scalar type hint reflection is not available yet.'); 162 | } 163 | 164 | public function testArgumentsTypeHintingClassValidation() 165 | { 166 | $aTask = new AsyncExecuteTask(); 167 | $aTask->setAttributes( 168 | [ 169 | 'class' => 'bazilio\async\tests\unit\BlackHole', 170 | 'method' => 'hintClass', 171 | 'arguments' => ['param' => 0] 172 | ] 173 | ); 174 | 175 | $this->assertFalse($aTask->validate()); 176 | $this->assertEquals( 177 | $aTask->errors['arguments'][0], 178 | 'Method `hintClass` param `param` expects type `bazilio\async\tests\unit\TestTask` but got integer' 179 | ); 180 | } 181 | 182 | public function testMissingArgumentsValidation() 183 | { 184 | $aTask = new AsyncExecuteTask(); 185 | $aTask->setAttributes( 186 | [ 187 | 'class' => 'bazilio\async\tests\unit\BlackHole', 188 | 'method' => 'run', 189 | 'arguments' => ['fail' => 'through the space'] 190 | ] 191 | ); 192 | 193 | $this->assertFalse($aTask->validate()); 194 | 195 | $this->assertEquals( 196 | $aTask->errors['arguments'][0], 197 | "Method `run` missing required arguments: param" 198 | ); 199 | 200 | try { 201 | $this->async->sendTask($aTask); 202 | } catch (Exception $e) { 203 | return; 204 | } 205 | 206 | $this->fail('Async doesn\'t reject invalid task.'); 207 | } 208 | 209 | public function testSubscribe() 210 | { 211 | if (get_called_class() == 'bazilio\async\tests\unit\AmqpTest') { 212 | $this->markTestSkipped('No support for AMQP yet'); 213 | return; 214 | } 215 | 216 | $task = new TestTask(); 217 | $task->id = 1; 218 | 219 | \Yii::$app->async->sendTask($task); 220 | 221 | $this->assertNotFalse(\Yii::$app->async->receiveTask($task::$queueName, true)); 222 | } 223 | 224 | public function testConsoleCommandDaemon() { 225 | if (get_called_class() !== 'bazilio\async\tests\unit\RedisTest') { 226 | $this->markTestSkipped('No support for this transport yet'); 227 | return; 228 | } 229 | 230 | $task = new TestTask(); 231 | \Yii::$app->async->sendTask($task); 232 | 233 | $controller = new AsyncWorkerCommand('id', new Module('id')); 234 | 235 | $this->setExpectedException('yii\db\Exception'); 236 | $controller->actionDaemon($task::$queueName); 237 | 238 | $this->assertFalse($this->async->receiveTask($task::$queueName)); 239 | } 240 | 241 | public function testConsoleCommandExecute() { 242 | $task = new TestTask(); 243 | \Yii::$app->async->sendTask($task); 244 | 245 | $controller = new AsyncWorkerCommand('id', new Module('id')); 246 | 247 | $controller->actionExecute($task::$queueName); 248 | 249 | $this->assertFalse($this->async->receiveTask($task::$queueName)); 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /tests/unit/UnitTester.php: -------------------------------------------------------------------------------- 1 | scenario->runStep(new \Codeception\Step\Action('assertEquals', func_get_args())); 43 | } 44 | 45 | 46 | /** 47 | * [!] Method is generated. Documentation taken from corresponding module. 48 | * 49 | * Checks that two variables are not equal 50 | * 51 | * @param $expected 52 | * @param $actual 53 | * @param string $message 54 | * @see \Codeception\Module\Asserts::assertNotEquals() 55 | */ 56 | public function assertNotEquals($expected, $actual, $message = null) { 57 | return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args())); 58 | } 59 | 60 | 61 | /** 62 | * [!] Method is generated. Documentation taken from corresponding module. 63 | * 64 | * Checks that two variables are same 65 | * 66 | * @param $expected 67 | * @param $actual 68 | * @param string $message 69 | * 70 | * @return mixed 71 | * @see \Codeception\Module\Asserts::assertSame() 72 | */ 73 | public function assertSame($expected, $actual, $message = null) { 74 | return $this->scenario->runStep(new \Codeception\Step\Action('assertSame', func_get_args())); 75 | } 76 | 77 | 78 | /** 79 | * [!] Method is generated. Documentation taken from corresponding module. 80 | * 81 | * Checks that two variables are not same 82 | * 83 | * @param $expected 84 | * @param $actual 85 | * @param string $message 86 | * @see \Codeception\Module\Asserts::assertNotSame() 87 | */ 88 | public function assertNotSame($expected, $actual, $message = null) { 89 | return $this->scenario->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args())); 90 | } 91 | 92 | 93 | /** 94 | * [!] Method is generated. Documentation taken from corresponding module. 95 | * 96 | * Checks that actual is greater than expected 97 | * 98 | * @param $expected 99 | * @param $actual 100 | * @param string $message 101 | * @see \Codeception\Module\Asserts::assertGreaterThan() 102 | */ 103 | public function assertGreaterThan($expected, $actual, $message = null) { 104 | return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args())); 105 | } 106 | 107 | 108 | /** 109 | * [!] Method is generated. Documentation taken from corresponding module. 110 | * 111 | * @deprecated 112 | * @see \Codeception\Module\Asserts::assertGreaterThen() 113 | */ 114 | public function assertGreaterThen($expected, $actual, $message = null) { 115 | return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args())); 116 | } 117 | 118 | 119 | /** 120 | * [!] Method is generated. Documentation taken from corresponding module. 121 | * 122 | * Checks that actual is greater or equal than expected 123 | * 124 | * @param $expected 125 | * @param $actual 126 | * @param string $message 127 | * @see \Codeception\Module\Asserts::assertGreaterThanOrEqual() 128 | */ 129 | public function assertGreaterThanOrEqual($expected, $actual, $message = null) { 130 | return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args())); 131 | } 132 | 133 | 134 | /** 135 | * [!] Method is generated. Documentation taken from corresponding module. 136 | * 137 | * @deprecated 138 | * @see \Codeception\Module\Asserts::assertGreaterThenOrEqual() 139 | */ 140 | public function assertGreaterThenOrEqual($expected, $actual, $message = null) { 141 | return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args())); 142 | } 143 | 144 | 145 | /** 146 | * [!] Method is generated. Documentation taken from corresponding module. 147 | * 148 | * Checks that actual is less than expected 149 | * 150 | * @param $expected 151 | * @param $actual 152 | * @param string $message 153 | * @see \Codeception\Module\Asserts::assertLessThan() 154 | */ 155 | public function assertLessThan($expected, $actual, $message = null) { 156 | return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args())); 157 | } 158 | 159 | 160 | /** 161 | * [!] Method is generated. Documentation taken from corresponding module. 162 | * 163 | * Checks that actual is less or equal than expected 164 | * 165 | * @param $expected 166 | * @param $actual 167 | * @param string $message 168 | * @see \Codeception\Module\Asserts::assertLessThanOrEqual() 169 | */ 170 | public function assertLessThanOrEqual($expected, $actual, $message = null) { 171 | return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args())); 172 | } 173 | 174 | 175 | /** 176 | * [!] Method is generated. Documentation taken from corresponding module. 177 | * 178 | * Checks that haystack contains needle 179 | * 180 | * @param $needle 181 | * @param $haystack 182 | * @param string $message 183 | * @see \Codeception\Module\Asserts::assertContains() 184 | */ 185 | public function assertContains($needle, $haystack, $message = null) { 186 | return $this->scenario->runStep(new \Codeception\Step\Action('assertContains', func_get_args())); 187 | } 188 | 189 | 190 | /** 191 | * [!] Method is generated. Documentation taken from corresponding module. 192 | * 193 | * Checks that haystack doesn't contain needle. 194 | * 195 | * @param $needle 196 | * @param $haystack 197 | * @param string $message 198 | * @see \Codeception\Module\Asserts::assertNotContains() 199 | */ 200 | public function assertNotContains($needle, $haystack, $message = null) { 201 | return $this->scenario->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args())); 202 | } 203 | 204 | 205 | /** 206 | * [!] Method is generated. Documentation taken from corresponding module. 207 | * 208 | * Checks that variable is empty. 209 | * 210 | * @param $actual 211 | * @param string $message 212 | * @see \Codeception\Module\Asserts::assertEmpty() 213 | */ 214 | public function assertEmpty($actual, $message = null) { 215 | return $this->scenario->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args())); 216 | } 217 | 218 | 219 | /** 220 | * [!] Method is generated. Documentation taken from corresponding module. 221 | * 222 | * Checks that variable is not empty. 223 | * 224 | * @param $actual 225 | * @param string $message 226 | * @see \Codeception\Module\Asserts::assertNotEmpty() 227 | */ 228 | public function assertNotEmpty($actual, $message = null) { 229 | return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args())); 230 | } 231 | 232 | 233 | /** 234 | * [!] Method is generated. Documentation taken from corresponding module. 235 | * 236 | * Checks that variable is NULL 237 | * 238 | * @param $actual 239 | * @param string $message 240 | * @see \Codeception\Module\Asserts::assertNull() 241 | */ 242 | public function assertNull($actual, $message = null) { 243 | return $this->scenario->runStep(new \Codeception\Step\Action('assertNull', func_get_args())); 244 | } 245 | 246 | 247 | /** 248 | * [!] Method is generated. Documentation taken from corresponding module. 249 | * 250 | * Checks that variable is not NULL 251 | * 252 | * @param $actual 253 | * @param string $message 254 | * @see \Codeception\Module\Asserts::assertNotNull() 255 | */ 256 | public function assertNotNull($actual, $message = null) { 257 | return $this->scenario->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args())); 258 | } 259 | 260 | 261 | /** 262 | * [!] Method is generated. Documentation taken from corresponding module. 263 | * 264 | * Checks that condition is positive. 265 | * 266 | * @param $condition 267 | * @param string $message 268 | * @see \Codeception\Module\Asserts::assertTrue() 269 | */ 270 | public function assertTrue($condition, $message = null) { 271 | return $this->scenario->runStep(new \Codeception\Step\Action('assertTrue', func_get_args())); 272 | } 273 | 274 | 275 | /** 276 | * [!] Method is generated. Documentation taken from corresponding module. 277 | * 278 | * Checks that condition is negative. 279 | * 280 | * @param $condition 281 | * @param string $message 282 | * @see \Codeception\Module\Asserts::assertFalse() 283 | */ 284 | public function assertFalse($condition, $message = null) { 285 | return $this->scenario->runStep(new \Codeception\Step\Action('assertFalse', func_get_args())); 286 | } 287 | 288 | 289 | /** 290 | * [!] Method is generated. Documentation taken from corresponding module. 291 | * 292 | * Fails the test with message. 293 | * 294 | * @param $message 295 | * @see \Codeception\Module\Asserts::fail() 296 | */ 297 | public function fail($message) { 298 | return $this->scenario->runStep(new \Codeception\Step\Action('fail', func_get_args())); 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "72067c54b641a4026c9189ecdcbfc286", 8 | "packages": [ 9 | { 10 | "name": "bower-asset/jquery", 11 | "version": "2.1.4", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/jquery/jquery.git", 15 | "reference": "7751e69b615c6eca6f783a81e292a55725af6b85" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/jquery/jquery/zipball/7751e69b615c6eca6f783a81e292a55725af6b85", 20 | "reference": "7751e69b615c6eca6f783a81e292a55725af6b85", 21 | "shasum": "" 22 | }, 23 | "require-dev": { 24 | "bower-asset/qunit": "1.14.0", 25 | "bower-asset/requirejs": "2.1.10", 26 | "bower-asset/sinon": "1.8.1", 27 | "bower-asset/sizzle": "2.1.1-patch2" 28 | }, 29 | "type": "bower-asset-library", 30 | "extra": { 31 | "bower-asset-main": "dist/jquery.js", 32 | "bower-asset-ignore": [ 33 | "**/.*", 34 | "build", 35 | "dist/cdn", 36 | "speed", 37 | "test", 38 | "*.md", 39 | "AUTHORS.txt", 40 | "Gruntfile.js", 41 | "package.json" 42 | ] 43 | }, 44 | "license": [ 45 | "MIT" 46 | ], 47 | "keywords": [ 48 | "javascript", 49 | "jquery", 50 | "library" 51 | ] 52 | }, 53 | { 54 | "name": "bower-asset/jquery.inputmask", 55 | "version": "3.1.63", 56 | "source": { 57 | "type": "git", 58 | "url": "https://github.com/RobinHerbots/jquery.inputmask.git", 59 | "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48" 60 | }, 61 | "dist": { 62 | "type": "zip", 63 | "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/c40c7287eadc31e341ebbf0c02352eb55b9cbc48", 64 | "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48", 65 | "shasum": "" 66 | }, 67 | "require": { 68 | "bower-asset/jquery": ">=1.7" 69 | }, 70 | "type": "bower-asset-library", 71 | "extra": { 72 | "bower-asset-main": [ 73 | "./dist/inputmask/jquery.inputmask.js", 74 | "./dist/inputmask/jquery.inputmask.extensions.js", 75 | "./dist/inputmask/jquery.inputmask.date.extensions.js", 76 | "./dist/inputmask/jquery.inputmask.numeric.extensions.js", 77 | "./dist/inputmask/jquery.inputmask.phone.extensions.js", 78 | "./dist/inputmask/jquery.inputmask.regex.extensions.js" 79 | ], 80 | "bower-asset-ignore": [ 81 | "**/.*", 82 | "qunit/", 83 | "nuget/", 84 | "tools/", 85 | "js/", 86 | "*.md", 87 | "build.properties", 88 | "build.xml", 89 | "jquery.inputmask.jquery.json" 90 | ] 91 | }, 92 | "license": [ 93 | "http://opensource.org/licenses/mit-license.php" 94 | ], 95 | "description": "jquery.inputmask is a jquery plugin which create an input mask.", 96 | "keywords": [ 97 | "form", 98 | "input", 99 | "inputmask", 100 | "jquery", 101 | "mask", 102 | "plugins" 103 | ] 104 | }, 105 | { 106 | "name": "bower-asset/punycode", 107 | "version": "v1.3.2", 108 | "source": { 109 | "type": "git", 110 | "url": "https://github.com/bestiejs/punycode.js.git", 111 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" 112 | }, 113 | "dist": { 114 | "type": "zip", 115 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", 116 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3", 117 | "shasum": "" 118 | }, 119 | "type": "bower-asset-library", 120 | "extra": { 121 | "bower-asset-main": "punycode.js", 122 | "bower-asset-ignore": [ 123 | "coverage", 124 | "tests", 125 | ".*", 126 | "component.json", 127 | "Gruntfile.js", 128 | "node_modules", 129 | "package.json" 130 | ] 131 | } 132 | }, 133 | { 134 | "name": "bower-asset/yii2-pjax", 135 | "version": "v2.0.5", 136 | "source": { 137 | "type": "git", 138 | "url": "https://github.com/yiisoft/jquery-pjax.git", 139 | "reference": "6818718408086db6bdcf33649cecb86b6b4f9b67" 140 | }, 141 | "dist": { 142 | "type": "zip", 143 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/6818718408086db6bdcf33649cecb86b6b4f9b67", 144 | "reference": "6818718408086db6bdcf33649cecb86b6b4f9b67", 145 | "shasum": "" 146 | }, 147 | "require": { 148 | "bower-asset/jquery": ">=1.8" 149 | }, 150 | "type": "bower-asset-library", 151 | "extra": { 152 | "bower-asset-main": "./jquery.pjax.js", 153 | "bower-asset-ignore": [ 154 | ".travis.yml", 155 | "Gemfile", 156 | "Gemfile.lock", 157 | "vendor/", 158 | "script/", 159 | "test/" 160 | ] 161 | }, 162 | "license": [ 163 | "MIT" 164 | ] 165 | }, 166 | { 167 | "name": "cebe/markdown", 168 | "version": "1.1.0", 169 | "source": { 170 | "type": "git", 171 | "url": "https://github.com/cebe/markdown.git", 172 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2" 173 | }, 174 | "dist": { 175 | "type": "zip", 176 | "url": "https://api.github.com/repos/cebe/markdown/zipball/54a2c49de31cc44e864ebf0500a35ef21d0010b2", 177 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2", 178 | "shasum": "" 179 | }, 180 | "require": { 181 | "lib-pcre": "*", 182 | "php": ">=5.4.0" 183 | }, 184 | "require-dev": { 185 | "cebe/indent": "*", 186 | "facebook/xhprof": "*@dev", 187 | "phpunit/phpunit": "4.1.*" 188 | }, 189 | "bin": [ 190 | "bin/markdown" 191 | ], 192 | "type": "library", 193 | "extra": { 194 | "branch-alias": { 195 | "dev-master": "1.1.x-dev" 196 | } 197 | }, 198 | "autoload": { 199 | "psr-4": { 200 | "cebe\\markdown\\": "" 201 | } 202 | }, 203 | "notification-url": "https://packagist.org/downloads/", 204 | "license": [ 205 | "MIT" 206 | ], 207 | "authors": [ 208 | { 209 | "name": "Carsten Brandt", 210 | "email": "mail@cebe.cc", 211 | "homepage": "http://cebe.cc/", 212 | "role": "Creator" 213 | } 214 | ], 215 | "description": "A super fast, highly extensible markdown parser for PHP", 216 | "homepage": "https://github.com/cebe/markdown#readme", 217 | "keywords": [ 218 | "extensible", 219 | "fast", 220 | "gfm", 221 | "markdown", 222 | "markdown-extra" 223 | ], 224 | "time": "2015-03-06 05:28:07" 225 | }, 226 | { 227 | "name": "ezyang/htmlpurifier", 228 | "version": "v4.6.0", 229 | "source": { 230 | "type": "git", 231 | "url": "https://github.com/ezyang/htmlpurifier.git", 232 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd" 233 | }, 234 | "dist": { 235 | "type": "zip", 236 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6f389f0f25b90d0b495308efcfa073981177f0fd", 237 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd", 238 | "shasum": "" 239 | }, 240 | "require": { 241 | "php": ">=5.2" 242 | }, 243 | "type": "library", 244 | "autoload": { 245 | "psr-0": { 246 | "HTMLPurifier": "library/" 247 | }, 248 | "files": [ 249 | "library/HTMLPurifier.composer.php" 250 | ] 251 | }, 252 | "notification-url": "https://packagist.org/downloads/", 253 | "license": [ 254 | "LGPL" 255 | ], 256 | "authors": [ 257 | { 258 | "name": "Edward Z. Yang", 259 | "email": "admin@htmlpurifier.org", 260 | "homepage": "http://ezyang.com" 261 | } 262 | ], 263 | "description": "Standards compliant HTML filter written in PHP", 264 | "homepage": "http://htmlpurifier.org/", 265 | "keywords": [ 266 | "html" 267 | ], 268 | "time": "2013-11-30 08:25:19" 269 | }, 270 | { 271 | "name": "yiisoft/yii2", 272 | "version": "2.0.6", 273 | "source": { 274 | "type": "git", 275 | "url": "https://github.com/yiisoft/yii2-framework.git", 276 | "reference": "f42b2eb80f61992438661b01d0d74c6738e2ff38" 277 | }, 278 | "dist": { 279 | "type": "zip", 280 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/f42b2eb80f61992438661b01d0d74c6738e2ff38", 281 | "reference": "f42b2eb80f61992438661b01d0d74c6738e2ff38", 282 | "shasum": "" 283 | }, 284 | "require": { 285 | "bower-asset/jquery": "2.1.*@stable | 1.11.*@stable", 286 | "bower-asset/jquery.inputmask": "3.1.*", 287 | "bower-asset/punycode": "1.3.*", 288 | "bower-asset/yii2-pjax": ">=2.0.1", 289 | "cebe/markdown": "~1.0.0 | ~1.1.0", 290 | "ext-mbstring": "*", 291 | "ezyang/htmlpurifier": "4.6.*", 292 | "lib-pcre": "*", 293 | "php": ">=5.4.0", 294 | "yiisoft/yii2-composer": "*" 295 | }, 296 | "bin": [ 297 | "yii" 298 | ], 299 | "type": "library", 300 | "extra": { 301 | "branch-alias": { 302 | "dev-master": "2.0.x-dev" 303 | } 304 | }, 305 | "autoload": { 306 | "psr-4": { 307 | "yii\\": "" 308 | } 309 | }, 310 | "notification-url": "https://packagist.org/downloads/", 311 | "license": [ 312 | "BSD-3-Clause" 313 | ], 314 | "authors": [ 315 | { 316 | "name": "Qiang Xue", 317 | "email": "qiang.xue@gmail.com", 318 | "homepage": "http://www.yiiframework.com/", 319 | "role": "Founder and project lead" 320 | }, 321 | { 322 | "name": "Alexander Makarov", 323 | "email": "sam@rmcreative.ru", 324 | "homepage": "http://rmcreative.ru/", 325 | "role": "Core framework development" 326 | }, 327 | { 328 | "name": "Maurizio Domba", 329 | "homepage": "http://mdomba.info/", 330 | "role": "Core framework development" 331 | }, 332 | { 333 | "name": "Carsten Brandt", 334 | "email": "mail@cebe.cc", 335 | "homepage": "http://cebe.cc/", 336 | "role": "Core framework development" 337 | }, 338 | { 339 | "name": "Timur Ruziev", 340 | "email": "resurtm@gmail.com", 341 | "homepage": "http://resurtm.com/", 342 | "role": "Core framework development" 343 | }, 344 | { 345 | "name": "Paul Klimov", 346 | "email": "klimov.paul@gmail.com", 347 | "role": "Core framework development" 348 | } 349 | ], 350 | "description": "Yii PHP Framework Version 2", 351 | "homepage": "http://www.yiiframework.com/", 352 | "keywords": [ 353 | "framework", 354 | "yii2" 355 | ], 356 | "time": "2015-08-05 22:00:30" 357 | }, 358 | { 359 | "name": "yiisoft/yii2-composer", 360 | "version": "2.0.3", 361 | "source": { 362 | "type": "git", 363 | "url": "https://github.com/yiisoft/yii2-composer.git", 364 | "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be" 365 | }, 366 | "dist": { 367 | "type": "zip", 368 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/ca8d23707ae47d20b0454e4b135c156f6da6d7be", 369 | "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be", 370 | "shasum": "" 371 | }, 372 | "require": { 373 | "composer-plugin-api": "1.0.0" 374 | }, 375 | "type": "composer-plugin", 376 | "extra": { 377 | "class": "yii\\composer\\Plugin", 378 | "branch-alias": { 379 | "dev-master": "2.0.x-dev" 380 | } 381 | }, 382 | "autoload": { 383 | "psr-4": { 384 | "yii\\composer\\": "" 385 | } 386 | }, 387 | "notification-url": "https://packagist.org/downloads/", 388 | "license": [ 389 | "BSD-3-Clause" 390 | ], 391 | "authors": [ 392 | { 393 | "name": "Qiang Xue", 394 | "email": "qiang.xue@gmail.com" 395 | } 396 | ], 397 | "description": "The composer plugin for Yii extension installer", 398 | "keywords": [ 399 | "composer", 400 | "extension installer", 401 | "yii2" 402 | ], 403 | "time": "2015-03-01 06:22:44" 404 | } 405 | ], 406 | "packages-dev": [ 407 | { 408 | "name": "codeception/codeception", 409 | "version": "2.0.14", 410 | "source": { 411 | "type": "git", 412 | "url": "https://github.com/Codeception/Codeception.git", 413 | "reference": "d1e994dc9fe07d1decb21ded6ced4636f493822c" 414 | }, 415 | "dist": { 416 | "type": "zip", 417 | "url": "https://api.github.com/repos/Codeception/Codeception/zipball/d1e994dc9fe07d1decb21ded6ced4636f493822c", 418 | "reference": "d1e994dc9fe07d1decb21ded6ced4636f493822c", 419 | "shasum": "" 420 | }, 421 | "require": { 422 | "ext-json": "*", 423 | "ext-mbstring": "*", 424 | "facebook/webdriver": "~0.4|~0.5", 425 | "guzzlehttp/guzzle": "~4.0|~5.0", 426 | "php": ">=5.4.0", 427 | "phpunit/phpunit": "~4.6.0", 428 | "symfony/browser-kit": "~2.4", 429 | "symfony/console": "~2.4", 430 | "symfony/css-selector": "~2.4", 431 | "symfony/dom-crawler": "~2.4,!=2.4.5", 432 | "symfony/event-dispatcher": "~2.4", 433 | "symfony/finder": "~2.4", 434 | "symfony/yaml": "~2.4" 435 | }, 436 | "require-dev": { 437 | "codeception/specify": "~0.3", 438 | "facebook/php-sdk": "~3.2", 439 | "flow/jsonpath": "~0.2", 440 | "monolog/monolog": "~1.8", 441 | "pda/pheanstalk": "~2.0", 442 | "videlalvaro/php-amqplib": "~2.4" 443 | }, 444 | "suggest": { 445 | "codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests", 446 | "codeception/specify": "BDD-style code blocks", 447 | "codeception/verify": "BDD-style assertions", 448 | "monolog/monolog": "Log test steps", 449 | "phpseclib/phpseclib": "Extension required to use the SFTP option in the FTP Module." 450 | }, 451 | "bin": [ 452 | "codecept" 453 | ], 454 | "type": "library", 455 | "extra": { 456 | "branch-alias": { 457 | "dev-master": "2.1-dev" 458 | } 459 | }, 460 | "autoload": { 461 | "psr-0": { 462 | "Codeception": "src" 463 | } 464 | }, 465 | "notification-url": "https://packagist.org/downloads/", 466 | "license": [ 467 | "MIT" 468 | ], 469 | "authors": [ 470 | { 471 | "name": "Michael Bodnarchuk", 472 | "email": "davert@mail.ua", 473 | "homepage": "http://codegyre.com" 474 | } 475 | ], 476 | "description": "BDD-style testing framework", 477 | "homepage": "http://codeception.com/", 478 | "keywords": [ 479 | "BDD", 480 | "TDD", 481 | "acceptance testing", 482 | "functional testing", 483 | "unit testing" 484 | ], 485 | "time": "2015-05-28 09:05:45" 486 | }, 487 | { 488 | "name": "doctrine/instantiator", 489 | "version": "1.0.5", 490 | "source": { 491 | "type": "git", 492 | "url": "https://github.com/doctrine/instantiator.git", 493 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 494 | }, 495 | "dist": { 496 | "type": "zip", 497 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 498 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 499 | "shasum": "" 500 | }, 501 | "require": { 502 | "php": ">=5.3,<8.0-DEV" 503 | }, 504 | "require-dev": { 505 | "athletic/athletic": "~0.1.8", 506 | "ext-pdo": "*", 507 | "ext-phar": "*", 508 | "phpunit/phpunit": "~4.0", 509 | "squizlabs/php_codesniffer": "~2.0" 510 | }, 511 | "type": "library", 512 | "extra": { 513 | "branch-alias": { 514 | "dev-master": "1.0.x-dev" 515 | } 516 | }, 517 | "autoload": { 518 | "psr-4": { 519 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 520 | } 521 | }, 522 | "notification-url": "https://packagist.org/downloads/", 523 | "license": [ 524 | "MIT" 525 | ], 526 | "authors": [ 527 | { 528 | "name": "Marco Pivetta", 529 | "email": "ocramius@gmail.com", 530 | "homepage": "http://ocramius.github.com/" 531 | } 532 | ], 533 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 534 | "homepage": "https://github.com/doctrine/instantiator", 535 | "keywords": [ 536 | "constructor", 537 | "instantiate" 538 | ], 539 | "time": "2015-06-14 21:17:01" 540 | }, 541 | { 542 | "name": "facebook/webdriver", 543 | "version": "v0.6.0", 544 | "source": { 545 | "type": "git", 546 | "url": "https://github.com/facebook/php-webdriver.git", 547 | "reference": "2c5b305ea91b00ebbc433ad1663b7f16c1b31ec5" 548 | }, 549 | "dist": { 550 | "type": "zip", 551 | "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/2c5b305ea91b00ebbc433ad1663b7f16c1b31ec5", 552 | "reference": "2c5b305ea91b00ebbc433ad1663b7f16c1b31ec5", 553 | "shasum": "" 554 | }, 555 | "require": { 556 | "php": ">=5.3.19" 557 | }, 558 | "require-dev": { 559 | "phpdocumentor/phpdocumentor": "2.*", 560 | "phpunit/phpunit": "3.7.*" 561 | }, 562 | "type": "library", 563 | "autoload": { 564 | "classmap": [ 565 | "lib/" 566 | ] 567 | }, 568 | "notification-url": "https://packagist.org/downloads/", 569 | "license": [ 570 | "Apache-2.0" 571 | ], 572 | "description": "A php client for WebDriver", 573 | "homepage": "https://github.com/facebook/php-webdriver", 574 | "keywords": [ 575 | "facebook", 576 | "php", 577 | "selenium", 578 | "webdriver" 579 | ], 580 | "time": "2015-02-09 19:39:34" 581 | }, 582 | { 583 | "name": "guzzlehttp/guzzle", 584 | "version": "5.3.0", 585 | "source": { 586 | "type": "git", 587 | "url": "https://github.com/guzzle/guzzle.git", 588 | "reference": "f3c8c22471cb55475105c14769644a49c3262b93" 589 | }, 590 | "dist": { 591 | "type": "zip", 592 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93", 593 | "reference": "f3c8c22471cb55475105c14769644a49c3262b93", 594 | "shasum": "" 595 | }, 596 | "require": { 597 | "guzzlehttp/ringphp": "^1.1", 598 | "php": ">=5.4.0" 599 | }, 600 | "require-dev": { 601 | "ext-curl": "*", 602 | "phpunit/phpunit": "^4.0", 603 | "psr/log": "^1.0" 604 | }, 605 | "type": "library", 606 | "extra": { 607 | "branch-alias": { 608 | "dev-master": "5.0-dev" 609 | } 610 | }, 611 | "autoload": { 612 | "psr-4": { 613 | "GuzzleHttp\\": "src/" 614 | } 615 | }, 616 | "notification-url": "https://packagist.org/downloads/", 617 | "license": [ 618 | "MIT" 619 | ], 620 | "authors": [ 621 | { 622 | "name": "Michael Dowling", 623 | "email": "mtdowling@gmail.com", 624 | "homepage": "https://github.com/mtdowling" 625 | } 626 | ], 627 | "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", 628 | "homepage": "http://guzzlephp.org/", 629 | "keywords": [ 630 | "client", 631 | "curl", 632 | "framework", 633 | "http", 634 | "http client", 635 | "rest", 636 | "web service" 637 | ], 638 | "time": "2015-05-20 03:47:55" 639 | }, 640 | { 641 | "name": "guzzlehttp/ringphp", 642 | "version": "1.1.0", 643 | "source": { 644 | "type": "git", 645 | "url": "https://github.com/guzzle/RingPHP.git", 646 | "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b" 647 | }, 648 | "dist": { 649 | "type": "zip", 650 | "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", 651 | "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", 652 | "shasum": "" 653 | }, 654 | "require": { 655 | "guzzlehttp/streams": "~3.0", 656 | "php": ">=5.4.0", 657 | "react/promise": "~2.0" 658 | }, 659 | "require-dev": { 660 | "ext-curl": "*", 661 | "phpunit/phpunit": "~4.0" 662 | }, 663 | "suggest": { 664 | "ext-curl": "Guzzle will use specific adapters if cURL is present" 665 | }, 666 | "type": "library", 667 | "extra": { 668 | "branch-alias": { 669 | "dev-master": "1.1-dev" 670 | } 671 | }, 672 | "autoload": { 673 | "psr-4": { 674 | "GuzzleHttp\\Ring\\": "src/" 675 | } 676 | }, 677 | "notification-url": "https://packagist.org/downloads/", 678 | "license": [ 679 | "MIT" 680 | ], 681 | "authors": [ 682 | { 683 | "name": "Michael Dowling", 684 | "email": "mtdowling@gmail.com", 685 | "homepage": "https://github.com/mtdowling" 686 | } 687 | ], 688 | "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", 689 | "time": "2015-05-20 03:37:09" 690 | }, 691 | { 692 | "name": "guzzlehttp/streams", 693 | "version": "3.0.0", 694 | "source": { 695 | "type": "git", 696 | "url": "https://github.com/guzzle/streams.git", 697 | "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" 698 | }, 699 | "dist": { 700 | "type": "zip", 701 | "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", 702 | "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", 703 | "shasum": "" 704 | }, 705 | "require": { 706 | "php": ">=5.4.0" 707 | }, 708 | "require-dev": { 709 | "phpunit/phpunit": "~4.0" 710 | }, 711 | "type": "library", 712 | "extra": { 713 | "branch-alias": { 714 | "dev-master": "3.0-dev" 715 | } 716 | }, 717 | "autoload": { 718 | "psr-4": { 719 | "GuzzleHttp\\Stream\\": "src/" 720 | } 721 | }, 722 | "notification-url": "https://packagist.org/downloads/", 723 | "license": [ 724 | "MIT" 725 | ], 726 | "authors": [ 727 | { 728 | "name": "Michael Dowling", 729 | "email": "mtdowling@gmail.com", 730 | "homepage": "https://github.com/mtdowling" 731 | } 732 | ], 733 | "description": "Provides a simple abstraction over streams of data", 734 | "homepage": "http://guzzlephp.org/", 735 | "keywords": [ 736 | "Guzzle", 737 | "stream" 738 | ], 739 | "time": "2014-10-12 19:18:40" 740 | }, 741 | { 742 | "name": "kriswallsmith/spork", 743 | "version": "dev-master", 744 | "source": { 745 | "type": "git", 746 | "url": "https://github.com/kriswallsmith/spork.git", 747 | "reference": "530fcf57fce4d54806288547b22aa8dcbb4b6c96" 748 | }, 749 | "dist": { 750 | "type": "zip", 751 | "url": "https://api.github.com/repos/kriswallsmith/spork/zipball/530fcf57fce4d54806288547b22aa8dcbb4b6c96", 752 | "reference": "530fcf57fce4d54806288547b22aa8dcbb4b6c96", 753 | "shasum": "" 754 | }, 755 | "require": { 756 | "ext-pcntl": "*", 757 | "ext-posix": "*", 758 | "ext-shmop": "*", 759 | "php": ">=5.3.0", 760 | "symfony/event-dispatcher": "*" 761 | }, 762 | "type": "library", 763 | "autoload": { 764 | "psr-0": { 765 | "Spork": "src/" 766 | } 767 | }, 768 | "notification-url": "https://packagist.org/downloads/", 769 | "license": [ 770 | "MIT" 771 | ], 772 | "authors": [ 773 | { 774 | "name": "Kris Wallsmith", 775 | "email": "kris.wallsmith@gmail.com", 776 | "homepage": "http://kriswallsmith.net/" 777 | } 778 | ], 779 | "description": "Asynchronous PHP", 780 | "homepage": "https://github.com/kriswallsmith/spork", 781 | "time": "2015-05-18 19:16:02" 782 | }, 783 | { 784 | "name": "pdezwart/php-amqp", 785 | "version": "dev-master", 786 | "source": { 787 | "type": "git", 788 | "url": "https://github.com/pdezwart/php-amqp", 789 | "reference": "origin/master" 790 | }, 791 | "type": "library", 792 | "time": "2015-04-18 15:41:35" 793 | }, 794 | { 795 | "name": "phpdocumentor/reflection-docblock", 796 | "version": "2.0.4", 797 | "source": { 798 | "type": "git", 799 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 800 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" 801 | }, 802 | "dist": { 803 | "type": "zip", 804 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", 805 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", 806 | "shasum": "" 807 | }, 808 | "require": { 809 | "php": ">=5.3.3" 810 | }, 811 | "require-dev": { 812 | "phpunit/phpunit": "~4.0" 813 | }, 814 | "suggest": { 815 | "dflydev/markdown": "~1.0", 816 | "erusev/parsedown": "~1.0" 817 | }, 818 | "type": "library", 819 | "extra": { 820 | "branch-alias": { 821 | "dev-master": "2.0.x-dev" 822 | } 823 | }, 824 | "autoload": { 825 | "psr-0": { 826 | "phpDocumentor": [ 827 | "src/" 828 | ] 829 | } 830 | }, 831 | "notification-url": "https://packagist.org/downloads/", 832 | "license": [ 833 | "MIT" 834 | ], 835 | "authors": [ 836 | { 837 | "name": "Mike van Riel", 838 | "email": "mike.vanriel@naenius.com" 839 | } 840 | ], 841 | "time": "2015-02-03 12:10:50" 842 | }, 843 | { 844 | "name": "phpspec/prophecy", 845 | "version": "v1.5.0", 846 | "source": { 847 | "type": "git", 848 | "url": "https://github.com/phpspec/prophecy.git", 849 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" 850 | }, 851 | "dist": { 852 | "type": "zip", 853 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", 854 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", 855 | "shasum": "" 856 | }, 857 | "require": { 858 | "doctrine/instantiator": "^1.0.2", 859 | "phpdocumentor/reflection-docblock": "~2.0", 860 | "sebastian/comparator": "~1.1" 861 | }, 862 | "require-dev": { 863 | "phpspec/phpspec": "~2.0" 864 | }, 865 | "type": "library", 866 | "extra": { 867 | "branch-alias": { 868 | "dev-master": "1.4.x-dev" 869 | } 870 | }, 871 | "autoload": { 872 | "psr-0": { 873 | "Prophecy\\": "src/" 874 | } 875 | }, 876 | "notification-url": "https://packagist.org/downloads/", 877 | "license": [ 878 | "MIT" 879 | ], 880 | "authors": [ 881 | { 882 | "name": "Konstantin Kudryashov", 883 | "email": "ever.zet@gmail.com", 884 | "homepage": "http://everzet.com" 885 | }, 886 | { 887 | "name": "Marcello Duarte", 888 | "email": "marcello.duarte@gmail.com" 889 | } 890 | ], 891 | "description": "Highly opinionated mocking framework for PHP 5.3+", 892 | "homepage": "https://github.com/phpspec/prophecy", 893 | "keywords": [ 894 | "Double", 895 | "Dummy", 896 | "fake", 897 | "mock", 898 | "spy", 899 | "stub" 900 | ], 901 | "time": "2015-08-13 10:07:40" 902 | }, 903 | { 904 | "name": "phpunit/php-code-coverage", 905 | "version": "2.2.4", 906 | "source": { 907 | "type": "git", 908 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 909 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 910 | }, 911 | "dist": { 912 | "type": "zip", 913 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 914 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 915 | "shasum": "" 916 | }, 917 | "require": { 918 | "php": ">=5.3.3", 919 | "phpunit/php-file-iterator": "~1.3", 920 | "phpunit/php-text-template": "~1.2", 921 | "phpunit/php-token-stream": "~1.3", 922 | "sebastian/environment": "^1.3.2", 923 | "sebastian/version": "~1.0" 924 | }, 925 | "require-dev": { 926 | "ext-xdebug": ">=2.1.4", 927 | "phpunit/phpunit": "~4" 928 | }, 929 | "suggest": { 930 | "ext-dom": "*", 931 | "ext-xdebug": ">=2.2.1", 932 | "ext-xmlwriter": "*" 933 | }, 934 | "type": "library", 935 | "extra": { 936 | "branch-alias": { 937 | "dev-master": "2.2.x-dev" 938 | } 939 | }, 940 | "autoload": { 941 | "classmap": [ 942 | "src/" 943 | ] 944 | }, 945 | "notification-url": "https://packagist.org/downloads/", 946 | "license": [ 947 | "BSD-3-Clause" 948 | ], 949 | "authors": [ 950 | { 951 | "name": "Sebastian Bergmann", 952 | "email": "sb@sebastian-bergmann.de", 953 | "role": "lead" 954 | } 955 | ], 956 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 957 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 958 | "keywords": [ 959 | "coverage", 960 | "testing", 961 | "xunit" 962 | ], 963 | "time": "2015-10-06 15:47:00" 964 | }, 965 | { 966 | "name": "phpunit/php-file-iterator", 967 | "version": "1.4.1", 968 | "source": { 969 | "type": "git", 970 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 971 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 972 | }, 973 | "dist": { 974 | "type": "zip", 975 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 976 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 977 | "shasum": "" 978 | }, 979 | "require": { 980 | "php": ">=5.3.3" 981 | }, 982 | "type": "library", 983 | "extra": { 984 | "branch-alias": { 985 | "dev-master": "1.4.x-dev" 986 | } 987 | }, 988 | "autoload": { 989 | "classmap": [ 990 | "src/" 991 | ] 992 | }, 993 | "notification-url": "https://packagist.org/downloads/", 994 | "license": [ 995 | "BSD-3-Clause" 996 | ], 997 | "authors": [ 998 | { 999 | "name": "Sebastian Bergmann", 1000 | "email": "sb@sebastian-bergmann.de", 1001 | "role": "lead" 1002 | } 1003 | ], 1004 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1005 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1006 | "keywords": [ 1007 | "filesystem", 1008 | "iterator" 1009 | ], 1010 | "time": "2015-06-21 13:08:43" 1011 | }, 1012 | { 1013 | "name": "phpunit/php-text-template", 1014 | "version": "1.2.1", 1015 | "source": { 1016 | "type": "git", 1017 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1018 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 1019 | }, 1020 | "dist": { 1021 | "type": "zip", 1022 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1023 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1024 | "shasum": "" 1025 | }, 1026 | "require": { 1027 | "php": ">=5.3.3" 1028 | }, 1029 | "type": "library", 1030 | "autoload": { 1031 | "classmap": [ 1032 | "src/" 1033 | ] 1034 | }, 1035 | "notification-url": "https://packagist.org/downloads/", 1036 | "license": [ 1037 | "BSD-3-Clause" 1038 | ], 1039 | "authors": [ 1040 | { 1041 | "name": "Sebastian Bergmann", 1042 | "email": "sebastian@phpunit.de", 1043 | "role": "lead" 1044 | } 1045 | ], 1046 | "description": "Simple template engine.", 1047 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1048 | "keywords": [ 1049 | "template" 1050 | ], 1051 | "time": "2015-06-21 13:50:34" 1052 | }, 1053 | { 1054 | "name": "phpunit/php-timer", 1055 | "version": "1.0.7", 1056 | "source": { 1057 | "type": "git", 1058 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1059 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" 1060 | }, 1061 | "dist": { 1062 | "type": "zip", 1063 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 1064 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 1065 | "shasum": "" 1066 | }, 1067 | "require": { 1068 | "php": ">=5.3.3" 1069 | }, 1070 | "type": "library", 1071 | "autoload": { 1072 | "classmap": [ 1073 | "src/" 1074 | ] 1075 | }, 1076 | "notification-url": "https://packagist.org/downloads/", 1077 | "license": [ 1078 | "BSD-3-Clause" 1079 | ], 1080 | "authors": [ 1081 | { 1082 | "name": "Sebastian Bergmann", 1083 | "email": "sb@sebastian-bergmann.de", 1084 | "role": "lead" 1085 | } 1086 | ], 1087 | "description": "Utility class for timing", 1088 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1089 | "keywords": [ 1090 | "timer" 1091 | ], 1092 | "time": "2015-06-21 08:01:12" 1093 | }, 1094 | { 1095 | "name": "phpunit/php-token-stream", 1096 | "version": "1.4.8", 1097 | "source": { 1098 | "type": "git", 1099 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 1100 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 1101 | }, 1102 | "dist": { 1103 | "type": "zip", 1104 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1105 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1106 | "shasum": "" 1107 | }, 1108 | "require": { 1109 | "ext-tokenizer": "*", 1110 | "php": ">=5.3.3" 1111 | }, 1112 | "require-dev": { 1113 | "phpunit/phpunit": "~4.2" 1114 | }, 1115 | "type": "library", 1116 | "extra": { 1117 | "branch-alias": { 1118 | "dev-master": "1.4-dev" 1119 | } 1120 | }, 1121 | "autoload": { 1122 | "classmap": [ 1123 | "src/" 1124 | ] 1125 | }, 1126 | "notification-url": "https://packagist.org/downloads/", 1127 | "license": [ 1128 | "BSD-3-Clause" 1129 | ], 1130 | "authors": [ 1131 | { 1132 | "name": "Sebastian Bergmann", 1133 | "email": "sebastian@phpunit.de" 1134 | } 1135 | ], 1136 | "description": "Wrapper around PHP's tokenizer extension.", 1137 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1138 | "keywords": [ 1139 | "tokenizer" 1140 | ], 1141 | "time": "2015-09-15 10:49:45" 1142 | }, 1143 | { 1144 | "name": "phpunit/phpunit", 1145 | "version": "4.6.10", 1146 | "source": { 1147 | "type": "git", 1148 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1149 | "reference": "7b5fe98b28302a8b25693b2298bca74463336975" 1150 | }, 1151 | "dist": { 1152 | "type": "zip", 1153 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b5fe98b28302a8b25693b2298bca74463336975", 1154 | "reference": "7b5fe98b28302a8b25693b2298bca74463336975", 1155 | "shasum": "" 1156 | }, 1157 | "require": { 1158 | "ext-dom": "*", 1159 | "ext-json": "*", 1160 | "ext-pcre": "*", 1161 | "ext-reflection": "*", 1162 | "ext-spl": "*", 1163 | "php": ">=5.3.3", 1164 | "phpspec/prophecy": "~1.3,>=1.3.1", 1165 | "phpunit/php-code-coverage": "~2.0,>=2.0.11", 1166 | "phpunit/php-file-iterator": "~1.4", 1167 | "phpunit/php-text-template": "~1.2", 1168 | "phpunit/php-timer": "~1.0", 1169 | "phpunit/phpunit-mock-objects": "~2.3", 1170 | "sebastian/comparator": "~1.1", 1171 | "sebastian/diff": "~1.2", 1172 | "sebastian/environment": "~1.2", 1173 | "sebastian/exporter": "~1.2", 1174 | "sebastian/global-state": "~1.0", 1175 | "sebastian/version": "~1.0", 1176 | "symfony/yaml": "~2.1|~3.0" 1177 | }, 1178 | "suggest": { 1179 | "phpunit/php-invoker": "~1.1" 1180 | }, 1181 | "bin": [ 1182 | "phpunit" 1183 | ], 1184 | "type": "library", 1185 | "extra": { 1186 | "branch-alias": { 1187 | "dev-master": "4.6.x-dev" 1188 | } 1189 | }, 1190 | "autoload": { 1191 | "classmap": [ 1192 | "src/" 1193 | ] 1194 | }, 1195 | "notification-url": "https://packagist.org/downloads/", 1196 | "license": [ 1197 | "BSD-3-Clause" 1198 | ], 1199 | "authors": [ 1200 | { 1201 | "name": "Sebastian Bergmann", 1202 | "email": "sebastian@phpunit.de", 1203 | "role": "lead" 1204 | } 1205 | ], 1206 | "description": "The PHP Unit Testing framework.", 1207 | "homepage": "https://phpunit.de/", 1208 | "keywords": [ 1209 | "phpunit", 1210 | "testing", 1211 | "xunit" 1212 | ], 1213 | "time": "2015-06-03 05:03:30" 1214 | }, 1215 | { 1216 | "name": "phpunit/phpunit-mock-objects", 1217 | "version": "2.3.8", 1218 | "source": { 1219 | "type": "git", 1220 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1221 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 1222 | }, 1223 | "dist": { 1224 | "type": "zip", 1225 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1226 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1227 | "shasum": "" 1228 | }, 1229 | "require": { 1230 | "doctrine/instantiator": "^1.0.2", 1231 | "php": ">=5.3.3", 1232 | "phpunit/php-text-template": "~1.2", 1233 | "sebastian/exporter": "~1.2" 1234 | }, 1235 | "require-dev": { 1236 | "phpunit/phpunit": "~4.4" 1237 | }, 1238 | "suggest": { 1239 | "ext-soap": "*" 1240 | }, 1241 | "type": "library", 1242 | "extra": { 1243 | "branch-alias": { 1244 | "dev-master": "2.3.x-dev" 1245 | } 1246 | }, 1247 | "autoload": { 1248 | "classmap": [ 1249 | "src/" 1250 | ] 1251 | }, 1252 | "notification-url": "https://packagist.org/downloads/", 1253 | "license": [ 1254 | "BSD-3-Clause" 1255 | ], 1256 | "authors": [ 1257 | { 1258 | "name": "Sebastian Bergmann", 1259 | "email": "sb@sebastian-bergmann.de", 1260 | "role": "lead" 1261 | } 1262 | ], 1263 | "description": "Mock Object library for PHPUnit", 1264 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1265 | "keywords": [ 1266 | "mock", 1267 | "xunit" 1268 | ], 1269 | "time": "2015-10-02 06:51:40" 1270 | }, 1271 | { 1272 | "name": "react/promise", 1273 | "version": "v2.2.1", 1274 | "source": { 1275 | "type": "git", 1276 | "url": "https://github.com/reactphp/promise.git", 1277 | "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627" 1278 | }, 1279 | "dist": { 1280 | "type": "zip", 1281 | "url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627", 1282 | "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627", 1283 | "shasum": "" 1284 | }, 1285 | "require": { 1286 | "php": ">=5.4.0" 1287 | }, 1288 | "type": "library", 1289 | "extra": { 1290 | "branch-alias": { 1291 | "dev-master": "2.0-dev" 1292 | } 1293 | }, 1294 | "autoload": { 1295 | "psr-4": { 1296 | "React\\Promise\\": "src/" 1297 | }, 1298 | "files": [ 1299 | "src/functions_include.php" 1300 | ] 1301 | }, 1302 | "notification-url": "https://packagist.org/downloads/", 1303 | "license": [ 1304 | "MIT" 1305 | ], 1306 | "authors": [ 1307 | { 1308 | "name": "Jan Sorgalla", 1309 | "email": "jsorgalla@gmail.com" 1310 | } 1311 | ], 1312 | "description": "A lightweight implementation of CommonJS Promises/A for PHP", 1313 | "time": "2015-07-03 13:48:55" 1314 | }, 1315 | { 1316 | "name": "sebastian/comparator", 1317 | "version": "1.2.0", 1318 | "source": { 1319 | "type": "git", 1320 | "url": "https://github.com/sebastianbergmann/comparator.git", 1321 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 1322 | }, 1323 | "dist": { 1324 | "type": "zip", 1325 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 1326 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 1327 | "shasum": "" 1328 | }, 1329 | "require": { 1330 | "php": ">=5.3.3", 1331 | "sebastian/diff": "~1.2", 1332 | "sebastian/exporter": "~1.2" 1333 | }, 1334 | "require-dev": { 1335 | "phpunit/phpunit": "~4.4" 1336 | }, 1337 | "type": "library", 1338 | "extra": { 1339 | "branch-alias": { 1340 | "dev-master": "1.2.x-dev" 1341 | } 1342 | }, 1343 | "autoload": { 1344 | "classmap": [ 1345 | "src/" 1346 | ] 1347 | }, 1348 | "notification-url": "https://packagist.org/downloads/", 1349 | "license": [ 1350 | "BSD-3-Clause" 1351 | ], 1352 | "authors": [ 1353 | { 1354 | "name": "Jeff Welch", 1355 | "email": "whatthejeff@gmail.com" 1356 | }, 1357 | { 1358 | "name": "Volker Dusch", 1359 | "email": "github@wallbash.com" 1360 | }, 1361 | { 1362 | "name": "Bernhard Schussek", 1363 | "email": "bschussek@2bepublished.at" 1364 | }, 1365 | { 1366 | "name": "Sebastian Bergmann", 1367 | "email": "sebastian@phpunit.de" 1368 | } 1369 | ], 1370 | "description": "Provides the functionality to compare PHP values for equality", 1371 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1372 | "keywords": [ 1373 | "comparator", 1374 | "compare", 1375 | "equality" 1376 | ], 1377 | "time": "2015-07-26 15:48:44" 1378 | }, 1379 | { 1380 | "name": "sebastian/diff", 1381 | "version": "1.3.0", 1382 | "source": { 1383 | "type": "git", 1384 | "url": "https://github.com/sebastianbergmann/diff.git", 1385 | "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" 1386 | }, 1387 | "dist": { 1388 | "type": "zip", 1389 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", 1390 | "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", 1391 | "shasum": "" 1392 | }, 1393 | "require": { 1394 | "php": ">=5.3.3" 1395 | }, 1396 | "require-dev": { 1397 | "phpunit/phpunit": "~4.2" 1398 | }, 1399 | "type": "library", 1400 | "extra": { 1401 | "branch-alias": { 1402 | "dev-master": "1.3-dev" 1403 | } 1404 | }, 1405 | "autoload": { 1406 | "classmap": [ 1407 | "src/" 1408 | ] 1409 | }, 1410 | "notification-url": "https://packagist.org/downloads/", 1411 | "license": [ 1412 | "BSD-3-Clause" 1413 | ], 1414 | "authors": [ 1415 | { 1416 | "name": "Kore Nordmann", 1417 | "email": "mail@kore-nordmann.de" 1418 | }, 1419 | { 1420 | "name": "Sebastian Bergmann", 1421 | "email": "sebastian@phpunit.de" 1422 | } 1423 | ], 1424 | "description": "Diff implementation", 1425 | "homepage": "http://www.github.com/sebastianbergmann/diff", 1426 | "keywords": [ 1427 | "diff" 1428 | ], 1429 | "time": "2015-02-22 15:13:53" 1430 | }, 1431 | { 1432 | "name": "sebastian/environment", 1433 | "version": "1.3.2", 1434 | "source": { 1435 | "type": "git", 1436 | "url": "https://github.com/sebastianbergmann/environment.git", 1437 | "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" 1438 | }, 1439 | "dist": { 1440 | "type": "zip", 1441 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", 1442 | "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", 1443 | "shasum": "" 1444 | }, 1445 | "require": { 1446 | "php": ">=5.3.3" 1447 | }, 1448 | "require-dev": { 1449 | "phpunit/phpunit": "~4.4" 1450 | }, 1451 | "type": "library", 1452 | "extra": { 1453 | "branch-alias": { 1454 | "dev-master": "1.3.x-dev" 1455 | } 1456 | }, 1457 | "autoload": { 1458 | "classmap": [ 1459 | "src/" 1460 | ] 1461 | }, 1462 | "notification-url": "https://packagist.org/downloads/", 1463 | "license": [ 1464 | "BSD-3-Clause" 1465 | ], 1466 | "authors": [ 1467 | { 1468 | "name": "Sebastian Bergmann", 1469 | "email": "sebastian@phpunit.de" 1470 | } 1471 | ], 1472 | "description": "Provides functionality to handle HHVM/PHP environments", 1473 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1474 | "keywords": [ 1475 | "Xdebug", 1476 | "environment", 1477 | "hhvm" 1478 | ], 1479 | "time": "2015-08-03 06:14:51" 1480 | }, 1481 | { 1482 | "name": "sebastian/exporter", 1483 | "version": "1.2.1", 1484 | "source": { 1485 | "type": "git", 1486 | "url": "https://github.com/sebastianbergmann/exporter.git", 1487 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e" 1488 | }, 1489 | "dist": { 1490 | "type": "zip", 1491 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", 1492 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e", 1493 | "shasum": "" 1494 | }, 1495 | "require": { 1496 | "php": ">=5.3.3", 1497 | "sebastian/recursion-context": "~1.0" 1498 | }, 1499 | "require-dev": { 1500 | "phpunit/phpunit": "~4.4" 1501 | }, 1502 | "type": "library", 1503 | "extra": { 1504 | "branch-alias": { 1505 | "dev-master": "1.2.x-dev" 1506 | } 1507 | }, 1508 | "autoload": { 1509 | "classmap": [ 1510 | "src/" 1511 | ] 1512 | }, 1513 | "notification-url": "https://packagist.org/downloads/", 1514 | "license": [ 1515 | "BSD-3-Clause" 1516 | ], 1517 | "authors": [ 1518 | { 1519 | "name": "Jeff Welch", 1520 | "email": "whatthejeff@gmail.com" 1521 | }, 1522 | { 1523 | "name": "Volker Dusch", 1524 | "email": "github@wallbash.com" 1525 | }, 1526 | { 1527 | "name": "Bernhard Schussek", 1528 | "email": "bschussek@2bepublished.at" 1529 | }, 1530 | { 1531 | "name": "Sebastian Bergmann", 1532 | "email": "sebastian@phpunit.de" 1533 | }, 1534 | { 1535 | "name": "Adam Harvey", 1536 | "email": "aharvey@php.net" 1537 | } 1538 | ], 1539 | "description": "Provides the functionality to export PHP variables for visualization", 1540 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1541 | "keywords": [ 1542 | "export", 1543 | "exporter" 1544 | ], 1545 | "time": "2015-06-21 07:55:53" 1546 | }, 1547 | { 1548 | "name": "sebastian/global-state", 1549 | "version": "1.1.1", 1550 | "source": { 1551 | "type": "git", 1552 | "url": "https://github.com/sebastianbergmann/global-state.git", 1553 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1554 | }, 1555 | "dist": { 1556 | "type": "zip", 1557 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1558 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1559 | "shasum": "" 1560 | }, 1561 | "require": { 1562 | "php": ">=5.3.3" 1563 | }, 1564 | "require-dev": { 1565 | "phpunit/phpunit": "~4.2" 1566 | }, 1567 | "suggest": { 1568 | "ext-uopz": "*" 1569 | }, 1570 | "type": "library", 1571 | "extra": { 1572 | "branch-alias": { 1573 | "dev-master": "1.0-dev" 1574 | } 1575 | }, 1576 | "autoload": { 1577 | "classmap": [ 1578 | "src/" 1579 | ] 1580 | }, 1581 | "notification-url": "https://packagist.org/downloads/", 1582 | "license": [ 1583 | "BSD-3-Clause" 1584 | ], 1585 | "authors": [ 1586 | { 1587 | "name": "Sebastian Bergmann", 1588 | "email": "sebastian@phpunit.de" 1589 | } 1590 | ], 1591 | "description": "Snapshotting of global state", 1592 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1593 | "keywords": [ 1594 | "global state" 1595 | ], 1596 | "time": "2015-10-12 03:26:01" 1597 | }, 1598 | { 1599 | "name": "sebastian/recursion-context", 1600 | "version": "1.0.1", 1601 | "source": { 1602 | "type": "git", 1603 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1604 | "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" 1605 | }, 1606 | "dist": { 1607 | "type": "zip", 1608 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", 1609 | "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", 1610 | "shasum": "" 1611 | }, 1612 | "require": { 1613 | "php": ">=5.3.3" 1614 | }, 1615 | "require-dev": { 1616 | "phpunit/phpunit": "~4.4" 1617 | }, 1618 | "type": "library", 1619 | "extra": { 1620 | "branch-alias": { 1621 | "dev-master": "1.0.x-dev" 1622 | } 1623 | }, 1624 | "autoload": { 1625 | "classmap": [ 1626 | "src/" 1627 | ] 1628 | }, 1629 | "notification-url": "https://packagist.org/downloads/", 1630 | "license": [ 1631 | "BSD-3-Clause" 1632 | ], 1633 | "authors": [ 1634 | { 1635 | "name": "Jeff Welch", 1636 | "email": "whatthejeff@gmail.com" 1637 | }, 1638 | { 1639 | "name": "Sebastian Bergmann", 1640 | "email": "sebastian@phpunit.de" 1641 | }, 1642 | { 1643 | "name": "Adam Harvey", 1644 | "email": "aharvey@php.net" 1645 | } 1646 | ], 1647 | "description": "Provides functionality to recursively process PHP variables", 1648 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1649 | "time": "2015-06-21 08:04:50" 1650 | }, 1651 | { 1652 | "name": "sebastian/version", 1653 | "version": "1.0.6", 1654 | "source": { 1655 | "type": "git", 1656 | "url": "https://github.com/sebastianbergmann/version.git", 1657 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1658 | }, 1659 | "dist": { 1660 | "type": "zip", 1661 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1662 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1663 | "shasum": "" 1664 | }, 1665 | "type": "library", 1666 | "autoload": { 1667 | "classmap": [ 1668 | "src/" 1669 | ] 1670 | }, 1671 | "notification-url": "https://packagist.org/downloads/", 1672 | "license": [ 1673 | "BSD-3-Clause" 1674 | ], 1675 | "authors": [ 1676 | { 1677 | "name": "Sebastian Bergmann", 1678 | "email": "sebastian@phpunit.de", 1679 | "role": "lead" 1680 | } 1681 | ], 1682 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1683 | "homepage": "https://github.com/sebastianbergmann/version", 1684 | "time": "2015-06-21 13:59:46" 1685 | }, 1686 | { 1687 | "name": "symfony/browser-kit", 1688 | "version": "v2.8.0-BETA1", 1689 | "source": { 1690 | "type": "git", 1691 | "url": "https://github.com/symfony/browser-kit.git", 1692 | "reference": "589f32fe4f43155ea303d505171634c45f15e876" 1693 | }, 1694 | "dist": { 1695 | "type": "zip", 1696 | "url": "https://api.github.com/repos/symfony/browser-kit/zipball/589f32fe4f43155ea303d505171634c45f15e876", 1697 | "reference": "589f32fe4f43155ea303d505171634c45f15e876", 1698 | "shasum": "" 1699 | }, 1700 | "require": { 1701 | "php": ">=5.3.9", 1702 | "symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0" 1703 | }, 1704 | "require-dev": { 1705 | "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0", 1706 | "symfony/process": "~2.3.34|~2.7,>=2.7.6|~3.0.0" 1707 | }, 1708 | "suggest": { 1709 | "symfony/process": "" 1710 | }, 1711 | "type": "library", 1712 | "extra": { 1713 | "branch-alias": { 1714 | "dev-master": "2.8-dev" 1715 | } 1716 | }, 1717 | "autoload": { 1718 | "psr-4": { 1719 | "Symfony\\Component\\BrowserKit\\": "" 1720 | }, 1721 | "exclude-from-classmap": [ 1722 | "/Tests/" 1723 | ] 1724 | }, 1725 | "notification-url": "https://packagist.org/downloads/", 1726 | "license": [ 1727 | "MIT" 1728 | ], 1729 | "authors": [ 1730 | { 1731 | "name": "Fabien Potencier", 1732 | "email": "fabien@symfony.com" 1733 | }, 1734 | { 1735 | "name": "Symfony Community", 1736 | "homepage": "https://symfony.com/contributors" 1737 | } 1738 | ], 1739 | "description": "Symfony BrowserKit Component", 1740 | "homepage": "https://symfony.com", 1741 | "time": "2015-11-02 20:29:24" 1742 | }, 1743 | { 1744 | "name": "symfony/console", 1745 | "version": "v2.8.0-BETA1", 1746 | "source": { 1747 | "type": "git", 1748 | "url": "https://github.com/symfony/console.git", 1749 | "reference": "74bf9202a531cc6942454eb9e2dd1e13bde34a31" 1750 | }, 1751 | "dist": { 1752 | "type": "zip", 1753 | "url": "https://api.github.com/repos/symfony/console/zipball/74bf9202a531cc6942454eb9e2dd1e13bde34a31", 1754 | "reference": "74bf9202a531cc6942454eb9e2dd1e13bde34a31", 1755 | "shasum": "" 1756 | }, 1757 | "require": { 1758 | "php": ">=5.3.9", 1759 | "symfony/polyfill-mbstring": "~1.0" 1760 | }, 1761 | "require-dev": { 1762 | "psr/log": "~1.0", 1763 | "symfony/event-dispatcher": "~2.1|~3.0.0", 1764 | "symfony/process": "~2.1|~3.0.0" 1765 | }, 1766 | "suggest": { 1767 | "psr/log": "For using the console logger", 1768 | "symfony/event-dispatcher": "", 1769 | "symfony/process": "" 1770 | }, 1771 | "type": "library", 1772 | "extra": { 1773 | "branch-alias": { 1774 | "dev-master": "2.8-dev" 1775 | } 1776 | }, 1777 | "autoload": { 1778 | "psr-4": { 1779 | "Symfony\\Component\\Console\\": "" 1780 | }, 1781 | "exclude-from-classmap": [ 1782 | "/Tests/" 1783 | ] 1784 | }, 1785 | "notification-url": "https://packagist.org/downloads/", 1786 | "license": [ 1787 | "MIT" 1788 | ], 1789 | "authors": [ 1790 | { 1791 | "name": "Fabien Potencier", 1792 | "email": "fabien@symfony.com" 1793 | }, 1794 | { 1795 | "name": "Symfony Community", 1796 | "homepage": "https://symfony.com/contributors" 1797 | } 1798 | ], 1799 | "description": "Symfony Console Component", 1800 | "homepage": "https://symfony.com", 1801 | "time": "2015-11-04 00:47:19" 1802 | }, 1803 | { 1804 | "name": "symfony/css-selector", 1805 | "version": "v2.8.0-BETA1", 1806 | "source": { 1807 | "type": "git", 1808 | "url": "https://github.com/symfony/css-selector.git", 1809 | "reference": "b600fec37c0efca08046d481d79e7eabc07108ff" 1810 | }, 1811 | "dist": { 1812 | "type": "zip", 1813 | "url": "https://api.github.com/repos/symfony/css-selector/zipball/b600fec37c0efca08046d481d79e7eabc07108ff", 1814 | "reference": "b600fec37c0efca08046d481d79e7eabc07108ff", 1815 | "shasum": "" 1816 | }, 1817 | "require": { 1818 | "php": ">=5.3.9" 1819 | }, 1820 | "type": "library", 1821 | "extra": { 1822 | "branch-alias": { 1823 | "dev-master": "2.8-dev" 1824 | } 1825 | }, 1826 | "autoload": { 1827 | "psr-4": { 1828 | "Symfony\\Component\\CssSelector\\": "" 1829 | }, 1830 | "exclude-from-classmap": [ 1831 | "/Tests/" 1832 | ] 1833 | }, 1834 | "notification-url": "https://packagist.org/downloads/", 1835 | "license": [ 1836 | "MIT" 1837 | ], 1838 | "authors": [ 1839 | { 1840 | "name": "Jean-François Simon", 1841 | "email": "jeanfrancois.simon@sensiolabs.com" 1842 | }, 1843 | { 1844 | "name": "Fabien Potencier", 1845 | "email": "fabien@symfony.com" 1846 | }, 1847 | { 1848 | "name": "Symfony Community", 1849 | "homepage": "https://symfony.com/contributors" 1850 | } 1851 | ], 1852 | "description": "Symfony CssSelector Component", 1853 | "homepage": "https://symfony.com", 1854 | "time": "2015-10-30 20:15:42" 1855 | }, 1856 | { 1857 | "name": "symfony/dom-crawler", 1858 | "version": "v2.8.0-BETA1", 1859 | "source": { 1860 | "type": "git", 1861 | "url": "https://github.com/symfony/dom-crawler.git", 1862 | "reference": "740c98235f5b6e2b0b13df2fb97c7a1c7d1a18fc" 1863 | }, 1864 | "dist": { 1865 | "type": "zip", 1866 | "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/740c98235f5b6e2b0b13df2fb97c7a1c7d1a18fc", 1867 | "reference": "740c98235f5b6e2b0b13df2fb97c7a1c7d1a18fc", 1868 | "shasum": "" 1869 | }, 1870 | "require": { 1871 | "php": ">=5.3.9", 1872 | "symfony/polyfill-mbstring": "~1.0" 1873 | }, 1874 | "require-dev": { 1875 | "symfony/css-selector": "~2.8|~3.0.0" 1876 | }, 1877 | "suggest": { 1878 | "symfony/css-selector": "" 1879 | }, 1880 | "type": "library", 1881 | "extra": { 1882 | "branch-alias": { 1883 | "dev-master": "2.8-dev" 1884 | } 1885 | }, 1886 | "autoload": { 1887 | "psr-4": { 1888 | "Symfony\\Component\\DomCrawler\\": "" 1889 | }, 1890 | "exclude-from-classmap": [ 1891 | "/Tests/" 1892 | ] 1893 | }, 1894 | "notification-url": "https://packagist.org/downloads/", 1895 | "license": [ 1896 | "MIT" 1897 | ], 1898 | "authors": [ 1899 | { 1900 | "name": "Fabien Potencier", 1901 | "email": "fabien@symfony.com" 1902 | }, 1903 | { 1904 | "name": "Symfony Community", 1905 | "homepage": "https://symfony.com/contributors" 1906 | } 1907 | ], 1908 | "description": "Symfony DomCrawler Component", 1909 | "homepage": "https://symfony.com", 1910 | "time": "2015-11-02 20:29:39" 1911 | }, 1912 | { 1913 | "name": "symfony/event-dispatcher", 1914 | "version": "v2.8.0-BETA1", 1915 | "source": { 1916 | "type": "git", 1917 | "url": "https://github.com/symfony/event-dispatcher.git", 1918 | "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" 1919 | }, 1920 | "dist": { 1921 | "type": "zip", 1922 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", 1923 | "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", 1924 | "shasum": "" 1925 | }, 1926 | "require": { 1927 | "php": ">=5.3.9" 1928 | }, 1929 | "require-dev": { 1930 | "psr/log": "~1.0", 1931 | "symfony/config": "~2.0,>=2.0.5|~3.0.0", 1932 | "symfony/dependency-injection": "~2.6|~3.0.0", 1933 | "symfony/expression-language": "~2.6|~3.0.0", 1934 | "symfony/stopwatch": "~2.3|~3.0.0" 1935 | }, 1936 | "suggest": { 1937 | "symfony/dependency-injection": "", 1938 | "symfony/http-kernel": "" 1939 | }, 1940 | "type": "library", 1941 | "extra": { 1942 | "branch-alias": { 1943 | "dev-master": "2.8-dev" 1944 | } 1945 | }, 1946 | "autoload": { 1947 | "psr-4": { 1948 | "Symfony\\Component\\EventDispatcher\\": "" 1949 | }, 1950 | "exclude-from-classmap": [ 1951 | "/Tests/" 1952 | ] 1953 | }, 1954 | "notification-url": "https://packagist.org/downloads/", 1955 | "license": [ 1956 | "MIT" 1957 | ], 1958 | "authors": [ 1959 | { 1960 | "name": "Fabien Potencier", 1961 | "email": "fabien@symfony.com" 1962 | }, 1963 | { 1964 | "name": "Symfony Community", 1965 | "homepage": "https://symfony.com/contributors" 1966 | } 1967 | ], 1968 | "description": "Symfony EventDispatcher Component", 1969 | "homepage": "https://symfony.com", 1970 | "time": "2015-10-30 20:15:42" 1971 | }, 1972 | { 1973 | "name": "symfony/finder", 1974 | "version": "v2.8.0-BETA1", 1975 | "source": { 1976 | "type": "git", 1977 | "url": "https://github.com/symfony/finder.git", 1978 | "reference": "ead9b07af4ba77b6507bee697396a5c79e633f08" 1979 | }, 1980 | "dist": { 1981 | "type": "zip", 1982 | "url": "https://api.github.com/repos/symfony/finder/zipball/ead9b07af4ba77b6507bee697396a5c79e633f08", 1983 | "reference": "ead9b07af4ba77b6507bee697396a5c79e633f08", 1984 | "shasum": "" 1985 | }, 1986 | "require": { 1987 | "php": ">=5.3.9" 1988 | }, 1989 | "type": "library", 1990 | "extra": { 1991 | "branch-alias": { 1992 | "dev-master": "2.8-dev" 1993 | } 1994 | }, 1995 | "autoload": { 1996 | "psr-4": { 1997 | "Symfony\\Component\\Finder\\": "" 1998 | }, 1999 | "exclude-from-classmap": [ 2000 | "/Tests/" 2001 | ] 2002 | }, 2003 | "notification-url": "https://packagist.org/downloads/", 2004 | "license": [ 2005 | "MIT" 2006 | ], 2007 | "authors": [ 2008 | { 2009 | "name": "Fabien Potencier", 2010 | "email": "fabien@symfony.com" 2011 | }, 2012 | { 2013 | "name": "Symfony Community", 2014 | "homepage": "https://symfony.com/contributors" 2015 | } 2016 | ], 2017 | "description": "Symfony Finder Component", 2018 | "homepage": "https://symfony.com", 2019 | "time": "2015-10-30 20:15:42" 2020 | }, 2021 | { 2022 | "name": "symfony/polyfill-mbstring", 2023 | "version": "v1.0.0", 2024 | "source": { 2025 | "type": "git", 2026 | "url": "https://github.com/symfony/polyfill-mbstring.git", 2027 | "reference": "0b6a8940385311a24e060ec1fe35680e17c74497" 2028 | }, 2029 | "dist": { 2030 | "type": "zip", 2031 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497", 2032 | "reference": "0b6a8940385311a24e060ec1fe35680e17c74497", 2033 | "shasum": "" 2034 | }, 2035 | "require": { 2036 | "php": ">=5.3.3" 2037 | }, 2038 | "type": "library", 2039 | "extra": { 2040 | "branch-alias": { 2041 | "dev-master": "1.0-dev" 2042 | } 2043 | }, 2044 | "autoload": { 2045 | "psr-4": { 2046 | "Symfony\\Polyfill\\Mbstring\\": "" 2047 | }, 2048 | "files": [ 2049 | "bootstrap.php" 2050 | ] 2051 | }, 2052 | "notification-url": "https://packagist.org/downloads/", 2053 | "license": [ 2054 | "MIT" 2055 | ], 2056 | "authors": [ 2057 | { 2058 | "name": "Nicolas Grekas", 2059 | "email": "p@tchwork.com" 2060 | }, 2061 | { 2062 | "name": "Symfony Community", 2063 | "homepage": "https://symfony.com/contributors" 2064 | } 2065 | ], 2066 | "description": "Symfony polyfill for the Mbstring extension", 2067 | "homepage": "https://symfony.com", 2068 | "keywords": [ 2069 | "compatibility", 2070 | "mbstring", 2071 | "polyfill", 2072 | "portable", 2073 | "shim" 2074 | ], 2075 | "time": "2015-11-04 20:28:58" 2076 | }, 2077 | { 2078 | "name": "symfony/yaml", 2079 | "version": "v2.8.0-BETA1", 2080 | "source": { 2081 | "type": "git", 2082 | "url": "https://github.com/symfony/yaml.git", 2083 | "reference": "5ff00ea2999343d42398fcb793bbfc64c92235ff" 2084 | }, 2085 | "dist": { 2086 | "type": "zip", 2087 | "url": "https://api.github.com/repos/symfony/yaml/zipball/5ff00ea2999343d42398fcb793bbfc64c92235ff", 2088 | "reference": "5ff00ea2999343d42398fcb793bbfc64c92235ff", 2089 | "shasum": "" 2090 | }, 2091 | "require": { 2092 | "php": ">=5.3.9" 2093 | }, 2094 | "type": "library", 2095 | "extra": { 2096 | "branch-alias": { 2097 | "dev-master": "2.8-dev" 2098 | } 2099 | }, 2100 | "autoload": { 2101 | "psr-4": { 2102 | "Symfony\\Component\\Yaml\\": "" 2103 | }, 2104 | "exclude-from-classmap": [ 2105 | "/Tests/" 2106 | ] 2107 | }, 2108 | "notification-url": "https://packagist.org/downloads/", 2109 | "license": [ 2110 | "MIT" 2111 | ], 2112 | "authors": [ 2113 | { 2114 | "name": "Fabien Potencier", 2115 | "email": "fabien@symfony.com" 2116 | }, 2117 | { 2118 | "name": "Symfony Community", 2119 | "homepage": "https://symfony.com/contributors" 2120 | } 2121 | ], 2122 | "description": "Symfony Yaml Component", 2123 | "homepage": "https://symfony.com", 2124 | "time": "2015-11-05 09:04:44" 2125 | }, 2126 | { 2127 | "name": "yiisoft/yii2-codeception", 2128 | "version": "2.0.4", 2129 | "source": { 2130 | "type": "git", 2131 | "url": "https://github.com/yiisoft/yii2-codeception.git", 2132 | "reference": "de5007e7a99359597abbfe1c88dca3ce620061c5" 2133 | }, 2134 | "dist": { 2135 | "type": "zip", 2136 | "url": "https://api.github.com/repos/yiisoft/yii2-codeception/zipball/de5007e7a99359597abbfe1c88dca3ce620061c5", 2137 | "reference": "de5007e7a99359597abbfe1c88dca3ce620061c5", 2138 | "shasum": "" 2139 | }, 2140 | "require": { 2141 | "yiisoft/yii2": ">=2.0.4" 2142 | }, 2143 | "type": "yii2-extension", 2144 | "extra": { 2145 | "branch-alias": { 2146 | "dev-master": "2.0.x-dev" 2147 | } 2148 | }, 2149 | "autoload": { 2150 | "psr-4": { 2151 | "yii\\codeception\\": "" 2152 | } 2153 | }, 2154 | "notification-url": "https://packagist.org/downloads/", 2155 | "license": [ 2156 | "BSD-3-Clause" 2157 | ], 2158 | "authors": [ 2159 | { 2160 | "name": "Mark Jebri", 2161 | "email": "mark.github@yandex.ru" 2162 | } 2163 | ], 2164 | "description": "The Codeception integration for the Yii framework", 2165 | "keywords": [ 2166 | "codeception", 2167 | "yii2" 2168 | ], 2169 | "time": "2015-05-10 22:08:30" 2170 | }, 2171 | { 2172 | "name": "yiisoft/yii2-redis", 2173 | "version": "2.0.4", 2174 | "source": { 2175 | "type": "git", 2176 | "url": "https://github.com/yiisoft/yii2-redis.git", 2177 | "reference": "af2c2f91cd61c201c537d18f9c2338258c821918" 2178 | }, 2179 | "dist": { 2180 | "type": "zip", 2181 | "url": "https://api.github.com/repos/yiisoft/yii2-redis/zipball/af2c2f91cd61c201c537d18f9c2338258c821918", 2182 | "reference": "af2c2f91cd61c201c537d18f9c2338258c821918", 2183 | "shasum": "" 2184 | }, 2185 | "require": { 2186 | "yiisoft/yii2": ">=2.0.4" 2187 | }, 2188 | "type": "yii2-extension", 2189 | "extra": { 2190 | "branch-alias": { 2191 | "dev-master": "2.0.x-dev" 2192 | } 2193 | }, 2194 | "autoload": { 2195 | "psr-4": { 2196 | "yii\\redis\\": "" 2197 | } 2198 | }, 2199 | "notification-url": "https://packagist.org/downloads/", 2200 | "license": [ 2201 | "BSD-3-Clause" 2202 | ], 2203 | "authors": [ 2204 | { 2205 | "name": "Carsten Brandt", 2206 | "email": "mail@cebe.cc" 2207 | } 2208 | ], 2209 | "description": "Redis Cache, Session and ActiveRecord for the Yii framework", 2210 | "keywords": [ 2211 | "active-record", 2212 | "cache", 2213 | "redis", 2214 | "session", 2215 | "yii2" 2216 | ], 2217 | "time": "2015-05-10 22:10:19" 2218 | } 2219 | ], 2220 | "aliases": [], 2221 | "minimum-stability": "alpha", 2222 | "stability-flags": { 2223 | "pdezwart/php-amqp": 20, 2224 | "kriswallsmith/spork": 20 2225 | }, 2226 | "prefer-stable": false, 2227 | "prefer-lowest": false, 2228 | "platform": { 2229 | "php": ">=5.4.0" 2230 | }, 2231 | "platform-dev": [] 2232 | } 2233 | --------------------------------------------------------------------------------