diff --git a/.htaccess b/.htaccess
new file mode 100644
index 00000000..317d963b
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,9 @@
+
+ Options -MultiViews
+
+ RewriteEngine On
+ #RewriteBase /var/www/teste/
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^ index.php [QSA,L]
+
diff --git a/composer.json b/composer.json
new file mode 100644
index 00000000..be665ae6
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "silex/silex": "~2.0"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 00000000..2eed6fe6
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,593 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "8d4b4feb048277b50f1d95a289dad3e0",
+ "content-hash": "85677501dca45c0b473c524c2f1a82b0",
+ "packages": [
+ {
+ "name": "pimple/pimple",
+ "version": "v3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Pimple.git",
+ "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
+ "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Pimple": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Pimple, a simple Dependency Injection Container",
+ "homepage": "http://pimple.sensiolabs.org",
+ "keywords": [
+ "container",
+ "dependency injection"
+ ],
+ "time": "2015-09-11 15:10:35"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2016-10-10 12:19:37"
+ },
+ {
+ "name": "silex/silex",
+ "version": "v2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Silex.git",
+ "reference": "d5a9d9af14a1424ddecc3da481769cf64e7d3b34"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Silex/zipball/d5a9d9af14a1424ddecc3da481769cf64e7d3b34",
+ "reference": "d5a9d9af14a1424ddecc3da481769cf64e7d3b34",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "pimple/pimple": "~3.0",
+ "symfony/event-dispatcher": "~2.8|^3.0",
+ "symfony/http-foundation": "~2.8|^3.0",
+ "symfony/http-kernel": "~2.8|^3.0",
+ "symfony/routing": "~2.8|^3.0"
+ },
+ "replace": {
+ "silex/api": "self.version",
+ "silex/providers": "self.version"
+ },
+ "require-dev": {
+ "doctrine/dbal": "~2.2",
+ "monolog/monolog": "^1.4.1",
+ "swiftmailer/swiftmailer": "~5",
+ "symfony/asset": "~2.8|^3.0",
+ "symfony/browser-kit": "~2.8|^3.0",
+ "symfony/config": "~2.8|^3.0",
+ "symfony/css-selector": "~2.8|^3.0",
+ "symfony/debug": "~2.8|^3.0",
+ "symfony/doctrine-bridge": "~2.8|^3.0",
+ "symfony/dom-crawler": "~2.8|^3.0",
+ "symfony/expression-language": "~2.8|^3.0",
+ "symfony/finder": "~2.8|^3.0",
+ "symfony/form": "~2.8|^3.0",
+ "symfony/intl": "~2.8|^3.0",
+ "symfony/monolog-bridge": "~2.8|^3.0",
+ "symfony/options-resolver": "~2.8|^3.0",
+ "symfony/phpunit-bridge": "^3.2",
+ "symfony/process": "~2.8|^3.0",
+ "symfony/security": "~2.8|^3.0",
+ "symfony/serializer": "~2.8|^3.0",
+ "symfony/translation": "~2.8|^3.0",
+ "symfony/twig-bridge": "~2.8|^3.0",
+ "symfony/validator": "~2.8|^3.0",
+ "symfony/var-dumper": "~2.8|^3.0",
+ "symfony/web-link": "^3.3",
+ "twig/twig": "~1.28|~2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Silex\\": "src/Silex"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ }
+ ],
+ "description": "The PHP micro-framework based on the Symfony Components",
+ "homepage": "http://silex.sensiolabs.org",
+ "keywords": [
+ "microframework"
+ ],
+ "time": "2017-05-03 15:21:42"
+ },
+ {
+ "name": "symfony/debug",
+ "version": "v3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "e9c50482841ef696e8fa1470d950a79c8921f45d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/e9c50482841ef696e8fa1470d950a79c8921f45d",
+ "reference": "e9c50482841ef696e8fa1470d950a79c8921f45d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "psr/log": "~1.0"
+ },
+ "conflict": {
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+ },
+ "require-dev": {
+ "symfony/http-kernel": "~2.8|~3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Debug\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Debug Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-06-01 21:01:25"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "4054a102470665451108f9b59305c79176ef98f0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4054a102470665451108f9b59305c79176ef98f0",
+ "reference": "4054a102470665451108f9b59305c79176ef98f0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/dependency-injection": "~3.3",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/stopwatch": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-06-04 18:15:29"
+ },
+ {
+ "name": "symfony/http-foundation",
+ "version": "v3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "80eb5a1f968448b77da9e8b2c0827f6e8d767846"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/80eb5a1f968448b77da9e8b2c0827f6e8d767846",
+ "reference": "80eb5a1f968448b77da9e8b2c0827f6e8d767846",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.1"
+ },
+ "require-dev": {
+ "symfony/expression-language": "~2.8|~3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpFoundation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony HttpFoundation Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-06-05 13:06:51"
+ },
+ {
+ "name": "symfony/http-kernel",
+ "version": "v3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "be8280f7fa8e95b86514f1e1be997668a53b2888"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/be8280f7fa8e95b86514f1e1be997668a53b2888",
+ "reference": "be8280f7fa8e95b86514f1e1be997668a53b2888",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "psr/log": "~1.0",
+ "symfony/debug": "~2.8|~3.0",
+ "symfony/event-dispatcher": "~2.8|~3.0",
+ "symfony/http-foundation": "~3.3"
+ },
+ "conflict": {
+ "symfony/config": "<2.8",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/var-dumper": "<3.3",
+ "twig/twig": "<1.34|<2.4,>=2"
+ },
+ "require-dev": {
+ "psr/cache": "~1.0",
+ "symfony/browser-kit": "~2.8|~3.0",
+ "symfony/class-loader": "~2.8|~3.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/console": "~2.8|~3.0",
+ "symfony/css-selector": "~2.8|~3.0",
+ "symfony/dependency-injection": "~3.3",
+ "symfony/dom-crawler": "~2.8|~3.0",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/finder": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0",
+ "symfony/routing": "~2.8|~3.0",
+ "symfony/stopwatch": "~2.8|~3.0",
+ "symfony/templating": "~2.8|~3.0",
+ "symfony/translation": "~2.8|~3.0",
+ "symfony/var-dumper": "~3.3"
+ },
+ "suggest": {
+ "symfony/browser-kit": "",
+ "symfony/class-loader": "",
+ "symfony/config": "",
+ "symfony/console": "",
+ "symfony/dependency-injection": "",
+ "symfony/finder": "",
+ "symfony/var-dumper": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpKernel\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony HttpKernel Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-06-06 03:59:58"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "f29dca382a6485c3cbe6379f0c61230167681937"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937",
+ "reference": "f29dca382a6485c3cbe6379f0c61230167681937",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2017-06-09 14:24:12"
+ },
+ {
+ "name": "symfony/routing",
+ "version": "v3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "39804eeafea5cca851946e1eed122eb94459fdb4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/39804eeafea5cca851946e1eed122eb94459fdb4",
+ "reference": "39804eeafea5cca851946e1eed122eb94459fdb4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "conflict": {
+ "symfony/config": "<2.8",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/yaml": "<3.3"
+ },
+ "require-dev": {
+ "doctrine/annotations": "~1.0",
+ "doctrine/common": "~2.2",
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/dependency-injection": "~3.3",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/http-foundation": "~2.8|~3.0",
+ "symfony/yaml": "~3.3"
+ },
+ "suggest": {
+ "doctrine/annotations": "For using the annotation loader",
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/dependency-injection": "For loading routes from a service",
+ "symfony/expression-language": "For using expression matching",
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/yaml": "For using the YAML loader"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Routing\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Routing Component",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "router",
+ "routing",
+ "uri",
+ "url"
+ ],
+ "time": "2017-06-02 09:51:43"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": []
+}
diff --git a/composer.phar b/composer.phar
new file mode 100644
index 00000000..80004eda
Binary files /dev/null and b/composer.phar differ
diff --git a/db/ThiagoEvangelistaRamos.sql b/db/ThiagoEvangelistaRamos.sql
new file mode 100644
index 00000000..13f323ed
--- /dev/null
+++ b/db/ThiagoEvangelistaRamos.sql
@@ -0,0 +1,51 @@
+CREATE DATABASE video_repository_db;
+
+CREATE TABLE video (
+ `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(255) NOT NULL,
+ `category_id` BIGINT(20) NOT NULL,
+ `description` text NULL,
+ `filename` VARCHAR(255) NOT NULL,
+ `duration` time,
+ `active` VARCHAR(255) NOT NULL,
+ `creation_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `modification_date` datetime NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`) )
+ENGINE = InnoDB;
+
+
+CREATE TABLE category (
+ `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(255) NOT NULL,
+ `description` BIGINT(20) NOT NULL,
+ `active` VARCHAR(255) NOT NULL,
+ `creation_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `modification_date` datetime NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`) )
+ENGINE = InnoDB;
+
+CREATE TABLE user (
+ `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+ `name` VARCHAR(255) NOT NULL,
+ `email` VARCHAR(255) NOT NULL,
+ `active` VARCHAR(255) NOT NULL,
+ `creation_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `modification_date` datetime NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`) )
+ENGINE = InnoDB;
+
+
+CREATE TABLE user_access_token (
+ `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+ `user_id` BIGINT(20) NOT NULL,
+ `access_token` VARCHAR(255) NOT NULL,
+ `active` VARCHAR(255) NOT NULL,
+ `creation_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `modification_date` datetime NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`) )
+ENGINE = InnoDB;
+
+insert into user( name , email , active , creation_date ) values ( 'thiago', 'thiagoevangelista.contato@gmail.com' , 'yes', NOW());
+
+INSERT INTO user_access_token ( user_id , access_token , active, creation_date )
+VALUES (1, 'abcdefg' , 'yes' , NOW());
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 00000000..e0741fde
--- /dev/null
+++ b/vendor/autoload.php
@@ -0,0 +1,7 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier
+ * @author Jordi Boggiano
+ * @see http://www.php-fig.org/psr/psr-0/
+ * @see http://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+
+ private $classMapAuthoritative = false;
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 base directories
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
+ if ('\\' == $class[0]) {
+ $class = substr($class, 1);
+ }
+
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative) {
+ return false;
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if ($file === null && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if ($file === null) {
+ // Remember that this class does not exist.
+ return $this->classMap[$class] = false;
+ }
+
+ return $file;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE
new file mode 100644
index 00000000..1a281248
--- /dev/null
+++ b/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) 2016 Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 00000000..7a91153b
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,9 @@
+ $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 00000000..c3cd0229
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,10 @@
+ array($vendorDir . '/pimple/pimple/src'),
+);
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
new file mode 100644
index 00000000..a24f71fe
--- /dev/null
+++ b/vendor/composer/autoload_psr4.php
@@ -0,0 +1,17 @@
+ array($vendorDir . '/symfony/polyfill-mbstring'),
+ 'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
+ 'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
+ 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
+ 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
+ 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
+ 'Silex\\' => array($vendorDir . '/silex/silex/src/Silex'),
+ 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 00000000..ebd14970
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,70 @@
+= 50600 && !defined('HHVM_VERSION');
+ if ($useStaticLoader) {
+ require_once __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInitffc6f475c67d41d430373c18ea299e37::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInitffc6f475c67d41d430373c18ea299e37::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequireffc6f475c67d41d430373c18ea299e37($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequireffc6f475c67d41d430373c18ea299e37($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
+}
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
new file mode 100644
index 00000000..402cc136
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,84 @@
+ __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'S' =>
+ array (
+ 'Symfony\\Polyfill\\Mbstring\\' => 26,
+ 'Symfony\\Component\\Routing\\' => 26,
+ 'Symfony\\Component\\HttpKernel\\' => 29,
+ 'Symfony\\Component\\HttpFoundation\\' => 33,
+ 'Symfony\\Component\\EventDispatcher\\' => 34,
+ 'Symfony\\Component\\Debug\\' => 24,
+ 'Silex\\' => 6,
+ ),
+ 'P' =>
+ array (
+ 'Psr\\Log\\' => 8,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'Symfony\\Polyfill\\Mbstring\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
+ ),
+ 'Symfony\\Component\\Routing\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/routing',
+ ),
+ 'Symfony\\Component\\HttpKernel\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/http-kernel',
+ ),
+ 'Symfony\\Component\\HttpFoundation\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/http-foundation',
+ ),
+ 'Symfony\\Component\\EventDispatcher\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
+ ),
+ 'Symfony\\Component\\Debug\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/debug',
+ ),
+ 'Silex\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/silex/silex/src/Silex',
+ ),
+ 'Psr\\Log\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'P' =>
+ array (
+ 'Pimple' =>
+ array (
+ 0 => __DIR__ . '/..' . '/pimple/pimple/src',
+ ),
+ ),
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInitffc6f475c67d41d430373c18ea299e37::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitffc6f475c67d41d430373c18ea299e37::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInitffc6f475c67d41d430373c18ea299e37::$prefixesPsr0;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 00000000..496a1d14
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,594 @@
+[
+ {
+ "name": "symfony/routing",
+ "version": "v3.3.2",
+ "version_normalized": "3.3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "39804eeafea5cca851946e1eed122eb94459fdb4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/39804eeafea5cca851946e1eed122eb94459fdb4",
+ "reference": "39804eeafea5cca851946e1eed122eb94459fdb4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "conflict": {
+ "symfony/config": "<2.8",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/yaml": "<3.3"
+ },
+ "require-dev": {
+ "doctrine/annotations": "~1.0",
+ "doctrine/common": "~2.2",
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/dependency-injection": "~3.3",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/http-foundation": "~2.8|~3.0",
+ "symfony/yaml": "~3.3"
+ },
+ "suggest": {
+ "doctrine/annotations": "For using the annotation loader",
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/dependency-injection": "For loading routes from a service",
+ "symfony/expression-language": "For using expression matching",
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/yaml": "For using the YAML loader"
+ },
+ "time": "2017-06-02 09:51:43",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Routing\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Routing Component",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "router",
+ "routing",
+ "uri",
+ "url"
+ ]
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.4.0",
+ "version_normalized": "1.4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "f29dca382a6485c3cbe6379f0c61230167681937"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937",
+ "reference": "f29dca382a6485c3cbe6379f0c61230167681937",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "time": "2017-06-09 14:24:12",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ]
+ },
+ {
+ "name": "symfony/http-foundation",
+ "version": "v3.3.2",
+ "version_normalized": "3.3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "80eb5a1f968448b77da9e8b2c0827f6e8d767846"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/80eb5a1f968448b77da9e8b2c0827f6e8d767846",
+ "reference": "80eb5a1f968448b77da9e8b2c0827f6e8d767846",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.1"
+ },
+ "require-dev": {
+ "symfony/expression-language": "~2.8|~3.0"
+ },
+ "time": "2017-06-05 13:06:51",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpFoundation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony HttpFoundation Component",
+ "homepage": "https://symfony.com"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v3.3.2",
+ "version_normalized": "3.3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "4054a102470665451108f9b59305c79176ef98f0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4054a102470665451108f9b59305c79176ef98f0",
+ "reference": "4054a102470665451108f9b59305c79176ef98f0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/dependency-injection": "~3.3",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/stopwatch": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "time": "2017-06-04 18:15:29",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.2",
+ "version_normalized": "1.0.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "time": "2016-10-10 12:19:37",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ]
+ },
+ {
+ "name": "symfony/debug",
+ "version": "v3.3.2",
+ "version_normalized": "3.3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "e9c50482841ef696e8fa1470d950a79c8921f45d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/e9c50482841ef696e8fa1470d950a79c8921f45d",
+ "reference": "e9c50482841ef696e8fa1470d950a79c8921f45d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "psr/log": "~1.0"
+ },
+ "conflict": {
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+ },
+ "require-dev": {
+ "symfony/http-kernel": "~2.8|~3.0"
+ },
+ "time": "2017-06-01 21:01:25",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Debug\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Debug Component",
+ "homepage": "https://symfony.com"
+ },
+ {
+ "name": "symfony/http-kernel",
+ "version": "v3.3.2",
+ "version_normalized": "3.3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "be8280f7fa8e95b86514f1e1be997668a53b2888"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/be8280f7fa8e95b86514f1e1be997668a53b2888",
+ "reference": "be8280f7fa8e95b86514f1e1be997668a53b2888",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "psr/log": "~1.0",
+ "symfony/debug": "~2.8|~3.0",
+ "symfony/event-dispatcher": "~2.8|~3.0",
+ "symfony/http-foundation": "~3.3"
+ },
+ "conflict": {
+ "symfony/config": "<2.8",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/var-dumper": "<3.3",
+ "twig/twig": "<1.34|<2.4,>=2"
+ },
+ "require-dev": {
+ "psr/cache": "~1.0",
+ "symfony/browser-kit": "~2.8|~3.0",
+ "symfony/class-loader": "~2.8|~3.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/console": "~2.8|~3.0",
+ "symfony/css-selector": "~2.8|~3.0",
+ "symfony/dependency-injection": "~3.3",
+ "symfony/dom-crawler": "~2.8|~3.0",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/finder": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0",
+ "symfony/routing": "~2.8|~3.0",
+ "symfony/stopwatch": "~2.8|~3.0",
+ "symfony/templating": "~2.8|~3.0",
+ "symfony/translation": "~2.8|~3.0",
+ "symfony/var-dumper": "~3.3"
+ },
+ "suggest": {
+ "symfony/browser-kit": "",
+ "symfony/class-loader": "",
+ "symfony/config": "",
+ "symfony/console": "",
+ "symfony/dependency-injection": "",
+ "symfony/finder": "",
+ "symfony/var-dumper": ""
+ },
+ "time": "2017-06-06 03:59:58",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpKernel\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony HttpKernel Component",
+ "homepage": "https://symfony.com"
+ },
+ {
+ "name": "pimple/pimple",
+ "version": "v3.0.2",
+ "version_normalized": "3.0.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Pimple.git",
+ "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
+ "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "time": "2015-09-11 15:10:35",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Pimple": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Pimple, a simple Dependency Injection Container",
+ "homepage": "http://pimple.sensiolabs.org",
+ "keywords": [
+ "container",
+ "dependency injection"
+ ]
+ },
+ {
+ "name": "silex/silex",
+ "version": "v2.1.0",
+ "version_normalized": "2.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Silex.git",
+ "reference": "d5a9d9af14a1424ddecc3da481769cf64e7d3b34"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Silex/zipball/d5a9d9af14a1424ddecc3da481769cf64e7d3b34",
+ "reference": "d5a9d9af14a1424ddecc3da481769cf64e7d3b34",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "pimple/pimple": "~3.0",
+ "symfony/event-dispatcher": "~2.8|^3.0",
+ "symfony/http-foundation": "~2.8|^3.0",
+ "symfony/http-kernel": "~2.8|^3.0",
+ "symfony/routing": "~2.8|^3.0"
+ },
+ "replace": {
+ "silex/api": "self.version",
+ "silex/providers": "self.version"
+ },
+ "require-dev": {
+ "doctrine/dbal": "~2.2",
+ "monolog/monolog": "^1.4.1",
+ "swiftmailer/swiftmailer": "~5",
+ "symfony/asset": "~2.8|^3.0",
+ "symfony/browser-kit": "~2.8|^3.0",
+ "symfony/config": "~2.8|^3.0",
+ "symfony/css-selector": "~2.8|^3.0",
+ "symfony/debug": "~2.8|^3.0",
+ "symfony/doctrine-bridge": "~2.8|^3.0",
+ "symfony/dom-crawler": "~2.8|^3.0",
+ "symfony/expression-language": "~2.8|^3.0",
+ "symfony/finder": "~2.8|^3.0",
+ "symfony/form": "~2.8|^3.0",
+ "symfony/intl": "~2.8|^3.0",
+ "symfony/monolog-bridge": "~2.8|^3.0",
+ "symfony/options-resolver": "~2.8|^3.0",
+ "symfony/phpunit-bridge": "^3.2",
+ "symfony/process": "~2.8|^3.0",
+ "symfony/security": "~2.8|^3.0",
+ "symfony/serializer": "~2.8|^3.0",
+ "symfony/translation": "~2.8|^3.0",
+ "symfony/twig-bridge": "~2.8|^3.0",
+ "symfony/validator": "~2.8|^3.0",
+ "symfony/var-dumper": "~2.8|^3.0",
+ "symfony/web-link": "^3.3",
+ "twig/twig": "~1.28|~2.0"
+ },
+ "time": "2017-05-03 15:21:42",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Silex\\": "src/Silex"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ }
+ ],
+ "description": "The PHP micro-framework based on the Symfony Components",
+ "homepage": "http://silex.sensiolabs.org",
+ "keywords": [
+ "microframework"
+ ]
+ }
+]
diff --git a/vendor/pimple/pimple/.gitignore b/vendor/pimple/pimple/.gitignore
new file mode 100644
index 00000000..c089b095
--- /dev/null
+++ b/vendor/pimple/pimple/.gitignore
@@ -0,0 +1,3 @@
+phpunit.xml
+composer.lock
+/vendor/
diff --git a/vendor/pimple/pimple/.travis.yml b/vendor/pimple/pimple/.travis.yml
new file mode 100644
index 00000000..5f8bb7c9
--- /dev/null
+++ b/vendor/pimple/pimple/.travis.yml
@@ -0,0 +1,32 @@
+language: php
+
+env:
+ matrix:
+ - PIMPLE_EXT=no
+ - PIMPLE_EXT=yes
+ global:
+ - REPORT_EXIT_STATUS=1
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+
+before_script:
+ - composer self-update
+ - COMPOSER_ROOT_VERSION=dev-master composer dump-autoload
+ - if [ "$PIMPLE_EXT" == "yes" ]; then sh -c "cd ext/pimple && phpize && ./configure && make && sudo make install"; fi
+ - if [ "$PIMPLE_EXT" == "yes" ]; then echo "extension=pimple.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
+
+script:
+ - cd ext/pimple
+ - if [ "$PIMPLE_EXT" == "yes" ]; then yes n | make test | tee output ; grep -E 'Tests failed +. +0' output; fi
+ - cd ../..
+ - phpunit
+
+matrix:
+ exclude:
+ - php: hhvm
+ env: PIMPLE_EXT=yes
diff --git a/vendor/pimple/pimple/CHANGELOG b/vendor/pimple/pimple/CHANGELOG
new file mode 100644
index 00000000..cc679972
--- /dev/null
+++ b/vendor/pimple/pimple/CHANGELOG
@@ -0,0 +1,35 @@
+* 3.0.2 (2015-09-11)
+
+ * refactored the C extension
+ * minor non-significant changes
+
+* 3.0.1 (2015-07-30)
+
+ * simplified some code
+ * fixed a segfault in the C extension
+
+* 3.0.0 (2014-07-24)
+
+ * removed the Pimple class alias (use Pimple\Container instead)
+
+* 2.1.1 (2014-07-24)
+
+ * fixed compiler warnings for the C extension
+ * fixed code when dealing with circular references
+
+* 2.1.0 (2014-06-24)
+
+ * moved the Pimple to Pimple\Container (with a BC layer -- Pimple is now a
+ deprecated alias which will be removed in Pimple 3.0)
+ * added Pimple\ServiceProviderInterface (and Pimple::register())
+
+* 2.0.0 (2014-02-10)
+
+ * changed extend to automatically re-assign the extended service and keep it as shared or factory
+ (to keep BC, extend still returns the extended service)
+ * changed services to be shared by default (use factory() for factory
+ services)
+
+* 1.0.0
+
+ * initial version
diff --git a/vendor/pimple/pimple/LICENSE b/vendor/pimple/pimple/LICENSE
new file mode 100644
index 00000000..d7949e2f
--- /dev/null
+++ b/vendor/pimple/pimple/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2009-2015 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/pimple/pimple/README.rst b/vendor/pimple/pimple/README.rst
new file mode 100644
index 00000000..93fb35a8
--- /dev/null
+++ b/vendor/pimple/pimple/README.rst
@@ -0,0 +1,201 @@
+Pimple
+======
+
+.. caution::
+
+ This is the documentation for Pimple 3.x. If you are using Pimple 1.x, read
+ the `Pimple 1.x documentation`_. Reading the Pimple 1.x code is also a good
+ way to learn more about how to create a simple Dependency Injection
+ Container (recent versions of Pimple are more focused on performance).
+
+Pimple is a small Dependency Injection Container for PHP.
+
+Installation
+------------
+
+Before using Pimple in your project, add it to your ``composer.json`` file:
+
+.. code-block:: bash
+
+ $ ./composer.phar require pimple/pimple ~3.0
+
+Alternatively, Pimple is also available as a PHP C extension:
+
+.. code-block:: bash
+
+ $ git clone https://github.com/silexphp/Pimple
+ $ cd Pimple/ext/pimple
+ $ phpize
+ $ ./configure
+ $ make
+ $ make install
+
+Usage
+-----
+
+Creating a container is a matter of creating a ``Container`` instance:
+
+.. code-block:: php
+
+ use Pimple\Container;
+
+ $container = new Container();
+
+As many other dependency injection containers, Pimple manages two different
+kind of data: **services** and **parameters**.
+
+Defining Services
+~~~~~~~~~~~~~~~~~
+
+A service is an object that does something as part of a larger system. Examples
+of services: a database connection, a templating engine, or a mailer. Almost
+any **global** object can be a service.
+
+Services are defined by **anonymous functions** that return an instance of an
+object:
+
+.. code-block:: php
+
+ // define some services
+ $container['session_storage'] = function ($c) {
+ return new SessionStorage('SESSION_ID');
+ };
+
+ $container['session'] = function ($c) {
+ return new Session($c['session_storage']);
+ };
+
+Notice that the anonymous function has access to the current container
+instance, allowing references to other services or parameters.
+
+As objects are only created when you get them, the order of the definitions
+does not matter.
+
+Using the defined services is also very easy:
+
+.. code-block:: php
+
+ // get the session object
+ $session = $container['session'];
+
+ // the above call is roughly equivalent to the following code:
+ // $storage = new SessionStorage('SESSION_ID');
+ // $session = new Session($storage);
+
+Defining Factory Services
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, each time you get a service, Pimple returns the **same instance**
+of it. If you want a different instance to be returned for all calls, wrap your
+anonymous function with the ``factory()`` method
+
+.. code-block:: php
+
+ $container['session'] = $container->factory(function ($c) {
+ return new Session($c['session_storage']);
+ });
+
+Now, each call to ``$container['session']`` returns a new instance of the
+session.
+
+Defining Parameters
+~~~~~~~~~~~~~~~~~~~
+
+Defining a parameter allows to ease the configuration of your container from
+the outside and to store global values:
+
+.. code-block:: php
+
+ // define some parameters
+ $container['cookie_name'] = 'SESSION_ID';
+ $container['session_storage_class'] = 'SessionStorage';
+
+If you change the ``session_storage`` service definition like below:
+
+.. code-block:: php
+
+ $container['session_storage'] = function ($c) {
+ return new $c['session_storage_class']($c['cookie_name']);
+ };
+
+You can now easily change the cookie name by overriding the
+``session_storage_class`` parameter instead of redefining the service
+definition.
+
+Protecting Parameters
+~~~~~~~~~~~~~~~~~~~~~
+
+Because Pimple sees anonymous functions as service definitions, you need to
+wrap anonymous functions with the ``protect()`` method to store them as
+parameters:
+
+.. code-block:: php
+
+ $container['random_func'] = $container->protect(function () {
+ return rand();
+ });
+
+Modifying Services after Definition
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In some cases you may want to modify a service definition after it has been
+defined. You can use the ``extend()`` method to define additional code to be
+run on your service just after it is created:
+
+.. code-block:: php
+
+ $container['session_storage'] = function ($c) {
+ return new $c['session_storage_class']($c['cookie_name']);
+ };
+
+ $container->extend('session_storage', function ($storage, $c) {
+ $storage->...();
+
+ return $storage;
+ });
+
+The first argument is the name of the service to extend, the second a function
+that gets access to the object instance and the container.
+
+Extending a Container
+~~~~~~~~~~~~~~~~~~~~~
+
+If you use the same libraries over and over, you might want to reuse some
+services from one project to the next one; package your services into a
+**provider** by implementing ``Pimple\ServiceProviderInterface``:
+
+.. code-block:: php
+
+ use Pimple\Container;
+
+ class FooProvider implements Pimple\ServiceProviderInterface
+ {
+ public function register(Container $pimple)
+ {
+ // register some services and parameters
+ // on $pimple
+ }
+ }
+
+Then, register the provider on a Container:
+
+.. code-block:: php
+
+ $pimple->register(new FooProvider());
+
+Fetching the Service Creation Function
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you access an object, Pimple automatically calls the anonymous function
+that you defined, which creates the service object for you. If you want to get
+raw access to this function, you can use the ``raw()`` method:
+
+.. code-block:: php
+
+ $container['session'] = function ($c) {
+ return new Session($c['session_storage']);
+ };
+
+ $sessionFunction = $container->raw('session');
+
+.. _Pimple 1.x documentation: https://github.com/silexphp/Pimple/tree/1.1
diff --git a/vendor/pimple/pimple/composer.json b/vendor/pimple/pimple/composer.json
new file mode 100644
index 00000000..a5268f16
--- /dev/null
+++ b/vendor/pimple/pimple/composer.json
@@ -0,0 +1,25 @@
+{
+ "name": "pimple/pimple",
+ "type": "library",
+ "description": "Pimple, a simple Dependency Injection Container",
+ "keywords": ["dependency injection", "container"],
+ "homepage": "http://pimple.sensiolabs.org",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-0": { "Pimple": "src/" }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/pimple/pimple/ext/pimple/.gitignore b/vendor/pimple/pimple/ext/pimple/.gitignore
new file mode 100644
index 00000000..1861088a
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/.gitignore
@@ -0,0 +1,30 @@
+*.sw*
+.deps
+Makefile
+Makefile.fragments
+Makefile.global
+Makefile.objects
+acinclude.m4
+aclocal.m4
+build/
+config.cache
+config.guess
+config.h
+config.h.in
+config.log
+config.nice
+config.status
+config.sub
+configure
+configure.in
+install-sh
+libtool
+ltmain.sh
+missing
+mkinstalldirs
+run-tests.php
+*.loT
+.libs/
+modules/
+*.la
+*.lo
diff --git a/vendor/pimple/pimple/ext/pimple/README.md b/vendor/pimple/pimple/ext/pimple/README.md
new file mode 100644
index 00000000..7b39eb29
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/README.md
@@ -0,0 +1,12 @@
+This is Pimple 2 implemented in C
+
+* PHP >= 5.3
+* Not tested under Windows, might work
+
+Install
+=======
+
+ > phpize
+ > ./configure
+ > make
+ > make install
diff --git a/vendor/pimple/pimple/ext/pimple/config.m4 b/vendor/pimple/pimple/ext/pimple/config.m4
new file mode 100644
index 00000000..c9ba17dd
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/config.m4
@@ -0,0 +1,63 @@
+dnl $Id$
+dnl config.m4 for extension pimple
+
+dnl Comments in this file start with the string 'dnl'.
+dnl Remove where necessary. This file will not work
+dnl without editing.
+
+dnl If your extension references something external, use with:
+
+dnl PHP_ARG_WITH(pimple, for pimple support,
+dnl Make sure that the comment is aligned:
+dnl [ --with-pimple Include pimple support])
+
+dnl Otherwise use enable:
+
+PHP_ARG_ENABLE(pimple, whether to enable pimple support,
+dnl Make sure that the comment is aligned:
+[ --enable-pimple Enable pimple support])
+
+if test "$PHP_PIMPLE" != "no"; then
+ dnl Write more examples of tests here...
+
+ dnl # --with-pimple -> check with-path
+ dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
+ dnl SEARCH_FOR="/include/pimple.h" # you most likely want to change this
+ dnl if test -r $PHP_PIMPLE/$SEARCH_FOR; then # path given as parameter
+ dnl PIMPLE_DIR=$PHP_PIMPLE
+ dnl else # search default path list
+ dnl AC_MSG_CHECKING([for pimple files in default path])
+ dnl for i in $SEARCH_PATH ; do
+ dnl if test -r $i/$SEARCH_FOR; then
+ dnl PIMPLE_DIR=$i
+ dnl AC_MSG_RESULT(found in $i)
+ dnl fi
+ dnl done
+ dnl fi
+ dnl
+ dnl if test -z "$PIMPLE_DIR"; then
+ dnl AC_MSG_RESULT([not found])
+ dnl AC_MSG_ERROR([Please reinstall the pimple distribution])
+ dnl fi
+
+ dnl # --with-pimple -> add include path
+ dnl PHP_ADD_INCLUDE($PIMPLE_DIR/include)
+
+ dnl # --with-pimple -> check for lib and symbol presence
+ dnl LIBNAME=pimple # you may want to change this
+ dnl LIBSYMBOL=pimple # you most likely want to change this
+
+ dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
+ dnl [
+ dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $PIMPLE_DIR/lib, PIMPLE_SHARED_LIBADD)
+ dnl AC_DEFINE(HAVE_PIMPLELIB,1,[ ])
+ dnl ],[
+ dnl AC_MSG_ERROR([wrong pimple lib version or lib not found])
+ dnl ],[
+ dnl -L$PIMPLE_DIR/lib -lm
+ dnl ])
+ dnl
+ dnl PHP_SUBST(PIMPLE_SHARED_LIBADD)
+
+ PHP_NEW_EXTENSION(pimple, pimple.c, $ext_shared)
+fi
diff --git a/vendor/pimple/pimple/ext/pimple/config.w32 b/vendor/pimple/pimple/ext/pimple/config.w32
new file mode 100644
index 00000000..39857b32
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/config.w32
@@ -0,0 +1,13 @@
+// $Id$
+// vim:ft=javascript
+
+// If your extension references something external, use ARG_WITH
+// ARG_WITH("pimple", "for pimple support", "no");
+
+// Otherwise, use ARG_ENABLE
+// ARG_ENABLE("pimple", "enable pimple support", "no");
+
+if (PHP_PIMPLE != "no") {
+ EXTENSION("pimple", "pimple.c");
+}
+
diff --git a/vendor/pimple/pimple/ext/pimple/php_pimple.h b/vendor/pimple/pimple/ext/pimple/php_pimple.h
new file mode 100644
index 00000000..49431f08
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/php_pimple.h
@@ -0,0 +1,121 @@
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2014 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PHP_PIMPLE_H
+#define PHP_PIMPLE_H
+
+extern zend_module_entry pimple_module_entry;
+#define phpext_pimple_ptr &pimple_module_entry
+
+#ifdef PHP_WIN32
+# define PHP_PIMPLE_API __declspec(dllexport)
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define PHP_PIMPLE_API __attribute__ ((visibility("default")))
+#else
+# define PHP_PIMPLE_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#define PIMPLE_VERSION "3.0.2"
+#define PIMPLE_NS "Pimple"
+
+#define PIMPLE_DEFAULT_ZVAL_CACHE_NUM 5
+#define PIMPLE_DEFAULT_ZVAL_VALUES_NUM 10
+
+zend_module_entry *get_module(void);
+
+PHP_MINIT_FUNCTION(pimple);
+PHP_MINFO_FUNCTION(pimple);
+
+PHP_METHOD(Pimple, __construct);
+PHP_METHOD(Pimple, factory);
+PHP_METHOD(Pimple, protect);
+PHP_METHOD(Pimple, raw);
+PHP_METHOD(Pimple, extend);
+PHP_METHOD(Pimple, keys);
+PHP_METHOD(Pimple, register);
+PHP_METHOD(Pimple, offsetSet);
+PHP_METHOD(Pimple, offsetUnset);
+PHP_METHOD(Pimple, offsetGet);
+PHP_METHOD(Pimple, offsetExists);
+
+PHP_METHOD(PimpleClosure, invoker);
+
+typedef struct _pimple_bucket_value {
+ zval *value; /* Must be the first element */
+ zval *raw;
+ zend_object_handle handle_num;
+ enum {
+ PIMPLE_IS_PARAM = 0,
+ PIMPLE_IS_SERVICE = 2
+ } type;
+ zend_bool initialized;
+ zend_fcall_info_cache fcc;
+} pimple_bucket_value;
+
+typedef struct _pimple_object {
+ zend_object zobj;
+ HashTable values;
+ HashTable factories;
+ HashTable protected;
+} pimple_object;
+
+typedef struct _pimple_closure_object {
+ zend_object zobj;
+ zval *callable;
+ zval *factory;
+} pimple_closure_object;
+
+static const char sensiolabs_logo[] = "
";
+
+static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
+static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
+
+static void pimple_bucket_dtor(pimple_bucket_value *bucket);
+static void pimple_free_bucket(pimple_bucket_value *bucket);
+
+static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC);
+static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC);
+static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC);
+static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC);
+static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC);
+static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC);
+
+static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC);
+static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC);
+static zend_function *pimple_closure_get_constructor(zval * TSRMLS_DC);
+static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC);
+
+#ifdef ZTS
+#define PIMPLE_G(v) TSRMG(pimple_globals_id, zend_pimple_globals *, v)
+#else
+#define PIMPLE_G(v) (pimple_globals.v)
+#endif
+
+#endif /* PHP_PIMPLE_H */
+
diff --git a/vendor/pimple/pimple/ext/pimple/pimple.c b/vendor/pimple/pimple/ext/pimple/pimple.c
new file mode 100644
index 00000000..239c01d6
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/pimple.c
@@ -0,0 +1,922 @@
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2014 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_pimple.h"
+#include "pimple_compat.h"
+#include "zend_interfaces.h"
+#include "zend.h"
+#include "Zend/zend_closures.h"
+#include "ext/spl/spl_exceptions.h"
+#include "Zend/zend_exceptions.h"
+#include "main/php_output.h"
+#include "SAPI.h"
+
+static zend_class_entry *pimple_ce;
+static zend_object_handlers pimple_object_handlers;
+static zend_class_entry *pimple_closure_ce;
+static zend_class_entry *pimple_serviceprovider_ce;
+static zend_object_handlers pimple_closure_object_handlers;
+static zend_internal_function pimple_closure_invoker_function;
+
+#define FETCH_DIM_HANDLERS_VARS pimple_object *pimple_obj = NULL; \
+ ulong index; \
+ pimple_obj = (pimple_object *)zend_object_store_get_object(object TSRMLS_CC); \
+
+#define PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS do { \
+ if (ce != pimple_ce) { \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetget"), (void **)&function); \
+ if (function->common.scope != ce) { /* if the function is not defined in this actual class */ \
+ pimple_object_handlers.read_dimension = pimple_object_read_dimension; /* then overwrite the handler to use custom one */ \
+ } \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetset"), (void **)&function); \
+ if (function->common.scope != ce) { \
+ pimple_object_handlers.write_dimension = pimple_object_write_dimension; \
+ } \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetexists"), (void **)&function); \
+ if (function->common.scope != ce) { \
+ pimple_object_handlers.has_dimension = pimple_object_has_dimension; \
+ } \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetunset"), (void **)&function); \
+ if (function->common.scope != ce) { \
+ pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \
+ } \
+ } else { \
+ pimple_object_handlers.read_dimension = pimple_object_read_dimension; \
+ pimple_object_handlers.write_dimension = pimple_object_write_dimension; \
+ pimple_object_handlers.has_dimension = pimple_object_has_dimension; \
+ pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \
+ }\
+ } while(0);
+
+#define PIMPLE_CALL_CB do { \
+ zend_fcall_info_argn(&fci TSRMLS_CC, 1, &object); \
+ fci.size = sizeof(fci); \
+ fci.object_ptr = retval->fcc.object_ptr; \
+ fci.function_name = retval->value; \
+ fci.no_separation = 1; \
+ fci.retval_ptr_ptr = &retval_ptr_ptr; \
+\
+ zend_call_function(&fci, &retval->fcc TSRMLS_CC); \
+ efree(fci.params); \
+ if (EG(exception)) { \
+ return EG(uninitialized_zval_ptr); \
+ } \
+ } while(0);
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0)
+ZEND_ARG_ARRAY_INFO(0, value, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetset, 0, 0, 2)
+ZEND_ARG_INFO(0, offset)
+ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetget, 0, 0, 1)
+ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetexists, 0, 0, 1)
+ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetunset, 0, 0, 1)
+ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_factory, 0, 0, 1)
+ZEND_ARG_INFO(0, callable)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_protect, 0, 0, 1)
+ZEND_ARG_INFO(0, callable)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_raw, 0, 0, 1)
+ZEND_ARG_INFO(0, id)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_extend, 0, 0, 2)
+ZEND_ARG_INFO(0, id)
+ZEND_ARG_INFO(0, callable)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_keys, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_register, 0, 0, 1)
+ZEND_ARG_OBJ_INFO(0, provider, Pimple\\ServiceProviderInterface, 0)
+ZEND_ARG_ARRAY_INFO(0, values, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1)
+ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry pimple_ce_functions[] = {
+ PHP_ME(Pimple, __construct, arginfo___construct, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, factory, arginfo_factory, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, protect, arginfo_protect, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, raw, arginfo_raw, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, extend, arginfo_extend, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, keys, arginfo_keys, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, register, arginfo_register, ZEND_ACC_PUBLIC)
+
+ PHP_ME(Pimple, offsetSet, arginfo_offsetset, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, offsetGet, arginfo_offsetget, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, offsetExists, arginfo_offsetexists, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, offsetUnset, arginfo_offsetunset, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+static const zend_function_entry pimple_serviceprovider_iface_ce_functions[] = {
+ PHP_ABSTRACT_ME(ServiceProviderInterface, register, arginfo_serviceprovider_register)
+ PHP_FE_END
+};
+
+static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC)
+{
+ zend_object_std_dtor(&obj->zobj TSRMLS_CC);
+ if (obj->factory) {
+ zval_ptr_dtor(&obj->factory);
+ }
+ if (obj->callable) {
+ zval_ptr_dtor(&obj->callable);
+ }
+ efree(obj);
+}
+
+static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC)
+{
+ zend_hash_destroy(&obj->factories);
+ zend_hash_destroy(&obj->protected);
+ zend_hash_destroy(&obj->values);
+ zend_object_std_dtor(&obj->zobj TSRMLS_CC);
+ efree(obj);
+}
+
+static void pimple_free_bucket(pimple_bucket_value *bucket)
+{
+ if (bucket->raw) {
+ zval_ptr_dtor(&bucket->raw);
+ }
+}
+
+static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ pimple_closure_object *pimple_closure_obj = NULL;
+
+ pimple_closure_obj = ecalloc(1, sizeof(pimple_closure_object));
+ ZEND_OBJ_INIT(&pimple_closure_obj->zobj, ce);
+
+ pimple_closure_object_handlers.get_constructor = pimple_closure_get_constructor;
+ retval.handlers = &pimple_closure_object_handlers;
+ retval.handle = zend_objects_store_put(pimple_closure_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_closure_free_object_storage, NULL TSRMLS_CC);
+
+ return retval;
+}
+
+static zend_function *pimple_closure_get_constructor(zval *obj TSRMLS_DC)
+{
+ zend_error(E_ERROR, "Pimple\\ContainerClosure is an internal class and cannot be instantiated");
+
+ return NULL;
+}
+
+static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC)
+{
+ *zobj_ptr = obj;
+ *ce_ptr = Z_OBJCE_P(obj);
+ *fptr_ptr = (zend_function *)&pimple_closure_invoker_function;
+
+ return SUCCESS;
+}
+
+static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ pimple_object *pimple_obj = NULL;
+ zend_function *function = NULL;
+
+ pimple_obj = emalloc(sizeof(pimple_object));
+ ZEND_OBJ_INIT(&pimple_obj->zobj, ce);
+
+ PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS
+
+ retval.handlers = &pimple_object_handlers;
+ retval.handle = zend_objects_store_put(pimple_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_free_object_storage, NULL TSRMLS_CC);
+
+ zend_hash_init(&pimple_obj->factories, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
+ zend_hash_init(&pimple_obj->protected, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
+ zend_hash_init(&pimple_obj->values, PIMPLE_DEFAULT_ZVAL_VALUES_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
+
+ return retval;
+}
+
+static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ pimple_bucket_value pimple_value = {0}, *found_value = NULL;
+ ulong hash;
+
+ pimple_zval_to_pimpleval(value, &pimple_value TSRMLS_CC);
+
+ if (!offset) {/* $p[] = 'foo' when not overloaded */
+ zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL);
+ Z_ADDREF_P(value);
+ return;
+ }
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ hash = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ zend_hash_quick_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void **)&found_value);
+ if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
+ pimple_free_bucket(&pimple_value);
+ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%s\".", Z_STRVAL_P(offset));
+ return;
+ }
+ if (zend_hash_quick_update(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
+ pimple_free_bucket(&pimple_value);
+ return;
+ }
+ Z_ADDREF_P(value);
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ zend_hash_index_find(&pimple_obj->values, index, (void **)&found_value);
+ if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
+ pimple_free_bucket(&pimple_value);
+ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%ld\".", index);
+ return;
+ }
+ if (zend_hash_index_update(&pimple_obj->values, index, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
+ pimple_free_bucket(&pimple_value);
+ return;
+ }
+ Z_ADDREF_P(value);
+ break;
+ case IS_NULL: /* $p[] = 'foo' when overloaded */
+ zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL);
+ Z_ADDREF_P(value);
+ break;
+ default:
+ pimple_free_bucket(&pimple_value);
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+}
+
+static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ zend_symtable_del(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ zend_symtable_del(&pimple_obj->factories, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ zend_symtable_del(&pimple_obj->protected, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ zend_hash_index_del(&pimple_obj->values, index);
+ zend_hash_index_del(&pimple_obj->factories, index);
+ zend_hash_index_del(&pimple_obj->protected, index);
+ break;
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+}
+
+static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ pimple_bucket_value *retval = NULL;
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == SUCCESS) {
+ switch (check_empty) {
+ case 0: /* isset */
+ return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;) */
+ case 1: /* empty */
+ default:
+ return zend_is_true(retval->value);
+ }
+ }
+ return 0;
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == SUCCESS) {
+ switch (check_empty) {
+ case 0: /* isset */
+ return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;)*/
+ case 1: /* empty */
+ default:
+ return zend_is_true(retval->value);
+ }
+ }
+ return 0;
+ break;
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ return 0;
+ }
+}
+
+static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ pimple_bucket_value *retval = NULL;
+ zend_fcall_info fci = {0};
+ zval *retval_ptr_ptr = NULL;
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
+ return EG(uninitialized_zval_ptr);
+ }
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == FAILURE) {
+ return EG(uninitialized_zval_ptr);
+ }
+ break;
+ case IS_NULL: /* $p[][3] = 'foo' first dim access */
+ return EG(uninitialized_zval_ptr);
+ break;
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ return EG(uninitialized_zval_ptr);
+ }
+
+ if(retval->type == PIMPLE_IS_PARAM) {
+ return retval->value;
+ }
+
+ if (zend_hash_index_exists(&pimple_obj->protected, retval->handle_num)) {
+ /* Service is protected, return the value every time */
+ return retval->value;
+ }
+
+ if (zend_hash_index_exists(&pimple_obj->factories, retval->handle_num)) {
+ /* Service is a factory, call it everytime and never cache its result */
+ PIMPLE_CALL_CB
+ Z_DELREF_P(retval_ptr_ptr); /* fetch dim addr will increment refcount */
+ return retval_ptr_ptr;
+ }
+
+ if (retval->initialized == 1) {
+ /* Service has already been called, return its cached value */
+ return retval->value;
+ }
+
+ ALLOC_INIT_ZVAL(retval->raw);
+ MAKE_COPY_ZVAL(&retval->value, retval->raw);
+
+ PIMPLE_CALL_CB
+
+ retval->initialized = 1;
+ zval_ptr_dtor(&retval->value);
+ retval->value = retval_ptr_ptr;
+
+ return retval->value;
+}
+
+static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC)
+{
+ if (Z_TYPE_P(_zval) != IS_OBJECT) {
+ return FAILURE;
+ }
+
+ if (_pimple_bucket_value->fcc.called_scope) {
+ return SUCCESS;
+ }
+
+ if (Z_OBJ_HANDLER_P(_zval, get_closure) && Z_OBJ_HANDLER_P(_zval, get_closure)(_zval, &_pimple_bucket_value->fcc.calling_scope, &_pimple_bucket_value->fcc.function_handler, &_pimple_bucket_value->fcc.object_ptr TSRMLS_CC) == SUCCESS) {
+ _pimple_bucket_value->fcc.called_scope = _pimple_bucket_value->fcc.calling_scope;
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+}
+
+static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC)
+{
+ _pimple_bucket_value->value = _zval;
+
+ if (Z_TYPE_P(_zval) != IS_OBJECT) {
+ return PIMPLE_IS_PARAM;
+ }
+
+ if (pimple_zval_is_valid_callback(_zval, _pimple_bucket_value TSRMLS_CC) == SUCCESS) {
+ _pimple_bucket_value->type = PIMPLE_IS_SERVICE;
+ _pimple_bucket_value->handle_num = Z_OBJ_HANDLE_P(_zval);
+ }
+
+ return PIMPLE_IS_SERVICE;
+}
+
+static void pimple_bucket_dtor(pimple_bucket_value *bucket)
+{
+ zval_ptr_dtor(&bucket->value);
+ pimple_free_bucket(bucket);
+}
+
+PHP_METHOD(Pimple, protect)
+{
+ zval *protected = NULL;
+ pimple_object *pobj = NULL;
+ pimple_bucket_value bucket = {0};
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &protected) == FAILURE) {
+ return;
+ }
+
+ if (pimple_zval_is_valid_callback(protected, &bucket TSRMLS_CC) == FAILURE) {
+ pimple_free_bucket(&bucket);
+ zend_throw_exception(spl_ce_InvalidArgumentException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC);
+ return;
+ }
+
+ pimple_zval_to_pimpleval(protected, &bucket TSRMLS_CC);
+ pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (zend_hash_index_update(&pobj->protected, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) {
+ Z_ADDREF_P(protected);
+ RETURN_ZVAL(protected, 1 , 0);
+ } else {
+ pimple_free_bucket(&bucket);
+ }
+ RETURN_FALSE;
+}
+
+PHP_METHOD(Pimple, raw)
+{
+ zval *offset = NULL;
+ pimple_object *pobj = NULL;
+ pimple_bucket_value *value = NULL;
+ ulong index;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ pobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
+ RETURN_NULL();
+ }
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
+ RETURN_NULL();
+ }
+ break;
+ case IS_NULL:
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+
+ if (value->raw) {
+ RETVAL_ZVAL(value->raw, 1, 0);
+ } else {
+ RETVAL_ZVAL(value->value, 1, 0);
+ }
+}
+
+PHP_METHOD(Pimple, extend)
+{
+ zval *offset = NULL, *callable = NULL, *pimple_closure_obj = NULL;
+ pimple_bucket_value bucket = {0}, *value = NULL;
+ pimple_object *pobj = NULL;
+ pimple_closure_object *pcobj = NULL;
+ ulong index;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &callable) == FAILURE) {
+ return;
+ }
+
+ pobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
+ RETURN_NULL();
+ }
+ if (value->type != PIMPLE_IS_SERVICE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" does not contain an object definition.", Z_STRVAL_P(offset));
+ RETURN_NULL();
+ }
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" is not defined.", index);
+ RETURN_NULL();
+ }
+ if (value->type != PIMPLE_IS_SERVICE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" does not contain an object definition.", index);
+ RETURN_NULL();
+ }
+ break;
+ case IS_NULL:
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+
+ if (pimple_zval_is_valid_callback(callable, &bucket TSRMLS_CC) == FAILURE) {
+ pimple_free_bucket(&bucket);
+ zend_throw_exception(spl_ce_InvalidArgumentException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+ pimple_free_bucket(&bucket);
+
+ ALLOC_INIT_ZVAL(pimple_closure_obj);
+ object_init_ex(pimple_closure_obj, pimple_closure_ce);
+
+ pcobj = zend_object_store_get_object(pimple_closure_obj TSRMLS_CC);
+ pcobj->callable = callable;
+ pcobj->factory = value->value;
+ Z_ADDREF_P(callable);
+ Z_ADDREF_P(value->value);
+
+ if (zend_hash_index_exists(&pobj->factories, value->handle_num)) {
+ pimple_zval_to_pimpleval(pimple_closure_obj, &bucket TSRMLS_CC);
+ zend_hash_index_del(&pobj->factories, value->handle_num);
+ zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL);
+ Z_ADDREF_P(pimple_closure_obj);
+ }
+
+ pimple_object_write_dimension(getThis(), offset, pimple_closure_obj TSRMLS_CC);
+
+ RETVAL_ZVAL(pimple_closure_obj, 1, 1);
+}
+
+PHP_METHOD(Pimple, keys)
+{
+ HashPosition pos;
+ pimple_object *pobj = NULL;
+ zval **value = NULL;
+ zval *endval = NULL;
+ char *str_index = NULL;
+ int str_len;
+ ulong num_index;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ pobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+ array_init_size(return_value, zend_hash_num_elements(&pobj->values));
+
+ zend_hash_internal_pointer_reset_ex(&pobj->values, &pos);
+
+ while(zend_hash_get_current_data_ex(&pobj->values, (void **)&value, &pos) == SUCCESS) {
+ MAKE_STD_ZVAL(endval);
+ switch (zend_hash_get_current_key_ex(&pobj->values, &str_index, (uint *)&str_len, &num_index, 0, &pos)) {
+ case HASH_KEY_IS_STRING:
+ ZVAL_STRINGL(endval, str_index, str_len - 1, 1);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL);
+ break;
+ case HASH_KEY_IS_LONG:
+ ZVAL_LONG(endval, num_index);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL);
+ break;
+ }
+ zend_hash_move_forward_ex(&pobj->values, &pos);
+ }
+}
+
+PHP_METHOD(Pimple, factory)
+{
+ zval *factory = NULL;
+ pimple_object *pobj = NULL;
+ pimple_bucket_value bucket = {0};
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &factory) == FAILURE) {
+ return;
+ }
+
+ if (pimple_zval_is_valid_callback(factory, &bucket TSRMLS_CC) == FAILURE) {
+ pimple_free_bucket(&bucket);
+ zend_throw_exception(spl_ce_InvalidArgumentException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
+ return;
+ }
+
+ pimple_zval_to_pimpleval(factory, &bucket TSRMLS_CC);
+ pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) {
+ Z_ADDREF_P(factory);
+ RETURN_ZVAL(factory, 1 , 0);
+ } else {
+ pimple_free_bucket(&bucket);
+ }
+
+ RETURN_FALSE;
+}
+
+PHP_METHOD(Pimple, offsetSet)
+{
+ zval *offset = NULL, *value = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &value) == FAILURE) {
+ return;
+ }
+
+ pimple_object_write_dimension(getThis(), offset, value TSRMLS_CC);
+}
+
+PHP_METHOD(Pimple, offsetGet)
+{
+ zval *offset = NULL, *retval = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ retval = pimple_object_read_dimension(getThis(), offset, 0 TSRMLS_CC);
+
+ RETVAL_ZVAL(retval, 1, 0);
+}
+
+PHP_METHOD(Pimple, offsetUnset)
+{
+ zval *offset = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ pimple_object_unset_dimension(getThis(), offset TSRMLS_CC);
+}
+
+PHP_METHOD(Pimple, offsetExists)
+{
+ zval *offset = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ RETVAL_BOOL(pimple_object_has_dimension(getThis(), offset, 1 TSRMLS_CC));
+}
+
+PHP_METHOD(Pimple, register)
+{
+ zval *provider;
+ zval **data;
+ zval *retval = NULL;
+ zval key;
+
+ HashTable *array = NULL;
+ HashPosition pos;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|h", &provider, pimple_serviceprovider_ce, &array) == FAILURE) {
+ return;
+ }
+
+ RETVAL_ZVAL(getThis(), 1, 0);
+
+ zend_call_method_with_1_params(&provider, Z_OBJCE_P(provider), NULL, "register", &retval, getThis());
+
+ if (retval) {
+ zval_ptr_dtor(&retval);
+ }
+
+ if (!array) {
+ return;
+ }
+
+ zend_hash_internal_pointer_reset_ex(array, &pos);
+
+ while(zend_hash_get_current_data_ex(array, (void **)&data, &pos) == SUCCESS) {
+ zend_hash_get_current_key_zval_ex(array, &key, &pos);
+ pimple_object_write_dimension(getThis(), &key, *data TSRMLS_CC);
+ zend_hash_move_forward_ex(array, &pos);
+ }
+}
+
+PHP_METHOD(Pimple, __construct)
+{
+ zval *values = NULL, **pData = NULL, offset;
+ HashPosition pos;
+ char *str_index = NULL;
+ zend_uint str_length;
+ ulong num_index;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE || !values) {
+ return;
+ }
+
+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos);
+ while (zend_hash_has_more_elements_ex(Z_ARRVAL_P(values), &pos) == SUCCESS) {
+ zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&pData, &pos);
+ zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &str_index, &str_length, &num_index, 0, &pos);
+ INIT_ZVAL(offset);
+ if (zend_hash_get_current_key_type_ex(Z_ARRVAL_P(values), &pos) == HASH_KEY_IS_LONG) {
+ ZVAL_LONG(&offset, num_index);
+ } else {
+ ZVAL_STRINGL(&offset, str_index, (str_length - 1), 0);
+ }
+ pimple_object_write_dimension(getThis(), &offset, *pData TSRMLS_CC);
+ zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos);
+ }
+}
+
+/*
+ * This is PHP code snippet handling extend()s calls :
+
+ $extended = function ($c) use ($callable, $factory) {
+ return $callable($factory($c), $c);
+ };
+
+ */
+PHP_METHOD(PimpleClosure, invoker)
+{
+ pimple_closure_object *pcobj = NULL;
+ zval *arg = NULL, *retval = NULL, *newretval = NULL;
+ zend_fcall_info fci = {0};
+ zval **args[2];
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
+ return;
+ }
+
+ pcobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ fci.function_name = pcobj->factory;
+ args[0] = &arg;
+ zend_fcall_info_argp(&fci TSRMLS_CC, 1, args);
+ fci.retval_ptr_ptr = &retval;
+ fci.size = sizeof(fci);
+
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) {
+ efree(fci.params);
+ return; /* Should here return default zval */
+ }
+
+ efree(fci.params);
+ memset(&fci, 0, sizeof(fci));
+ fci.size = sizeof(fci);
+
+ fci.function_name = pcobj->callable;
+ args[0] = &retval;
+ args[1] = &arg;
+ zend_fcall_info_argp(&fci TSRMLS_CC, 2, args);
+ fci.retval_ptr_ptr = &newretval;
+
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) {
+ efree(fci.params);
+ zval_ptr_dtor(&retval);
+ return;
+ }
+
+ efree(fci.params);
+ zval_ptr_dtor(&retval);
+
+ RETVAL_ZVAL(newretval, 1 ,1);
+}
+
+PHP_MINIT_FUNCTION(pimple)
+{
+ zend_class_entry tmp_pimple_ce, tmp_pimple_closure_ce, tmp_pimple_serviceprovider_iface_ce;
+ INIT_NS_CLASS_ENTRY(tmp_pimple_ce, PIMPLE_NS, "Container", pimple_ce_functions);
+ INIT_NS_CLASS_ENTRY(tmp_pimple_closure_ce, PIMPLE_NS, "ContainerClosure", NULL);
+ INIT_NS_CLASS_ENTRY(tmp_pimple_serviceprovider_iface_ce, PIMPLE_NS, "ServiceProviderInterface", pimple_serviceprovider_iface_ce_functions);
+
+ tmp_pimple_ce.create_object = pimple_object_create;
+ tmp_pimple_closure_ce.create_object = pimple_closure_object_create;
+
+ pimple_ce = zend_register_internal_class(&tmp_pimple_ce TSRMLS_CC);
+ zend_class_implements(pimple_ce TSRMLS_CC, 1, zend_ce_arrayaccess);
+
+ pimple_closure_ce = zend_register_internal_class(&tmp_pimple_closure_ce TSRMLS_CC);
+ pimple_closure_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ pimple_serviceprovider_ce = zend_register_internal_interface(&tmp_pimple_serviceprovider_iface_ce TSRMLS_CC);
+
+ memcpy(&pimple_closure_object_handlers, zend_get_std_object_handlers(), sizeof(*zend_get_std_object_handlers()));
+ pimple_object_handlers = std_object_handlers;
+ pimple_closure_object_handlers.get_closure = pimple_closure_get_closure;
+
+ pimple_closure_invoker_function.function_name = "Pimple closure internal invoker";
+ pimple_closure_invoker_function.fn_flags |= ZEND_ACC_CLOSURE;
+ pimple_closure_invoker_function.handler = ZEND_MN(PimpleClosure_invoker);
+ pimple_closure_invoker_function.num_args = 1;
+ pimple_closure_invoker_function.required_num_args = 1;
+ pimple_closure_invoker_function.scope = pimple_closure_ce;
+ pimple_closure_invoker_function.type = ZEND_INTERNAL_FUNCTION;
+ pimple_closure_invoker_function.module = &pimple_module_entry;
+
+ return SUCCESS;
+}
+
+PHP_MINFO_FUNCTION(pimple)
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, "SensioLabs Pimple C support", "enabled");
+ php_info_print_table_row(2, "Pimple supported version", PIMPLE_VERSION);
+ php_info_print_table_end();
+
+ php_info_print_box_start(0);
+ php_write((void *)ZEND_STRL("SensioLabs Pimple C support developed by Julien Pauli") TSRMLS_CC);
+ if (!sapi_module.phpinfo_as_text) {
+ php_write((void *)ZEND_STRL(sensiolabs_logo) TSRMLS_CC);
+ }
+ php_info_print_box_end();
+}
+
+zend_module_entry pimple_module_entry = {
+ STANDARD_MODULE_HEADER,
+ "pimple",
+ NULL,
+ PHP_MINIT(pimple),
+ NULL,
+ NULL,
+ NULL,
+ PHP_MINFO(pimple),
+ PIMPLE_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_PIMPLE
+ZEND_GET_MODULE(pimple)
+#endif
diff --git a/vendor/pimple/pimple/ext/pimple/pimple_compat.h b/vendor/pimple/pimple/ext/pimple/pimple_compat.h
new file mode 100644
index 00000000..d234e174
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/pimple_compat.h
@@ -0,0 +1,81 @@
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2014 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PIMPLE_COMPAT_H_
+#define PIMPLE_COMPAT_H_
+
+#include "Zend/zend_extensions.h" /* for ZEND_EXTENSION_API_NO */
+
+#define PHP_5_0_X_API_NO 220040412
+#define PHP_5_1_X_API_NO 220051025
+#define PHP_5_2_X_API_NO 220060519
+#define PHP_5_3_X_API_NO 220090626
+#define PHP_5_4_X_API_NO 220100525
+#define PHP_5_5_X_API_NO 220121212
+#define PHP_5_6_X_API_NO 220131226
+
+#define IS_PHP_56 ZEND_EXTENSION_API_NO == PHP_5_6_X_API_NO
+#define IS_AT_LEAST_PHP_56 ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO
+
+#define IS_PHP_55 ZEND_EXTENSION_API_NO == PHP_5_5_X_API_NO
+#define IS_AT_LEAST_PHP_55 ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
+
+#define IS_PHP_54 ZEND_EXTENSION_API_NO == PHP_5_4_X_API_NO
+#define IS_AT_LEAST_PHP_54 ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO
+
+#define IS_PHP_53 ZEND_EXTENSION_API_NO == PHP_5_3_X_API_NO
+#define IS_AT_LEAST_PHP_53 ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+
+#if IS_PHP_53
+#define object_properties_init(obj, ce) do { \
+ zend_hash_copy(obj->properties, &ce->default_properties, zval_copy_property_ctor(ce), NULL, sizeof(zval *)); \
+ } while (0);
+#endif
+
+#define ZEND_OBJ_INIT(obj, ce) do { \
+ zend_object_std_init(obj, ce TSRMLS_CC); \
+ object_properties_init((obj), (ce)); \
+ } while(0);
+
+#if IS_PHP_53 || IS_PHP_54
+static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) {
+ Bucket *p;
+
+ p = pos ? (*pos) : ht->pInternalPointer;
+
+ if (!p) {
+ Z_TYPE_P(key) = IS_NULL;
+ } else if (p->nKeyLength) {
+ Z_TYPE_P(key) = IS_STRING;
+ Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1);
+ Z_STRLEN_P(key) = p->nKeyLength - 1;
+ } else {
+ Z_TYPE_P(key) = IS_LONG;
+ Z_LVAL_P(key) = p->h;
+ }
+}
+#endif
+
+#endif /* PIMPLE_COMPAT_H_ */
diff --git a/vendor/pimple/pimple/ext/pimple/tests/001.phpt b/vendor/pimple/pimple/ext/pimple/tests/001.phpt
new file mode 100644
index 00000000..0809ea23
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/001.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Test for read_dim/write_dim handlers
+--SKIPIF--
+
+--FILE--
+
+
+--EXPECTF--
+foo
+42
+foo2
+foo99
+baz
+strstr
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/002.phpt b/vendor/pimple/pimple/ext/pimple/tests/002.phpt
new file mode 100644
index 00000000..7b56d2c1
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/002.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Test for constructor
+--SKIPIF--
+
+--FILE--
+'foo'));
+var_dump($p[42]);
+?>
+--EXPECT--
+NULL
+string(3) "foo"
diff --git a/vendor/pimple/pimple/ext/pimple/tests/003.phpt b/vendor/pimple/pimple/ext/pimple/tests/003.phpt
new file mode 100644
index 00000000..a22cfa35
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/003.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Test empty dimensions
+--SKIPIF--
+
+--FILE--
+
+--EXPECT--
+int(42)
+string(3) "bar"
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/004.phpt b/vendor/pimple/pimple/ext/pimple/tests/004.phpt
new file mode 100644
index 00000000..1e1d2513
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/004.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test has/unset dim handlers
+--SKIPIF--
+
+--FILE--
+
+--EXPECT--
+int(42)
+NULL
+bool(true)
+bool(false)
+bool(true)
+bool(true)
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/005.phpt b/vendor/pimple/pimple/ext/pimple/tests/005.phpt
new file mode 100644
index 00000000..0479ee05
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/005.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Test simple class inheritance
+--SKIPIF--
+
+--FILE--
+someAttr;
+?>
+--EXPECT--
+string(3) "hit"
+foo
+fooAttr
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/006.phpt b/vendor/pimple/pimple/ext/pimple/tests/006.phpt
new file mode 100644
index 00000000..cfe8a119
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/006.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Test complex class inheritance
+--SKIPIF--
+
+--FILE--
+ 'bar', 88 => 'baz');
+
+$p = new TestPimple($defaultValues);
+$p[42] = 'foo';
+var_dump($p[42]);
+var_dump($p[0]);
+?>
+--EXPECT--
+string(13) "hit offsetset"
+string(27) "hit offsetget in TestPimple"
+string(25) "hit offsetget in MyPimple"
+string(3) "foo"
+string(27) "hit offsetget in TestPimple"
+string(25) "hit offsetget in MyPimple"
+string(3) "baz"
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/007.phpt b/vendor/pimple/pimple/ext/pimple/tests/007.phpt
new file mode 100644
index 00000000..5aac6838
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/007.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test for read_dim/write_dim handlers
+--SKIPIF--
+
+--FILE--
+
+--EXPECTF--
+foo
+42
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/008.phpt b/vendor/pimple/pimple/ext/pimple/tests/008.phpt
new file mode 100644
index 00000000..db7eeec4
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/008.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Test frozen services
+--SKIPIF--
+
+--FILE--
+
+--EXPECTF--
diff --git a/vendor/pimple/pimple/ext/pimple/tests/009.phpt b/vendor/pimple/pimple/ext/pimple/tests/009.phpt
new file mode 100644
index 00000000..bb05ea29
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/009.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Test service is called as callback, and only once
+--SKIPIF--
+
+--FILE--
+
+--EXPECTF--
+bool(true)
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/010.phpt b/vendor/pimple/pimple/ext/pimple/tests/010.phpt
new file mode 100644
index 00000000..badce014
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/010.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Test service is called as callback for every callback type
+--SKIPIF--
+
+--FILE--
+
+--EXPECTF--
+callme
+called
+Foo::bar
+array(2) {
+ [0]=>
+ string(3) "Foo"
+ [1]=>
+ string(3) "bar"
+}
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/011.phpt b/vendor/pimple/pimple/ext/pimple/tests/011.phpt
new file mode 100644
index 00000000..6682ab8e
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/011.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Test service callback throwing an exception
+--SKIPIF--
+
+--FILE--
+
+--EXPECTF--
+all right!
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/012.phpt b/vendor/pimple/pimple/ext/pimple/tests/012.phpt
new file mode 100644
index 00000000..4c6ac486
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/012.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Test service factory
+--SKIPIF--
+
+--FILE--
+factory($f = function() { var_dump('called-1'); return 'ret-1';});
+
+$p[] = $f;
+
+$p[] = function () { var_dump('called-2'); return 'ret-2'; };
+
+var_dump($p[0]);
+var_dump($p[0]);
+var_dump($p[1]);
+var_dump($p[1]);
+?>
+--EXPECTF--
+string(8) "called-1"
+string(5) "ret-1"
+string(8) "called-1"
+string(5) "ret-1"
+string(8) "called-2"
+string(5) "ret-2"
+string(5) "ret-2"
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/013.phpt b/vendor/pimple/pimple/ext/pimple/tests/013.phpt
new file mode 100644
index 00000000..f419958c
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/013.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Test keys()
+--SKIPIF--
+
+--FILE--
+keys());
+
+$p['foo'] = 'bar';
+$p[] = 'foo';
+
+var_dump($p->keys());
+
+unset($p['foo']);
+
+var_dump($p->keys());
+?>
+--EXPECTF--
+array(0) {
+}
+array(2) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ int(0)
+}
+array(1) {
+ [0]=>
+ int(0)
+}
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/014.phpt b/vendor/pimple/pimple/ext/pimple/tests/014.phpt
new file mode 100644
index 00000000..ac937213
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/014.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test raw()
+--SKIPIF--
+
+--FILE--
+raw('foo'));
+var_dump($p[42]);
+
+unset($p['foo']);
+
+try {
+ $p->raw('foo');
+ echo "expected exception";
+} catch (InvalidArgumentException $e) { }
+--EXPECTF--
+string(8) "called-2"
+string(5) "ret-2"
+object(Closure)#%i (0) {
+}
+string(8) "called-2"
+string(5) "ret-2"
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/015.phpt b/vendor/pimple/pimple/ext/pimple/tests/015.phpt
new file mode 100644
index 00000000..314f008a
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/015.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Test protect()
+--SKIPIF--
+
+--FILE--
+protect($f);
+
+var_dump($p['foo']);
+--EXPECTF--
+object(Closure)#%i (0) {
+}
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/016.phpt b/vendor/pimple/pimple/ext/pimple/tests/016.phpt
new file mode 100644
index 00000000..e55edb0a
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/016.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test extend()
+--SKIPIF--
+
+--FILE--
+extend(12, function ($w) { var_dump($w); return 'bar'; }); /* $callable in code above */
+
+var_dump($c('param'));
+--EXPECTF--
+string(5) "param"
+string(3) "foo"
+string(3) "bar"
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/017.phpt b/vendor/pimple/pimple/ext/pimple/tests/017.phpt
new file mode 100644
index 00000000..bac23ce0
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/017.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Test extend() with exception in service extension
+--SKIPIF--
+
+--FILE--
+extend(12, function ($w) { throw new BadMethodCallException; });
+
+try {
+ $p[12];
+ echo "Exception expected";
+} catch (BadMethodCallException $e) { }
+--EXPECTF--
diff --git a/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt b/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt
new file mode 100644
index 00000000..8f881d6e
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Test extend() with exception in service factory
+--SKIPIF--
+
+--FILE--
+extend(12, function ($w) { return 'foobar'; });
+
+try {
+ $p[12];
+ echo "Exception expected";
+} catch (BadMethodCallException $e) { }
+--EXPECTF--
diff --git a/vendor/pimple/pimple/ext/pimple/tests/018.phpt b/vendor/pimple/pimple/ext/pimple/tests/018.phpt
new file mode 100644
index 00000000..27c12a14
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/018.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Test register()
+--SKIPIF--
+
+--FILE--
+register(new Foo, array(42 => 'bar'));
+
+var_dump($p[42]);
+--EXPECTF--
+object(Pimple\Container)#1 (0) {
+}
+string(3) "bar"
\ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/019.phpt b/vendor/pimple/pimple/ext/pimple/tests/019.phpt
new file mode 100644
index 00000000..28a9aeca
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/019.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Test register() returns static and is a fluent interface
+--SKIPIF--
+
+--FILE--
+register(new Foo));
+--EXPECTF--
+bool(true)
diff --git a/vendor/pimple/pimple/ext/pimple/tests/bench.phpb b/vendor/pimple/pimple/ext/pimple/tests/bench.phpb
new file mode 100644
index 00000000..8f983e65
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/bench.phpb
@@ -0,0 +1,51 @@
+factory($factory);
+
+$p['factory'] = $factory;
+
+echo $p['factory'];
+echo $p['factory'];
+echo $p['factory'];
+
+}
+
+echo microtime(true) - $time;
diff --git a/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb b/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb
new file mode 100644
index 00000000..aec541f0
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb
@@ -0,0 +1,25 @@
+
diff --git a/vendor/pimple/pimple/phpunit.xml.dist b/vendor/pimple/pimple/phpunit.xml.dist
new file mode 100644
index 00000000..5c8d487f
--- /dev/null
+++ b/vendor/pimple/pimple/phpunit.xml.dist
@@ -0,0 +1,14 @@
+
+
+
+
+
+ ./src/Pimple/Tests
+
+
+
diff --git a/vendor/pimple/pimple/src/Pimple/Container.php b/vendor/pimple/pimple/src/Pimple/Container.php
new file mode 100644
index 00000000..c976431e
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Container.php
@@ -0,0 +1,282 @@
+factories = new \SplObjectStorage();
+ $this->protected = new \SplObjectStorage();
+
+ foreach ($values as $key => $value) {
+ $this->offsetSet($key, $value);
+ }
+ }
+
+ /**
+ * Sets a parameter or an object.
+ *
+ * Objects must be defined as Closures.
+ *
+ * Allowing any PHP callable leads to difficult to debug problems
+ * as function names (strings) are callable (creating a function with
+ * the same name as an existing parameter would break your container).
+ *
+ * @param string $id The unique identifier for the parameter or object
+ * @param mixed $value The value of the parameter or a closure to define an object
+ *
+ * @throws \RuntimeException Prevent override of a frozen service
+ */
+ public function offsetSet($id, $value)
+ {
+ if (isset($this->frozen[$id])) {
+ throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));
+ }
+
+ $this->values[$id] = $value;
+ $this->keys[$id] = true;
+ }
+
+ /**
+ * Gets a parameter or an object.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ *
+ * @return mixed The value of the parameter or an object
+ *
+ * @throws \InvalidArgumentException if the identifier is not defined
+ */
+ public function offsetGet($id)
+ {
+ if (!isset($this->keys[$id])) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+ }
+
+ if (
+ isset($this->raw[$id])
+ || !is_object($this->values[$id])
+ || isset($this->protected[$this->values[$id]])
+ || !method_exists($this->values[$id], '__invoke')
+ ) {
+ return $this->values[$id];
+ }
+
+ if (isset($this->factories[$this->values[$id]])) {
+ return $this->values[$id]($this);
+ }
+
+ $raw = $this->values[$id];
+ $val = $this->values[$id] = $raw($this);
+ $this->raw[$id] = $raw;
+
+ $this->frozen[$id] = true;
+
+ return $val;
+ }
+
+ /**
+ * Checks if a parameter or an object is set.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ *
+ * @return bool
+ */
+ public function offsetExists($id)
+ {
+ return isset($this->keys[$id]);
+ }
+
+ /**
+ * Unsets a parameter or an object.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ */
+ public function offsetUnset($id)
+ {
+ if (isset($this->keys[$id])) {
+ if (is_object($this->values[$id])) {
+ unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);
+ }
+
+ unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);
+ }
+ }
+
+ /**
+ * Marks a callable as being a factory service.
+ *
+ * @param callable $callable A service definition to be used as a factory
+ *
+ * @return callable The passed callable
+ *
+ * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
+ */
+ public function factory($callable)
+ {
+ if (!method_exists($callable, '__invoke')) {
+ throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.');
+ }
+
+ $this->factories->attach($callable);
+
+ return $callable;
+ }
+
+ /**
+ * Protects a callable from being interpreted as a service.
+ *
+ * This is useful when you want to store a callable as a parameter.
+ *
+ * @param callable $callable A callable to protect from being evaluated
+ *
+ * @return callable The passed callable
+ *
+ * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
+ */
+ public function protect($callable)
+ {
+ if (!method_exists($callable, '__invoke')) {
+ throw new \InvalidArgumentException('Callable is not a Closure or invokable object.');
+ }
+
+ $this->protected->attach($callable);
+
+ return $callable;
+ }
+
+ /**
+ * Gets a parameter or the closure defining an object.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ *
+ * @return mixed The value of the parameter or the closure defining an object
+ *
+ * @throws \InvalidArgumentException if the identifier is not defined
+ */
+ public function raw($id)
+ {
+ if (!isset($this->keys[$id])) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+ }
+
+ if (isset($this->raw[$id])) {
+ return $this->raw[$id];
+ }
+
+ return $this->values[$id];
+ }
+
+ /**
+ * Extends an object definition.
+ *
+ * Useful when you want to extend an existing object definition,
+ * without necessarily loading that object.
+ *
+ * @param string $id The unique identifier for the object
+ * @param callable $callable A service definition to extend the original
+ *
+ * @return callable The wrapped callable
+ *
+ * @throws \InvalidArgumentException if the identifier is not defined or not a service definition
+ */
+ public function extend($id, $callable)
+ {
+ if (!isset($this->keys[$id])) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+ }
+
+ if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
+ }
+
+ if (!is_object($callable) || !method_exists($callable, '__invoke')) {
+ throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
+ }
+
+ $factory = $this->values[$id];
+
+ $extended = function ($c) use ($callable, $factory) {
+ return $callable($factory($c), $c);
+ };
+
+ if (isset($this->factories[$factory])) {
+ $this->factories->detach($factory);
+ $this->factories->attach($extended);
+ }
+
+ return $this[$id] = $extended;
+ }
+
+ /**
+ * Returns all defined value names.
+ *
+ * @return array An array of value names
+ */
+ public function keys()
+ {
+ return array_keys($this->values);
+ }
+
+ /**
+ * Registers a service provider.
+ *
+ * @param ServiceProviderInterface $provider A ServiceProviderInterface instance
+ * @param array $values An array of values that customizes the provider
+ *
+ * @return static
+ */
+ public function register(ServiceProviderInterface $provider, array $values = array())
+ {
+ $provider->register($this);
+
+ foreach ($values as $key => $value) {
+ $this[$key] = $value;
+ }
+
+ return $this;
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php b/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php
new file mode 100644
index 00000000..c004594b
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php
@@ -0,0 +1,46 @@
+value = $value;
+
+ return $service;
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php
new file mode 100644
index 00000000..33cd4e54
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php
@@ -0,0 +1,34 @@
+factory(function () {
+ return new Service();
+ });
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php
new file mode 100644
index 00000000..d71b184d
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php
@@ -0,0 +1,35 @@
+
+ */
+class Service
+{
+ public $value;
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php b/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php
new file mode 100644
index 00000000..8e5c4c73
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php
@@ -0,0 +1,76 @@
+
+ */
+class PimpleServiceProviderInterfaceTest extends \PHPUnit_Framework_TestCase
+{
+ public function testProvider()
+ {
+ $pimple = new Container();
+
+ $pimpleServiceProvider = new Fixtures\PimpleServiceProvider();
+ $pimpleServiceProvider->register($pimple);
+
+ $this->assertEquals('value', $pimple['param']);
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+
+ $serviceOne = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ }
+
+ public function testProviderWithRegisterMethod()
+ {
+ $pimple = new Container();
+
+ $pimple->register(new Fixtures\PimpleServiceProvider(), array(
+ 'anotherParameter' => 'anotherValue',
+ ));
+
+ $this->assertEquals('value', $pimple['param']);
+ $this->assertEquals('anotherValue', $pimple['anotherParameter']);
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+
+ $serviceOne = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php b/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php
new file mode 100644
index 00000000..918f620d
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php
@@ -0,0 +1,440 @@
+
+ */
+class PimpleTest extends \PHPUnit_Framework_TestCase
+{
+ public function testWithString()
+ {
+ $pimple = new Container();
+ $pimple['param'] = 'value';
+
+ $this->assertEquals('value', $pimple['param']);
+ }
+
+ public function testWithClosure()
+ {
+ $pimple = new Container();
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+ }
+
+ public function testServicesShouldBeDifferent()
+ {
+ $pimple = new Container();
+ $pimple['service'] = $pimple->factory(function () {
+ return new Fixtures\Service();
+ });
+
+ $serviceOne = $pimple['service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ }
+
+ public function testShouldPassContainerAsParameter()
+ {
+ $pimple = new Container();
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+ $pimple['container'] = function ($container) {
+ return $container;
+ };
+
+ $this->assertNotSame($pimple, $pimple['service']);
+ $this->assertSame($pimple, $pimple['container']);
+ }
+
+ public function testIsset()
+ {
+ $pimple = new Container();
+ $pimple['param'] = 'value';
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+
+ $pimple['null'] = null;
+
+ $this->assertTrue(isset($pimple['param']));
+ $this->assertTrue(isset($pimple['service']));
+ $this->assertTrue(isset($pimple['null']));
+ $this->assertFalse(isset($pimple['non_existent']));
+ }
+
+ public function testConstructorInjection()
+ {
+ $params = array('param' => 'value');
+ $pimple = new Container($params);
+
+ $this->assertSame($params['param'], $pimple['param']);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testOffsetGetValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ echo $pimple['foo'];
+ }
+
+ public function testOffsetGetHonorsNullValues()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = null;
+ $this->assertNull($pimple['foo']);
+ }
+
+ public function testUnset()
+ {
+ $pimple = new Container();
+ $pimple['param'] = 'value';
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+
+ unset($pimple['param'], $pimple['service']);
+ $this->assertFalse(isset($pimple['param']));
+ $this->assertFalse(isset($pimple['service']));
+ }
+
+ /**
+ * @dataProvider serviceDefinitionProvider
+ */
+ public function testShare($service)
+ {
+ $pimple = new Container();
+ $pimple['shared_service'] = $service;
+
+ $serviceOne = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertSame($serviceOne, $serviceTwo);
+ }
+
+ /**
+ * @dataProvider serviceDefinitionProvider
+ */
+ public function testProtect($service)
+ {
+ $pimple = new Container();
+ $pimple['protected'] = $pimple->protect($service);
+
+ $this->assertSame($service, $pimple['protected']);
+ }
+
+ public function testGlobalFunctionNameAsParameterValue()
+ {
+ $pimple = new Container();
+ $pimple['global_function'] = 'strlen';
+ $this->assertSame('strlen', $pimple['global_function']);
+ }
+
+ public function testRaw()
+ {
+ $pimple = new Container();
+ $pimple['service'] = $definition = $pimple->factory(function () { return 'foo'; });
+ $this->assertSame($definition, $pimple->raw('service'));
+ }
+
+ public function testRawHonorsNullValues()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = null;
+ $this->assertNull($pimple->raw('foo'));
+ }
+
+ public function testFluentRegister()
+ {
+ $pimple = new Container();
+ $this->assertSame($pimple, $pimple->register($this->getMock('Pimple\ServiceProviderInterface')));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testRawValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ $pimple->raw('foo');
+ }
+
+ /**
+ * @dataProvider serviceDefinitionProvider
+ */
+ public function testExtend($service)
+ {
+ $pimple = new Container();
+ $pimple['shared_service'] = function () {
+ return new Fixtures\Service();
+ };
+ $pimple['factory_service'] = $pimple->factory(function () {
+ return new Fixtures\Service();
+ });
+
+ $pimple->extend('shared_service', $service);
+ $serviceOne = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+ $serviceTwo = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+ $this->assertSame($serviceOne, $serviceTwo);
+ $this->assertSame($serviceOne->value, $serviceTwo->value);
+
+ $pimple->extend('factory_service', $service);
+ $serviceOne = $pimple['factory_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+ $serviceTwo = $pimple['factory_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ $this->assertNotSame($serviceOne->value, $serviceTwo->value);
+ }
+
+ public function testExtendDoesNotLeakWithFactories()
+ {
+ if (extension_loaded('pimple')) {
+ $this->markTestSkipped('Pimple extension does not support this test');
+ }
+ $pimple = new Container();
+
+ $pimple['foo'] = $pimple->factory(function () { return; });
+ $pimple['foo'] = $pimple->extend('foo', function ($foo, $pimple) { return; });
+ unset($pimple['foo']);
+
+ $p = new \ReflectionProperty($pimple, 'values');
+ $p->setAccessible(true);
+ $this->assertEmpty($p->getValue($pimple));
+
+ $p = new \ReflectionProperty($pimple, 'factories');
+ $p->setAccessible(true);
+ $this->assertCount(0, $p->getValue($pimple));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testExtendValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ $pimple->extend('foo', function () {});
+ }
+
+ public function testKeys()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = 123;
+ $pimple['bar'] = 123;
+
+ $this->assertEquals(array('foo', 'bar'), $pimple->keys());
+ }
+
+ /** @test */
+ public function settingAnInvokableObjectShouldTreatItAsFactory()
+ {
+ $pimple = new Container();
+ $pimple['invokable'] = new Fixtures\Invokable();
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['invokable']);
+ }
+
+ /** @test */
+ public function settingNonInvokableObjectShouldTreatItAsParameter()
+ {
+ $pimple = new Container();
+ $pimple['non_invokable'] = new Fixtures\NonInvokable();
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\NonInvokable', $pimple['non_invokable']);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Service definition is not a Closure or invokable object.
+ */
+ public function testFactoryFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->factory($service);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Callable is not a Closure or invokable object.
+ */
+ public function testProtectFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->protect($service);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" does not contain an object definition.
+ */
+ public function testExtendFailsForKeysNotContainingServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple['foo'] = $service;
+ $pimple->extend('foo', function () {});
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Extension service definition is not a Closure or invokable object.
+ */
+ public function testExtendFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {};
+ $pimple->extend('foo', $service);
+ }
+
+ /**
+ * Provider for invalid service definitions.
+ */
+ public function badServiceDefinitionProvider()
+ {
+ return array(
+ array(123),
+ array(new Fixtures\NonInvokable()),
+ );
+ }
+
+ /**
+ * Provider for service definitions.
+ */
+ public function serviceDefinitionProvider()
+ {
+ return array(
+ array(function ($value) {
+ $service = new Fixtures\Service();
+ $service->value = $value;
+
+ return $service;
+ }),
+ array(new Fixtures\Invokable()),
+ );
+ }
+
+ public function testDefiningNewServiceAfterFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $foo = $pimple['foo'];
+
+ $pimple['bar'] = function () {
+ return 'bar';
+ };
+ $this->assertSame('bar', $pimple['bar']);
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Cannot override frozen service "foo".
+ */
+ public function testOverridingServiceAfterFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $foo = $pimple['foo'];
+
+ $pimple['foo'] = function () {
+ return 'bar';
+ };
+ }
+
+ public function testRemovingServiceAfterFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $foo = $pimple['foo'];
+
+ unset($pimple['foo']);
+ $pimple['foo'] = function () {
+ return 'bar';
+ };
+ $this->assertSame('bar', $pimple['foo']);
+ }
+
+ public function testExtendingService()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
+ return "$foo.bar";
+ });
+ $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
+ return "$foo.baz";
+ });
+ $this->assertSame('foo.bar.baz', $pimple['foo']);
+ }
+
+ public function testExtendingServiceAfterOtherServiceFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $pimple['bar'] = function () {
+ return 'bar';
+ };
+ $foo = $pimple['foo'];
+
+ $pimple['bar'] = $pimple->extend('bar', function ($bar, $app) {
+ return "$bar.baz";
+ });
+ $this->assertSame('bar.baz', $pimple['bar']);
+ }
+}
diff --git a/vendor/psr/log/.gitignore b/vendor/psr/log/.gitignore
new file mode 100644
index 00000000..22d0d82f
--- /dev/null
+++ b/vendor/psr/log/.gitignore
@@ -0,0 +1 @@
+vendor
diff --git a/vendor/psr/log/LICENSE b/vendor/psr/log/LICENSE
new file mode 100644
index 00000000..474c952b
--- /dev/null
+++ b/vendor/psr/log/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/psr/log/Psr/Log/AbstractLogger.php b/vendor/psr/log/Psr/Log/AbstractLogger.php
new file mode 100644
index 00000000..90e721af
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/AbstractLogger.php
@@ -0,0 +1,128 @@
+log(LogLevel::EMERGENCY, $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/vendor/psr/log/Psr/Log/InvalidArgumentException.php
new file mode 100644
index 00000000..67f852d1
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/InvalidArgumentException.php
@@ -0,0 +1,7 @@
+logger = $logger;
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php
new file mode 100644
index 00000000..5ea72438
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerInterface.php
@@ -0,0 +1,123 @@
+log(LogLevel::EMERGENCY, $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ abstract public function log($level, $message, array $context = array());
+}
diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php
new file mode 100644
index 00000000..d8cd682c
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/NullLogger.php
@@ -0,0 +1,28 @@
+logger) { }`
+ * blocks.
+ */
+class NullLogger extends AbstractLogger
+{
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function log($level, $message, array $context = array())
+ {
+ // noop
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
new file mode 100644
index 00000000..a0391a52
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
@@ -0,0 +1,140 @@
+ ".
+ *
+ * Example ->error('Foo') would yield "error Foo".
+ *
+ * @return string[]
+ */
+ abstract public function getLogs();
+
+ public function testImplements()
+ {
+ $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
+ }
+
+ /**
+ * @dataProvider provideLevelsAndMessages
+ */
+ public function testLogsAtAllLevels($level, $message)
+ {
+ $logger = $this->getLogger();
+ $logger->{$level}($message, array('user' => 'Bob'));
+ $logger->log($level, $message, array('user' => 'Bob'));
+
+ $expected = array(
+ $level.' message of level '.$level.' with context: Bob',
+ $level.' message of level '.$level.' with context: Bob',
+ );
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function provideLevelsAndMessages()
+ {
+ return array(
+ LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
+ LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
+ LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
+ LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
+ LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
+ LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
+ LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
+ LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
+ );
+ }
+
+ /**
+ * @expectedException \Psr\Log\InvalidArgumentException
+ */
+ public function testThrowsOnInvalidLevel()
+ {
+ $logger = $this->getLogger();
+ $logger->log('invalid level', 'Foo');
+ }
+
+ public function testContextReplacement()
+ {
+ $logger = $this->getLogger();
+ $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
+
+ $expected = array('info {Message {nothing} Bob Bar a}');
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function testObjectCastToString()
+ {
+ if (method_exists($this, 'createPartialMock')) {
+ $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString'));
+ } else {
+ $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
+ }
+ $dummy->expects($this->once())
+ ->method('__toString')
+ ->will($this->returnValue('DUMMY'));
+
+ $this->getLogger()->warning($dummy);
+
+ $expected = array('warning DUMMY');
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function testContextCanContainAnything()
+ {
+ $context = array(
+ 'bool' => true,
+ 'null' => null,
+ 'string' => 'Foo',
+ 'int' => 0,
+ 'float' => 0.5,
+ 'nested' => array('with object' => new DummyTest),
+ 'object' => new \DateTime,
+ 'resource' => fopen('php://memory', 'r'),
+ );
+
+ $this->getLogger()->warning('Crazy context data', $context);
+
+ $expected = array('warning Crazy context data');
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function testContextExceptionKeyCanBeExceptionOrOtherValues()
+ {
+ $logger = $this->getLogger();
+ $logger->warning('Random message', array('exception' => 'oops'));
+ $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
+
+ $expected = array(
+ 'warning Random message',
+ 'critical Uncaught Exception!'
+ );
+ $this->assertEquals($expected, $this->getLogs());
+ }
+}
+
+class DummyTest
+{
+ public function __toString()
+ {
+ }
+}
diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md
new file mode 100644
index 00000000..574bc1cb
--- /dev/null
+++ b/vendor/psr/log/README.md
@@ -0,0 +1,45 @@
+PSR Log
+=======
+
+This repository holds all interfaces/classes/traits related to
+[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
+
+Note that this is not a logger of its own. It is merely an interface that
+describes a logger. See the specification for more details.
+
+Usage
+-----
+
+If you need a logger, you can use the interface like this:
+
+```php
+logger = $logger;
+ }
+
+ public function doSomething()
+ {
+ if ($this->logger) {
+ $this->logger->info('Doing work');
+ }
+
+ // do something useful
+ }
+}
+```
+
+You can then pick one of the implementations of the interface to get a logger.
+
+If you want to implement the interface, you can require this package and
+implement `Psr\Log\LoggerInterface` in your code. Please read the
+[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+for details.
diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json
new file mode 100644
index 00000000..87934d70
--- /dev/null
+++ b/vendor/psr/log/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "psr/log",
+ "description": "Common interface for logging libraries",
+ "keywords": ["psr", "psr-3", "log"],
+ "homepage": "https://github.com/php-fig/log",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/silex/silex/.gitignore b/vendor/silex/silex/.gitignore
new file mode 100644
index 00000000..3d4ff050
--- /dev/null
+++ b/vendor/silex/silex/.gitignore
@@ -0,0 +1,5 @@
+/phpunit.xml
+/vendor
+/build
+/composer.lock
+
diff --git a/vendor/silex/silex/.travis.yml b/vendor/silex/silex/.travis.yml
new file mode 100644
index 00000000..fed52268
--- /dev/null
+++ b/vendor/silex/silex/.travis.yml
@@ -0,0 +1,44 @@
+language: php
+
+sudo: false
+
+env:
+ global:
+ - SYMFONY_DEPRECATIONS_HELPER=weak
+
+cache:
+ directories:
+ - $HOME/.composer/cache/files
+
+before_install:
+ - if [[ $TRAVIS_PHP_VERSION != hhvm ]]; then phpenv config-rm xdebug.ini; fi
+
+before_script:
+ # symfony/*
+ - sh -c "if [ '$TWIG_VERSION' != '2.0' ]; then sed -i 's/~1.8|~2.0/~1.8/g' composer.json; composer update; fi"
+ - sh -c "if [ '$SYMFONY_DEPS_VERSION' = '3.0' ]; then sed -i 's/~2\.8|^3\.0/3.0.*@dev/g' composer.json; composer update; fi"
+ - sh -c "if [ '$SYMFONY_DEPS_VERSION' = '3.1' ]; then sed -i 's/~2\.8|^3\.0/3.1.*@dev/g' composer.json; composer update; fi"
+ - sh -c "if [ '$SYMFONY_DEPS_VERSION' = '3.2' ]; then sed -i 's/~2\.8|^3\.0/3.2.*@dev/g' composer.json; composer update; fi"
+ - sh -c "if [ '$SYMFONY_DEPS_VERSION' = '' ]; then sed -i 's/~2\.8|^3\.0/2.8.*@dev/g' composer.json; composer update; fi"
+ - composer install
+
+script: ./vendor/bin/simple-phpunit
+
+matrix:
+ include:
+ - php: 5.5
+ - php: 5.6
+ env: TWIG_VERSION=2.0
+ - php: 5.6
+ env: SYMFONY_DEPS_VERSION=3.0
+ - php: 5.6
+ env: SYMFONY_DEPS_VERSION=3.1
+ - php: 5.6
+ env: SYMFONY_DEPS_VERSION=3.2
+ - php: 7.0
+ - php: 7.1
+ - php: hhvm
+
+cache:
+ directories:
+ - .phpunit
diff --git a/vendor/silex/silex/LICENSE b/vendor/silex/silex/LICENSE
new file mode 100644
index 00000000..b420d719
--- /dev/null
+++ b/vendor/silex/silex/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2010-2017 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/silex/silex/README.rst b/vendor/silex/silex/README.rst
new file mode 100644
index 00000000..b79e47b6
--- /dev/null
+++ b/vendor/silex/silex/README.rst
@@ -0,0 +1,64 @@
+Silex, a simple Web Framework
+=============================
+
+Silex is a PHP micro-framework to develop websites based on `Symfony
+components`_:
+
+.. code-block:: php
+
+ get('/hello/{name}', function ($name) use ($app) {
+ return 'Hello '.$app->escape($name);
+ });
+
+ $app->run();
+
+Silex works with PHP 5.5.9 or later.
+
+Installation
+------------
+
+The recommended way to install Silex is through `Composer`_:
+
+.. code-block:: bash
+
+ composer require silex/silex "~2.0"
+
+Alternatively, you can download the `silex.zip`_ file and extract it.
+
+More Information
+----------------
+
+Read the `documentation`_ for more information and `changelog
+`_ for upgrading information.
+
+Tests
+-----
+
+To run the test suite, you need `Composer`_ and `PHPUnit`_:
+
+.. code-block:: bash
+
+ composer install
+ phpunit
+
+Community
+---------
+
+Check out #silex-php on irc.freenode.net.
+
+License
+-------
+
+Silex is licensed under the MIT license.
+
+.. _Symfony components: http://symfony.com
+.. _Composer: http://getcomposer.org
+.. _PHPUnit: https://phpunit.de
+.. _silex.zip: http://silex.sensiolabs.org/download
+.. _documentation: http://silex.sensiolabs.org/documentation
diff --git a/vendor/silex/silex/composer.json b/vendor/silex/silex/composer.json
new file mode 100644
index 00000000..aa2f24ee
--- /dev/null
+++ b/vendor/silex/silex/composer.json
@@ -0,0 +1,69 @@
+{
+ "name": "silex/silex",
+ "description": "The PHP micro-framework based on the Symfony Components",
+ "keywords": ["microframework"],
+ "homepage": "http://silex.sensiolabs.org",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ }
+ ],
+ "require": {
+ "php": ">=5.5.9",
+ "pimple/pimple": "~3.0",
+ "symfony/event-dispatcher": "~2.8|^3.0",
+ "symfony/http-foundation": "~2.8|^3.0",
+ "symfony/http-kernel": "~2.8|^3.0",
+ "symfony/routing": "~2.8|^3.0"
+ },
+ "require-dev": {
+ "symfony/asset": "~2.8|^3.0",
+ "symfony/expression-language": "~2.8|^3.0",
+ "symfony/security": "~2.8|^3.0",
+ "symfony/config": "~2.8|^3.0",
+ "symfony/form": "~2.8|^3.0",
+ "symfony/browser-kit": "~2.8|^3.0",
+ "symfony/css-selector": "~2.8|^3.0",
+ "symfony/debug": "~2.8|^3.0",
+ "symfony/dom-crawler": "~2.8|^3.0",
+ "symfony/finder": "~2.8|^3.0",
+ "symfony/intl": "~2.8|^3.0",
+ "symfony/monolog-bridge": "~2.8|^3.0",
+ "symfony/doctrine-bridge": "~2.8|^3.0",
+ "symfony/options-resolver": "~2.8|^3.0",
+ "symfony/phpunit-bridge": "^3.2",
+ "symfony/process": "~2.8|^3.0",
+ "symfony/serializer": "~2.8|^3.0",
+ "symfony/translation": "~2.8|^3.0",
+ "symfony/twig-bridge": "~2.8|^3.0",
+ "symfony/validator": "~2.8|^3.0",
+ "symfony/var-dumper": "~2.8|^3.0",
+ "twig/twig": "~1.28|~2.0",
+ "doctrine/dbal": "~2.2",
+ "swiftmailer/swiftmailer": "~5",
+ "monolog/monolog": "^1.4.1",
+ "symfony/web-link": "^3.3"
+ },
+ "replace": {
+ "silex/api": "self.version",
+ "silex/providers": "self.version"
+ },
+ "autoload": {
+ "psr-4": { "Silex\\": "src/Silex" }
+ },
+ "autoload-dev" : {
+ "psr-4": { "Silex\\Tests\\" : "tests/Silex/Tests" }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/silex/silex/doc/changelog.rst b/vendor/silex/silex/doc/changelog.rst
new file mode 100644
index 00000000..81beee92
--- /dev/null
+++ b/vendor/silex/silex/doc/changelog.rst
@@ -0,0 +1,378 @@
+Changelog
+=========
+
+2.1.0 (2017-05-03)
+------------------
+
+* added more options to security.firewalls
+* added WebLink component integration
+* added parameters to configure the Twig core extension behavior
+* fixed deprecation notices with symfony/twig-bridge 3.2+ in TwigServiceProvider
+* added FormRegistry as a service to enable the extension point
+* removed the build scripts
+* fixed some deprecation warnings
+* added support for registering Swiftmailer plugins
+
+2.0.4 (2016-11-06)
+------------------
+
+* fixed twig.app_variable definition
+* added support for latest versions of Twig 1.x and 2.0 (Twig runtime loaders)
+* added support for Symfony 2.3
+
+2.0.3 (2016-08-22)
+------------------
+
+* fixed lazy evaluation of 'monolog.use_error_handler'
+* fixed PHP7 type hint on controllers
+
+2.0.2 (2016-06-14)
+------------------
+
+* fixed Symfony 3.1 deprecations
+
+2.0.1 (2016-05-27)
+------------------
+
+* fixed the silex form extension registration to allow overriding default ones
+* removed support for the obsolete Locale Symfony component (uses the Intl one now)
+* added support for Symfony 3.1
+
+2.0.0 (2016-05-18)
+------------------
+
+* decoupled the exception handler from HttpKernelServiceProvider
+* Switched to BCrypt as the default encoder in the security provider
+* added full support for RequestMatcher
+* added support for Symfony Guard
+* added support for callables in CallbackResolver
+* added FormTrait::namedForm()
+* added support for delivery_addresses, delivery_whitelist, and sender_address
+* added support to register form types / form types extensions / form types guessers as services
+* added support for callable in mounts (allow nested route collection to be built easily)
+* added support for conditions on routes
+* added support for the Symfony VarDumper Component
+* added a global Twig variable (an AppVariable instance)
+* [BC BREAK] CSRF has been moved to a standalone provider (``form.secret`` is not available anymore)
+* added support for the Symfony HttpFoundation Twig bridge extension
+* added support for the Symfony Asset Component
+* bumped minimum version of Symfony to 2.8
+* bumped minimum version of PHP to 5.5.0
+* Updated Pimple to 3.0
+* Updated session listeners to extends HttpKernel ones
+* [BC BREAK] Locale management has been moved to LocaleServiceProvider which must be registered
+ if you want Silex to manage your locale (must also be registered for the translation service provider)
+* [BC BREAK] Provider interfaces moved to Silex\Api namespace, published as
+ separate package via subtree split
+* [BC BREAK] ServiceProviderInterface split in to EventListenerProviderInterface
+ and BootableProviderInterface
+* [BC BREAK] Service Provider support files moved under Silex\Provider
+ namespace, allowing publishing as separate package via sub-tree split
+* ``monolog.exception.logger_filter`` option added to Monolog service provider
+* [BC BREAK] ``$app['request']`` service removed, use ``$app['request_stack']`` instead
+
+1.3.6 (2016-XX-XX)
+------------------
+
+* n/a
+
+1.3.5 (2016-01-06)
+------------------
+
+* fixed typo in SecurityServiceProvider
+
+1.3.4 (2015-09-15)
+------------------
+
+* fixed some new deprecations
+* fixed translation registration for the validators
+
+1.3.3 (2015-09-08)
+------------------
+
+* added support for Symfony 3.0 and Twig 2.0
+* fixed some Form deprecations
+* removed deprecated method call in the exception handler
+* fixed Swiftmailer spool flushing when spool is not enabled
+
+1.3.2 (2015-08-24)
+------------------
+
+* no changes
+
+1.3.1 (2015-08-04)
+------------------
+
+* added missing support for the Expression constraint
+* fixed the possibility to override translations for validator error messages
+* fixed sub-mounts with same name clash
+* fixed session logout handler when a firewall is stateless
+
+1.3.0 (2015-06-05)
+------------------
+
+* added a `$app['user']` to get the current user (security provider)
+* added view handlers
+* added support for the OPTIONS HTTP method
+* added caching for the Translator provider
+* deprecated `$app['exception_handler']->disable()` in favor of `unset($app['exception_handler'])`
+* made Silex compatible with Symfony 2.7 an 2.8 (and keep compatibility with Symfony 2.3, 2.5, and 2.6)
+* removed deprecated TwigCoreExtension class (register the new HttpFragmentServiceProvider instead)
+* bumped minimum version of PHP to 5.3.9
+
+1.2.5 (2015-06-04)
+------------------
+
+* no code changes (last version of the 1.2 branch)
+
+1.2.4 (2015-04-11)
+------------------
+
+* fixed the exception message when mounting a collection that doesn't return a ControllerCollection
+* fixed Symfony dependencies (Silex 1.2 is not compatible with Symfony 2.7)
+
+1.2.3 (2015-01-20)
+------------------
+
+* fixed remember me listener
+* fixed translation files loading when they do not exist
+* allowed global after middlewares to return responses like route specific ones
+
+1.2.2 (2014-09-26)
+------------------
+
+* fixed Translator locale management
+* added support for the $app argument in application middlewares (to make it consistent with route middlewares)
+* added form.types to the Form provider
+
+1.2.1 (2014-07-01)
+------------------
+
+* added support permissions in the Monolog provider
+* fixed Switfmailer spool where the event dispatcher is different from the other ones
+* fixed locale when changing it on the translator itself
+
+1.2.0 (2014-03-29)
+------------------
+
+* Allowed disabling the boot logic of MonologServiceProvider
+* Reverted "convert attributes on the request that actually exist"
+* [BC BREAK] Routes are now always added in the order of their registration (even for mounted routes)
+* Added run() on Route to be able to define the controller code
+* Deprecated TwigCoreExtension (register the new HttpFragmentServiceProvider instead)
+* Added HttpFragmentServiceProvider
+* Allowed a callback to be a method call on a service (before, after, finish, error, on Application; convert, before, after on Controller)
+
+1.1.3 (2013-XX-XX)
+------------------
+
+* Fixed translator locale management
+
+1.1.2 (2013-10-30)
+------------------
+
+* Added missing "security.hide_user_not_found" support in SecurityServiceProvider
+* Fixed event listeners that are registered after the boot via the on() method
+
+1.0.2 (2013-10-30)
+------------------
+
+* Fixed SecurityServiceProvider to use null as a fake controller so that routes can be dumped
+
+1.1.1 (2013-10-11)
+------------------
+
+* Removed or replaced deprecated Symfony code
+* Updated code to take advantages of 2.3 new features
+* Only convert attributes on the request that actually exist.
+
+1.1.0 (2013-07-04)
+------------------
+
+* Support for any ``Psr\Log\LoggerInterface`` as opposed to the monolog-bridge
+ one.
+* Made dispatcher proxy methods ``on``, ``before``, ``after`` and ``error``
+ lazy, so that they will not instantiate the dispatcher early.
+* Dropped support for 2.1 and 2.2 versions of Symfony.
+
+1.0.1 (2013-07-04)
+------------------
+
+* Fixed RedirectableUrlMatcher::redirect() when Silex is configured to use a logger
+* Make ``DoctrineServiceProvider`` multi-db support lazy.
+
+1.0.0 (2013-05-03)
+------------------
+
+* **2013-04-12**: Added support for validators as services.
+
+* **2013-04-01**: Added support for host matching with symfony 2.2::
+
+ $app->match('/', function() {
+ // app-specific action
+ })->host('example.com');
+
+ $app->match('/', function ($user) {
+ // user-specific action
+ })->host('{user}.example.com');
+
+* **2013-03-08**: Added support for form type extensions and guessers as
+ services.
+
+* **2013-03-08**: Added support for remember-me via the
+ ``RememberMeServiceProvider``.
+
+* **2013-02-07**: Added ``Application::sendFile()`` to ease sending
+ ``BinaryFileResponse``.
+
+* **2012-11-05**: Filters have been renamed to application middlewares in the
+ documentation.
+
+* **2012-11-05**: The ``before()``, ``after()``, ``error()``, and ``finish()``
+ listener priorities now set the priority of the underlying Symfony event
+ instead of a custom one before.
+
+* **2012-11-05**: Removing the default exception handler should now be done
+ via its ``disable()`` method:
+
+ Before:
+
+ unset($app['exception_handler']);
+
+ After:
+
+ $app['exception_handler']->disable();
+
+* **2012-07-15**: removed the ``monolog.configure`` service. Use the
+ ``extend`` method instead:
+
+ Before::
+
+ $app['monolog.configure'] = $app->protect(function ($monolog) use ($app) {
+ // do something
+ });
+
+ After::
+
+ $app['monolog'] = $app->share($app->extend('monolog', function($monolog, $app) {
+ // do something
+
+ return $monolog;
+ }));
+
+
+* **2012-06-17**: ``ControllerCollection`` now takes a required route instance
+ as a constructor argument.
+
+ Before::
+
+ $controllers = new ControllerCollection();
+
+ After::
+
+ $controllers = new ControllerCollection(new Route());
+
+ // or even better
+ $controllers = $app['controllers_factory'];
+
+* **2012-06-17**: added application traits for PHP 5.4
+
+* **2012-06-16**: renamed ``request.default_locale`` to ``locale``
+
+* **2012-06-16**: Removed the ``translator.loader`` service. See documentation
+ for how to use XLIFF or YAML-based translation files.
+
+* **2012-06-15**: removed the ``twig.configure`` service. Use the ``extend``
+ method instead:
+
+ Before::
+
+ $app['twig.configure'] = $app->protect(function ($twig) use ($app) {
+ // do something
+ });
+
+ After::
+
+ $app['twig'] = $app->share($app->extend('twig', function($twig, $app) {
+ // do something
+
+ return $twig;
+ }));
+
+* **2012-06-13**: Added a route ``before`` middleware
+
+* **2012-06-13**: Renamed the route ``middleware`` to ``before``
+
+* **2012-06-13**: Added an extension for the Symfony Security component
+
+* **2012-05-31**: Made the ``BrowserKit``, ``CssSelector``, ``DomCrawler``,
+ ``Finder`` and ``Process`` components optional dependencies. Projects that
+ depend on them (e.g. through functional tests) should add those dependencies
+ to their ``composer.json``.
+
+* **2012-05-26**: added ``boot()`` to ``ServiceProviderInterface``.
+
+* **2012-05-26**: Removed ``SymfonyBridgesServiceProvider``. It is now implicit
+ by checking the existence of the bridge.
+
+* **2012-05-26**: Removed the ``translator.messages`` parameter (use
+ ``translator.domains`` instead).
+
+* **2012-05-24**: Removed the ``autoloader`` service (use composer instead).
+ The ``*.class_path`` settings on all the built-in providers have also been
+ removed in favor of Composer.
+
+* **2012-05-21**: Changed error() to allow handling specific exceptions.
+
+* **2012-05-20**: Added a way to define settings on a controller collection.
+
+* **2012-05-20**: The Request instance is not available anymore from the
+ Application after it has been handled.
+
+* **2012-04-01**: Added ``finish`` filters.
+
+* **2012-03-20**: Added ``json`` helper::
+
+ $data = array('some' => 'data');
+ $response = $app->json($data);
+
+* **2012-03-11**: Added route middlewares.
+
+* **2012-03-02**: Switched to use Composer for dependency management.
+
+* **2012-02-27**: Updated to Symfony 2.1 session handling.
+
+* **2012-01-02**: Introduced support for streaming responses.
+
+* **2011-09-22**: ``ExtensionInterface`` has been renamed to
+ ``ServiceProviderInterface``. All built-in extensions have been renamed
+ accordingly (for instance, ``Silex\Extension\TwigExtension`` has been
+ renamed to ``Silex\Provider\TwigServiceProvider``).
+
+* **2011-09-22**: The way reusable applications work has changed. The
+ ``mount()`` method now takes an instance of ``ControllerCollection`` instead
+ of an ``Application`` one.
+
+ Before::
+
+ $app = new Application();
+ $app->get('/bar', function() { return 'foo'; });
+
+ return $app;
+
+ After::
+
+ $app = new ControllerCollection();
+ $app->get('/bar', function() { return 'foo'; });
+
+ return $app;
+
+* **2011-08-08**: The controller method configuration is now done on the Controller itself
+
+ Before::
+
+ $app->match('/', function () { echo 'foo'; }, 'GET|POST');
+
+ After::
+
+ $app->match('/', function () { echo 'foo'; })->method('GET|POST');
diff --git a/vendor/silex/silex/doc/conf.py b/vendor/silex/silex/doc/conf.py
new file mode 100644
index 00000000..dfe355c7
--- /dev/null
+++ b/vendor/silex/silex/doc/conf.py
@@ -0,0 +1,17 @@
+import sys, os
+from sphinx.highlighting import lexers
+from pygments.lexers.web import PhpLexer
+
+sys.path.append(os.path.abspath('_exts'))
+
+extensions = []
+master_doc = 'index'
+highlight_language = 'php'
+
+project = u'Silex'
+copyright = u'2010 Fabien Potencier'
+
+version = '0'
+release = '0.0.0'
+
+lexers['php'] = PhpLexer(startinline=True)
diff --git a/vendor/silex/silex/doc/contributing.rst b/vendor/silex/silex/doc/contributing.rst
new file mode 100644
index 00000000..34a339d8
--- /dev/null
+++ b/vendor/silex/silex/doc/contributing.rst
@@ -0,0 +1,34 @@
+Contributing
+============
+
+We are open to contributions to the Silex code. If you find a bug or want to
+contribute a provider, just follow these steps:
+
+* Fork `the Silex repository `_;
+
+* Make your feature addition or bug fix;
+
+* Add tests for it;
+
+* Optionally, add some documentation;
+
+* `Send a pull request
+ `_, to the correct
+ target branch (1.3 for bug fixes, master for new features).
+
+.. note::
+
+ Any code you contribute must be licensed under the MIT
+ License.
+
+Writing Documentation
+=====================
+
+The documentation is written in `reStructuredText
+`_ and can be generated using `sphinx
+`_.
+
+.. code-block:: bash
+
+ $ cd doc
+ $ sphinx-build -b html . build
diff --git a/vendor/silex/silex/doc/cookbook/error_handler.rst b/vendor/silex/silex/doc/cookbook/error_handler.rst
new file mode 100644
index 00000000..235c263a
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/error_handler.rst
@@ -0,0 +1,38 @@
+Converting Errors to Exceptions
+===============================
+
+Silex catches exceptions that are thrown from within a request/response cycle.
+However, it does *not* catch PHP errors and notices. This recipe tells you how
+to catch them by converting them to exceptions.
+
+Registering the ErrorHandler
+----------------------------
+
+The ``Symfony/Debug`` package has an ``ErrorHandler`` class that solves this
+problem. It converts all errors to exceptions, and exceptions are then caught
+by Silex.
+
+Register it by calling the static ``register`` method::
+
+ use Symfony\Component\Debug\ErrorHandler;
+
+ ErrorHandler::register();
+
+It is recommended that you do this as early as possible.
+
+Handling fatal errors
+---------------------
+
+To handle fatal errors, you can additionally register a global
+``ExceptionHandler``::
+
+ use Symfony\Component\Debug\ExceptionHandler;
+
+ ExceptionHandler::register();
+
+In production you may want to disable the debug output by passing ``false`` as
+the ``$debug`` argument::
+
+ use Symfony\Component\Debug\ExceptionHandler;
+
+ ExceptionHandler::register(false);
diff --git a/vendor/silex/silex/doc/cookbook/form_no_csrf.rst b/vendor/silex/silex/doc/cookbook/form_no_csrf.rst
new file mode 100644
index 00000000..e9bf595e
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/form_no_csrf.rst
@@ -0,0 +1,36 @@
+Disabling CSRF Protection on a Form using the FormExtension
+===========================================================
+
+The *FormExtension* provides a service for building form in your application
+with the Symfony Form component. When the :doc:`CSRF Service Provider
+` is registered, the *FormExtension* uses the CSRF Protection
+avoiding Cross-site request forgery, a method by which a malicious user
+attempts to make your legitimate users unknowingly submit data that they don't
+intend to submit.
+
+You can find more details about CSRF Protection and CSRF token in the
+`Symfony Book
+`_.
+
+In some cases (for example, when embedding a form in an html email) you might
+want not to use this protection. The easiest way to avoid this is to
+understand that it is possible to give specific options to your form builder
+through the ``createBuilder()`` function.
+
+Example
+-------
+
+.. code-block:: php
+
+ $form = $app['form.factory']->createBuilder('form', null, array('csrf_protection' => false));
+
+That's it, your form could be submitted from everywhere without CSRF Protection.
+
+Going further
+-------------
+
+This specific example showed how to change the ``csrf_protection`` in the
+``$options`` parameter of the ``createBuilder()`` function. More of them could
+be passed through this parameter, it is as simple as using the Symfony
+``getDefaultOptions()`` method in your form classes. `See more here
+`_.
diff --git a/vendor/silex/silex/doc/cookbook/guard_authentication.rst b/vendor/silex/silex/doc/cookbook/guard_authentication.rst
new file mode 100644
index 00000000..8774f686
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/guard_authentication.rst
@@ -0,0 +1,183 @@
+How to Create a Custom Authentication System with Guard
+=======================================================
+
+Whether you need to build a traditional login form, an API token
+authentication system or you need to integrate with some proprietary
+single-sign-on system, the Guard component can make it easy... and fun!
+
+In this example, you'll build an API token authentication system and
+learn how to work with Guard.
+
+Step 1) Create the Authenticator Class
+--------------------------------------
+
+Suppose you have an API where your clients will send an X-AUTH-TOKEN
+header on each request. This token is composed of the username followed
+by a password, separated by a colon (e.g. ``X-AUTH-TOKEN: coolguy:awesomepassword``).
+Your job is to read this, find the associated user (if any) and check
+the password.
+
+To create a custom authentication system, just create a class and make
+it implement GuardAuthenticatorInterface. Or, extend the simpler
+AbstractGuardAuthenticator. This requires you to implement six methods:
+
+.. code-block:: php
+
+ encoderFactory = $encoderFactory;
+ }
+
+ public function getCredentials(Request $request)
+ {
+ // Checks if the credential header is provided
+ if (!$token = $request->headers->get('X-AUTH-TOKEN')) {
+ return;
+ }
+
+ // Parse the header or ignore it if the format is incorrect.
+ if (false === strpos($token, ':')) {
+ return;
+ }
+ list($username, $secret) = explode(':', $token, 2);
+
+ return array(
+ 'username' => $username,
+ 'secret' => $secret,
+ );
+ }
+
+ public function getUser($credentials, UserProviderInterface $userProvider)
+ {
+ return $userProvider->loadUserByUsername($credentials['username']);
+ }
+
+ public function checkCredentials($credentials, UserInterface $user)
+ {
+ // check credentials - e.g. make sure the password is valid
+ // return true to cause authentication success
+
+ $encoder = $this->encoderFactory->getEncoder($user);
+
+ return $encoder->isPasswordValid(
+ $user->getPassword(),
+ $credentials['secret'],
+ $user->getSalt()
+ );
+ }
+
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
+ {
+ // on success, let the request continue
+ return;
+ }
+
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
+ {
+ $data = array(
+ 'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),
+
+ // or to translate this message
+ // $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
+ );
+
+ return new JsonResponse($data, 403);
+ }
+
+ /**
+ * Called when authentication is needed, but it's not sent
+ */
+ public function start(Request $request, AuthenticationException $authException = null)
+ {
+ $data = array(
+ // you might translate this message
+ 'message' => 'Authentication Required',
+ );
+
+ return new JsonResponse($data, 401);
+ }
+
+ public function supportsRememberMe()
+ {
+ return false;
+ }
+ }
+
+
+Step 2) Configure the Authenticator
+-----------------------------------
+
+To finish this, register the class as a service:
+
+.. code-block:: php
+
+ $app['app.token_authenticator'] = function ($app) {
+ return new App\Security\TokenAuthenticator($app['security.encoder_factory']);
+ };
+
+
+Finally, configure your `security.firewalls` key to use this authenticator:
+
+.. code-block:: php
+
+ $app['security.firewalls'] = array(
+ 'main' => array(
+ 'guard' => array(
+ 'authenticators' => array(
+ 'app.token_authenticator'
+ ),
+
+ // Using more than 1 authenticator, you must specify
+ // which one is used as entry point.
+ // 'entry_point' => 'app.token_authenticator',
+ ),
+ // configure where your users come from. Hardcode them, or load them from somewhere
+ // http://silex.sensiolabs.org/doc/providers/security.html#defining-a-custom-user-provider
+ 'users' => array(
+ //raw password = foo
+ 'victoria' => array('ROLE_USER', '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a'),
+ ),
+ // 'anonymous' => true
+ ),
+ );
+
+.. note::
+ You can use many authenticators, they are executed by the order
+ they are configured.
+
+You did it! You now have a fully-working API token authentication
+system. If your homepage required ROLE_USER, then you could test it
+under different conditions:
+
+.. code-block:: bash
+
+ # test with no token
+ curl http://localhost:8000/
+ # {"message":"Authentication Required"}
+
+ # test with a bad token
+ curl -H "X-AUTH-TOKEN: alan" http://localhost:8000/
+ # {"message":"Username could not be found."}
+
+ # test with a working token
+ curl -H "X-AUTH-TOKEN: victoria:foo" http://localhost:8000/
+ # the homepage controller is executed: the page loads normally
+
+For more details read the Symfony cookbook entry on
+`How to Create a Custom Authentication System with Guard `_.
diff --git a/vendor/silex/silex/doc/cookbook/index.rst b/vendor/silex/silex/doc/cookbook/index.rst
new file mode 100644
index 00000000..53b10fe2
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/index.rst
@@ -0,0 +1,40 @@
+Cookbook
+========
+
+The cookbook section contains recipes for solving specific problems.
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+ json_request_body
+ session_storage
+ form_no_csrf
+ validator_yaml
+ sub_requests
+ error_handler
+ multiple_loggers
+ guard_authentication
+
+Recipes
+-------
+
+* :doc:`Accepting a JSON Request Body ` A common need when
+ building a restful API is the ability to accept a JSON encoded entity from
+ the request body.
+
+* :doc:`Using PdoSessionStorage to store Sessions in the Database
+ `.
+
+* :doc:`Disabling the CSRF Protection on a Form using the FormExtension
+ `.
+
+* :doc:`Using YAML to configure Validation `.
+
+* :doc:`Making sub-Requests `.
+
+* :doc:`Converting Errors to Exceptions `.
+
+* :doc:`Using multiple Monolog Loggers `.
+
+* :doc:`How to Create a Custom Authentication System with Guard `.
diff --git a/vendor/silex/silex/doc/cookbook/json_request_body.rst b/vendor/silex/silex/doc/cookbook/json_request_body.rst
new file mode 100644
index 00000000..47159008
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/json_request_body.rst
@@ -0,0 +1,95 @@
+Accepting a JSON Request Body
+=============================
+
+A common need when building a restful API is the ability to accept a JSON
+encoded entity from the request body.
+
+An example for such an API could be a blog post creation.
+
+Example API
+-----------
+
+In this example we will create an API for creating a blog post. The following
+is a spec of how we want it to work.
+
+Request
+~~~~~~~
+
+In the request we send the data for the blog post as a JSON object. We also
+indicate that using the ``Content-Type`` header:
+
+.. code-block:: text
+
+ POST /blog/posts
+ Accept: application/json
+ Content-Type: application/json
+ Content-Length: 57
+
+ {"title":"Hello World!","body":"This is my first post!"}
+
+Response
+~~~~~~~~
+
+The server responds with a 201 status code, telling us that the post was
+created. It tells us the ``Content-Type`` of the response, which is also
+JSON:
+
+.. code-block:: text
+
+ HTTP/1.1 201 Created
+ Content-Type: application/json
+ Content-Length: 65
+ Connection: close
+
+ {"id":"1","title":"Hello World!","body":"This is my first post!"}
+
+Parsing the request body
+------------------------
+
+The request body should only be parsed as JSON if the ``Content-Type`` header
+begins with ``application/json``. Since we want to do this for every request,
+the easiest solution is to use an application before middleware.
+
+We simply use ``json_decode`` to parse the content of the request and then
+replace the request data on the ``$request`` object::
+
+ use Symfony\Component\HttpFoundation\Request;
+ use Symfony\Component\HttpFoundation\ParameterBag;
+
+ $app->before(function (Request $request) {
+ if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
+ $data = json_decode($request->getContent(), true);
+ $request->request->replace(is_array($data) ? $data : array());
+ }
+ });
+
+Controller implementation
+-------------------------
+
+Our controller will create a new blog post from the data provided and will
+return the post object, including its ``id``, as JSON::
+
+ use Symfony\Component\HttpFoundation\Request;
+ use Symfony\Component\HttpFoundation\Response;
+
+ $app->post('/blog/posts', function (Request $request) use ($app) {
+ $post = array(
+ 'title' => $request->request->get('title'),
+ 'body' => $request->request->get('body'),
+ );
+
+ $post['id'] = createPost($post);
+
+ return $app->json($post, 201);
+ });
+
+Manual testing
+--------------
+
+In order to manually test our API, we can use the ``curl`` command line
+utility, which allows sending HTTP requests:
+
+.. code-block:: bash
+
+ $ curl http://blog.lo/blog/posts -d '{"title":"Hello World!","body":"This is my first post!"}' -H 'Content-Type: application/json'
+ {"id":"1","title":"Hello World!","body":"This is my first post!"}
diff --git a/vendor/silex/silex/doc/cookbook/multiple_loggers.rst b/vendor/silex/silex/doc/cookbook/multiple_loggers.rst
new file mode 100644
index 00000000..cb103953
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/multiple_loggers.rst
@@ -0,0 +1,69 @@
+Using multiple Monolog Loggers
+==============================
+
+Having separate instances of Monolog for different parts of your system is
+often desirable and allows you to configure them independently, allowing for fine
+grained control of where your logging goes and in what detail.
+
+This simple example allows you to quickly configure several monolog instances,
+using the bundled handler, but each with a different channel.
+
+.. code-block:: php
+
+ $app['monolog.factory'] = $app->protect(function ($name) use ($app) {
+ $log = new $app['monolog.logger.class']($name);
+ $log->pushHandler($app['monolog.handler']);
+
+ return $log;
+ });
+
+ foreach (array('auth', 'payments', 'stats') as $channel) {
+ $app['monolog.'.$channel] = function ($app) use ($channel) {
+ return $app['monolog.factory']($channel);
+ };
+ }
+
+As your application grows, or your logging needs for certain areas of the
+system become apparent, it should be straightforward to then configure that
+particular service separately, including your customizations.
+
+.. code-block:: php
+
+ use Monolog\Handler\StreamHandler;
+
+ $app['monolog.payments'] = function ($app) {
+ $log = new $app['monolog.logger.class']('payments');
+ $handler = new StreamHandler($app['monolog.payments.logfile'], $app['monolog.payment.level']);
+ $log->pushHandler($handler);
+
+ return $log;
+ };
+
+Alternatively, you could attempt to make the factory more complicated, and rely
+on some conventions, such as checking for an array of handlers registered with
+the container with the channel name, defaulting to the bundled handler.
+
+.. code-block:: php
+
+ use Monolog\Handler\StreamHandler;
+ use Monolog\Logger;
+
+ $app['monolog.factory'] = $app->protect(function ($name) use ($app) {
+ $log = new $app['monolog.logger.class']($name);
+
+ $handlers = isset($app['monolog.'.$name.'.handlers'])
+ ? $app['monolog.'.$name.'.handlers']
+ : array($app['monolog.handler']);
+
+ foreach ($handlers as $handler) {
+ $log->pushHandler($handler);
+ }
+
+ return $log;
+ });
+
+ $app['monolog.payments.handlers'] = function ($app) {
+ return array(
+ new StreamHandler(__DIR__.'/../payments.log', Logger::DEBUG),
+ );
+ };
diff --git a/vendor/silex/silex/doc/cookbook/session_storage.rst b/vendor/silex/silex/doc/cookbook/session_storage.rst
new file mode 100644
index 00000000..29328b49
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/session_storage.rst
@@ -0,0 +1,89 @@
+Using PdoSessionStorage to store Sessions in the Database
+=========================================================
+
+By default, the :doc:`SessionServiceProvider ` writes
+session information in files using Symfony NativeFileSessionStorage. Most
+medium to large websites use a database to store sessions instead of files,
+because databases are easier to use and scale in a multi-webserver environment.
+
+Symfony's `NativeSessionStorage
+`_
+has multiple storage handlers and one of them uses PDO to store sessions,
+`PdoSessionHandler
+`_.
+To use it, replace the ``session.storage.handler`` service in your application
+like explained below.
+
+With a dedicated PDO service
+----------------------------
+
+.. code-block:: php
+
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+ $app->register(new Silex\Provider\SessionServiceProvider());
+
+ $app['pdo.dsn'] = 'mysql:dbname=mydatabase';
+ $app['pdo.user'] = 'myuser';
+ $app['pdo.password'] = 'mypassword';
+
+ $app['session.db_options'] = array(
+ 'db_table' => 'session',
+ 'db_id_col' => 'session_id',
+ 'db_data_col' => 'session_value',
+ 'db_time_col' => 'session_time',
+ );
+
+ $app['pdo'] = function () use ($app) {
+ return new PDO(
+ $app['pdo.dsn'],
+ $app['pdo.user'],
+ $app['pdo.password']
+ );
+ };
+
+ $app['session.storage.handler'] = function () use ($app) {
+ return new PdoSessionHandler(
+ $app['pdo'],
+ $app['session.db_options']
+ );
+ };
+
+Using the DoctrineServiceProvider
+---------------------------------
+
+When using the :doc:`DoctrineServiceProvider ` You don't
+have to make another database connection, simply pass the getWrappedConnection method.
+
+.. code-block:: php
+
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+ $app->register(new Silex\Provider\SessionServiceProvider());
+
+ $app['session.storage.handler'] = function () use ($app) {
+ return new PdoSessionHandler(
+ $app['db']->getWrappedConnection(),
+ array(
+ 'db_table' => 'session',
+ 'db_id_col' => 'session_id',
+ 'db_data_col' => 'session_value',
+ 'db_lifetime_col' => 'session_lifetime',
+ 'db_time_col' => 'session_time',
+ )
+ );
+ };
+
+Database structure
+------------------
+
+PdoSessionStorage needs a database table with 3 columns:
+
+* ``session_id``: ID column (VARCHAR(255) or larger)
+* ``session_value``: Value column (TEXT or CLOB)
+* ``session_lifetime``: Lifetime column (INTEGER)
+* ``session_time``: Time column (INTEGER)
+
+You can find examples of SQL statements to create the session table in the
+`Symfony cookbook
+`_
diff --git a/vendor/silex/silex/doc/cookbook/sub_requests.rst b/vendor/silex/silex/doc/cookbook/sub_requests.rst
new file mode 100644
index 00000000..95d39136
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/sub_requests.rst
@@ -0,0 +1,137 @@
+Making sub-Requests
+===================
+
+Since Silex is based on the ``HttpKernelInterface``, it allows you to simulate
+requests against your application. This means that you can embed a page within
+another, it also allows you to forward a request which is essentially an
+internal redirect that does not change the URL.
+
+Basics
+------
+
+You can make a sub-request by calling the ``handle`` method on the
+``Application``. This method takes three arguments:
+
+* ``$request``: An instance of the ``Request`` class which represents the
+ HTTP request.
+
+* ``$type``: Must be either ``HttpKernelInterface::MASTER_REQUEST`` or
+ ``HttpKernelInterface::SUB_REQUEST``. Certain listeners are only executed for
+ the master request, so it's important that this is set to ``SUB_REQUEST``.
+
+* ``$catch``: Catches exceptions and turns them into a response with status code
+ ``500``. This argument defaults to ``true``. For sub-requests you will most
+ likely want to set it to ``false``.
+
+By calling ``handle``, you can make a sub-request manually. Here's an example::
+
+ use Symfony\Component\HttpFoundation\Request;
+ use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+ $subRequest = Request::create('/');
+ $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
+
+There's some more things that you need to keep in mind though. In most cases
+you will want to forward some parts of the current master request to the
+sub-request like cookies, server information, or the session.
+
+Here is a more advanced example that forwards said information (``$request``
+holds the master request)::
+
+ use Symfony\Component\HttpFoundation\Request;
+ use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+ $subRequest = Request::create('/', 'GET', array(), $request->cookies->all(), array(), $request->server->all());
+ if ($request->getSession()) {
+ $subRequest->setSession($request->getSession());
+ }
+
+ $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
+
+To forward this response to the client, you can simply return it from a
+controller::
+
+ use Silex\Application;
+ use Symfony\Component\HttpFoundation\Request;
+ use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+ $app->get('/foo', function (Application $app, Request $request) {
+ $subRequest = Request::create('/', ...);
+ $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
+
+ return $response;
+ });
+
+If you want to embed the response as part of a larger page you can call
+``Response::getContent``::
+
+ $header = ...;
+ $footer = ...;
+ $body = $response->getContent();
+
+ return $header.$body.$footer;
+
+Rendering pages in Twig templates
+---------------------------------
+
+The :doc:`TwigServiceProvider ` provides a ``render``
+function that you can use in Twig templates. It gives you a convenient way to
+embed pages.
+
+.. code-block:: jinja
+
+ {{ render('/sidebar') }}
+
+For details, refer to the :doc:`TwigServiceProvider ` docs.
+
+Edge Side Includes
+------------------
+
+You can use ESI either through the :doc:`HttpCacheServiceProvider
+` or a reverse proxy cache such as Varnish. This also
+allows you to embed pages, however it also gives you the benefit of caching
+parts of the page.
+
+Here is an example of how you would embed a page via ESI:
+
+.. code-block:: jinja
+
+
+
+For details, refer to the :doc:`HttpCacheServiceProvider
+` docs.
+
+Dealing with the request base URL
+---------------------------------
+
+One thing to watch out for is the base URL. If your application is not
+hosted at the webroot of your web server, then you may have an URL like
+``http://example.org/foo/index.php/articles/42``.
+
+In this case, ``/foo/index.php`` is your request base path. Silex accounts for
+this path prefix in the routing process, it reads it from
+``$request->server``. In the context of sub-requests this can lead to issues,
+because if you do not prepend the base path the request could mistake a part
+of the path you want to match as the base path and cut it off.
+
+You can prevent that from happening by always prepending the base path when
+constructing a request::
+
+ $url = $request->getUriForPath('/');
+ $subRequest = Request::create($url, 'GET', array(), $request->cookies->all(), array(), $request->server->all());
+
+This is something to be aware of when making sub-requests by hand.
+
+Services depending on the Request
+---------------------------------
+
+The container is a concept that is global to a Silex application, since the
+application object **is** the container. Any request that is run against an
+application will re-use the same set of services. Since these services are
+mutable, code in a master request can affect the sub-requests and vice versa.
+Any services depending on the ``request`` service will store the first request
+that they get (could be master or sub-request), and keep using it, even if
+that request is already over.
+
+Instead of injecting the ``request`` service, you should always inject the
+``request_stack`` one instead.
diff --git a/vendor/silex/silex/doc/cookbook/validator_yaml.rst b/vendor/silex/silex/doc/cookbook/validator_yaml.rst
new file mode 100644
index 00000000..10a41fcf
--- /dev/null
+++ b/vendor/silex/silex/doc/cookbook/validator_yaml.rst
@@ -0,0 +1,35 @@
+Using YAML to configure Validation
+==================================
+
+Simplicity is at the heart of Silex so there is no out of the box solution to
+use YAML files for validation. But this doesn't mean that this is not
+possible. Let's see how to do it.
+
+First, you need to install the YAML Component:
+
+.. code-block:: bash
+
+ composer require symfony/yaml
+
+Next, you need to tell the Validation Service that you are not using
+``StaticMethodLoader`` to load your class metadata but a YAML file::
+
+ $app->register(new ValidatorServiceProvider());
+
+ $app['validator.mapping.class_metadata_factory'] = new Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory(
+ new Symfony\Component\Validator\Mapping\Loader\YamlFileLoader(__DIR__.'/validation.yml')
+ );
+
+Now, we can replace the usage of the static method and move all the validation
+rules to ``validation.yml``:
+
+.. code-block:: yaml
+
+ # validation.yml
+ Post:
+ properties:
+ title:
+ - NotNull: ~
+ - NotBlank: ~
+ body:
+ - Min: 100
diff --git a/vendor/silex/silex/doc/index.rst b/vendor/silex/silex/doc/index.rst
new file mode 100644
index 00000000..d1a851d0
--- /dev/null
+++ b/vendor/silex/silex/doc/index.rst
@@ -0,0 +1,19 @@
+The Book
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ intro
+ usage
+ middlewares
+ organizing_controllers
+ services
+ providers
+ testing
+ cookbook/index
+ internals
+ contributing
+ providers/index
+ web_servers
+ changelog
diff --git a/vendor/silex/silex/doc/internals.rst b/vendor/silex/silex/doc/internals.rst
new file mode 100644
index 00000000..c7ffac8c
--- /dev/null
+++ b/vendor/silex/silex/doc/internals.rst
@@ -0,0 +1,84 @@
+Internals
+=========
+
+This chapter will tell you how Silex works internally.
+
+Silex
+-----
+
+Application
+~~~~~~~~~~~
+
+The application is the main interface to Silex. It implements Symfony's
+`HttpKernelInterface
+`_,
+so you can pass a `Request
+`_
+to the ``handle`` method and it will return a `Response
+`_.
+
+It extends the ``Pimple`` service container, allowing for flexibility on the
+outside as well as the inside. You could replace any service, and you are also
+able to read them.
+
+The application makes strong use of the `EventDispatcher
+`_ to hook into the Symfony `HttpKernel
+`_
+events. This allows fetching the ``Request``, converting string responses into
+``Response`` objects and handling Exceptions. We also use it to dispatch some
+custom events like before/after middlewares and errors.
+
+Controller
+~~~~~~~~~~
+
+The Symfony `Route
+`_ is
+actually quite powerful. Routes can be named, which allows for URL generation.
+They can also have requirements for the variable parts. In order to allow
+setting these through a nice interface, the ``match`` method (which is used by
+``get``, ``post``, etc.) returns an instance of the ``Controller``, which
+wraps a route.
+
+ControllerCollection
+~~~~~~~~~~~~~~~~~~~~
+
+One of the goals of exposing the `RouteCollection
+`_
+was to make it mutable, so providers could add stuff to it. The challenge here
+is the fact that routes know nothing about their name. The name only has
+meaning in context of the ``RouteCollection`` and cannot be changed.
+
+To solve this challenge we came up with a staging area for routes. The
+``ControllerCollection`` holds the controllers until ``flush`` is called, at
+which point the routes are added to the ``RouteCollection``. Also, the
+controllers are then frozen. This means that they can no longer be modified
+and will throw an Exception if you try to do so.
+
+Unfortunately no good way for flushing implicitly could be found, which is why
+flushing is now always explicit. The Application will flush, but if you want
+to read the ``ControllerCollection`` before the request takes place, you will
+have to call flush yourself.
+
+The ``Application`` provides a shortcut ``flush`` method for flushing the
+``ControllerCollection``.
+
+.. tip::
+
+ Instead of creating an instance of ``RouteCollection`` yourself, use the
+ ``$app['controllers_factory']`` factory instead.
+
+Symfony
+-------
+
+Following Symfony components are used by Silex:
+
+* **HttpFoundation**: For ``Request`` and ``Response``.
+
+* **HttpKernel**: Because we need a heart.
+
+* **Routing**: For matching defined routes.
+
+* **EventDispatcher**: For hooking into the HttpKernel.
+
+For more information, `check out the Symfony website `_.
diff --git a/vendor/silex/silex/doc/intro.rst b/vendor/silex/silex/doc/intro.rst
new file mode 100644
index 00000000..2ab2bc30
--- /dev/null
+++ b/vendor/silex/silex/doc/intro.rst
@@ -0,0 +1,50 @@
+Introduction
+============
+
+Silex is a PHP microframework. It is built on the shoulders of `Symfony`_ and
+`Pimple`_ and also inspired by `Sinatra`_.
+
+Silex aims to be:
+
+* *Concise*: Silex exposes an intuitive and concise API.
+
+* *Extensible*: Silex has an extension system based around the Pimple
+ service-container that makes it easy to tie in third party libraries.
+
+* *Testable*: Silex uses Symfony's HttpKernel which abstracts request and
+ response. This makes it very easy to test apps and the framework itself. It
+ also respects the HTTP specification and encourages its proper use.
+
+In a nutshell, you define controllers and map them to routes, all in one step.
+
+Usage
+-----
+
+.. code-block:: php
+
+ get('/hello/{name}', function ($name) use ($app) {
+ return 'Hello '.$app->escape($name);
+ });
+
+ $app->run();
+
+All that is needed to get access to the Framework is to include the
+autoloader.
+
+Next, a route for ``/hello/{name}`` that matches for ``GET`` requests is
+defined. When the route matches, the function is executed and the return value
+is sent back to the client.
+
+Finally, the app is run. Visit ``/hello/world`` to see the result. It's really
+that easy!
+
+.. _Symfony: http://symfony.com/
+.. _Pimple: http://pimple.sensiolabs.org/
+.. _Sinatra: http://www.sinatrarb.com/
diff --git a/vendor/silex/silex/doc/middlewares.rst b/vendor/silex/silex/doc/middlewares.rst
new file mode 100644
index 00000000..c5c17cf0
--- /dev/null
+++ b/vendor/silex/silex/doc/middlewares.rst
@@ -0,0 +1,162 @@
+Middleware
+==========
+
+Silex allows you to run code, that changes the default Silex behavior, at
+different stages during the handling of a request through *middleware*:
+
+* *Application middleware* is triggered independently of the current handled
+ request;
+
+* *Route middleware* is triggered when its associated route is matched.
+
+Application Middleware
+----------------------
+
+Application middleware is only run for the "master" Request.
+
+Before Middleware
+~~~~~~~~~~~~~~~~~
+
+A *before* application middleware allows you to tweak the Request before the
+controller is executed::
+
+ $app->before(function (Request $request, Application $app) {
+ // ...
+ });
+
+By default, the middleware is run after the routing and the security.
+
+If you want your middleware to be run even if an exception is thrown early on
+(on a 404 or 403 error for instance), then, you need to register it as an
+early event::
+
+ $app->before(function (Request $request, Application $app) {
+ // ...
+ }, Application::EARLY_EVENT);
+
+In this case, the routing and the security won't have been executed, and so you
+won't have access to the locale, the current route, or the security user.
+
+.. note::
+
+ The before middleware is an event registered on the Symfony *request*
+ event.
+
+After Middleware
+~~~~~~~~~~~~~~~~
+
+An *after* application middleware allows you to tweak the Response before it
+is sent to the client::
+
+ $app->after(function (Request $request, Response $response) {
+ // ...
+ });
+
+.. note::
+
+ The after middleware is an event registered on the Symfony *response*
+ event.
+
+Finish Middleware
+~~~~~~~~~~~~~~~~~
+
+A *finish* application middleware allows you to execute tasks after the
+Response has been sent to the client (like sending emails or logging)::
+
+ $app->finish(function (Request $request, Response $response) {
+ // ...
+ // Warning: modifications to the Request or Response will be ignored
+ });
+
+.. note::
+
+ The finish middleware is an event registered on the Symfony *terminate*
+ event.
+
+Route Middleware
+----------------
+
+Route middleware is added to routes or route collections and it is only
+triggered when the corresponding route is matched. You can also stack them::
+
+ $app->get('/somewhere', function () {
+ // ...
+ })
+ ->before($before1)
+ ->before($before2)
+ ->after($after1)
+ ->after($after2)
+ ;
+
+Before Middleware
+~~~~~~~~~~~~~~~~~
+
+A *before* route middleware is fired just before the route callback, but after
+the *before* application middleware::
+
+ $before = function (Request $request, Application $app) {
+ // ...
+ };
+
+ $app->get('/somewhere', function () {
+ // ...
+ })
+ ->before($before);
+
+After Middleware
+~~~~~~~~~~~~~~~~
+
+An *after* route middleware is fired just after the route callback, but before
+the application *after* application middleware::
+
+ $after = function (Request $request, Response $response, Application $app) {
+ // ...
+ };
+
+ $app->get('/somewhere', function () {
+ // ...
+ })
+ ->after($after);
+
+Middleware Priority
+-------------------
+
+You can add as much middleware as you want, in which case they are triggered
+in the same order as you added them.
+
+You can explicitly control the priority of your middleware by passing an
+additional argument to the registration methods::
+
+ $app->before(function (Request $request) {
+ // ...
+ }, 32);
+
+As a convenience, two constants allow you to register an event as early as
+possible or as late as possible::
+
+ $app->before(function (Request $request) {
+ // ...
+ }, Application::EARLY_EVENT);
+
+ $app->before(function (Request $request) {
+ // ...
+ }, Application::LATE_EVENT);
+
+Short-circuiting the Controller
+-------------------------------
+
+If a *before* middleware returns a ``Response`` object, the request handling is
+short-circuited (the next middleware won't be run, nor the route
+callback), and the Response is passed to the *after* middleware right away::
+
+ $app->before(function (Request $request) {
+ // redirect the user to the login screen if access to the Resource is protected
+ if (...) {
+ return new RedirectResponse('/login');
+ }
+ });
+
+.. note::
+
+ A ``RuntimeException`` is thrown if a before middleware does not return a
+ Response or ``null``.
diff --git a/vendor/silex/silex/doc/organizing_controllers.rst b/vendor/silex/silex/doc/organizing_controllers.rst
new file mode 100644
index 00000000..50558cbb
--- /dev/null
+++ b/vendor/silex/silex/doc/organizing_controllers.rst
@@ -0,0 +1,84 @@
+Organizing Controllers
+======================
+
+When your application starts to define too many controllers, you might want to
+group them logically::
+
+ // define controllers for a blog
+ $blog = $app['controllers_factory'];
+ $blog->get('/', function () {
+ return 'Blog home page';
+ });
+ // ...
+
+ // define controllers for a forum
+ $forum = $app['controllers_factory'];
+ $forum->get('/', function () {
+ return 'Forum home page';
+ });
+
+ // define "global" controllers
+ $app->get('/', function () {
+ return 'Main home page';
+ });
+
+ $app->mount('/blog', $blog);
+ $app->mount('/forum', $forum);
+
+ // define controllers for a admin
+ $app->mount('/admin', function ($admin) {
+ // recursively mount
+ $admin->mount('/blog', function ($user) {
+ $user->get('/', function () {
+ return 'Admin Blog home page';
+ });
+ });
+ });
+
+.. note::
+
+ ``$app['controllers_factory']`` is a factory that returns a new instance
+ of ``ControllerCollection`` when used.
+
+``mount()`` prefixes all routes with the given prefix and merges them into the
+main Application. So, ``/`` will map to the main home page, ``/blog/`` to the
+blog home page, ``/forum/`` to the forum home page, and ``/admin/blog/`` to the
+admin blog home page.
+
+.. caution::
+
+ When mounting a route collection under ``/blog``, it is not possible to
+ define a route for the ``/blog`` URL. The shortest possible URL is
+ ``/blog/``.
+
+.. note::
+
+ When calling ``get()``, ``match()``, or any other HTTP methods on the
+ Application, you are in fact calling them on a default instance of
+ ``ControllerCollection`` (stored in ``$app['controllers']``).
+
+Another benefit is the ability to apply settings on a set of controllers very
+easily. Building on the example from the middleware section, here is how you
+would secure all controllers for the backend collection::
+
+ $backend = $app['controllers_factory'];
+
+ // ensure that all controllers require logged-in users
+ $backend->before($mustBeLogged);
+
+.. tip::
+
+ For a better readability, you can split each controller collection into a
+ separate file::
+
+ // blog.php
+ $blog = $app['controllers_factory'];
+ $blog->get('/', function () { return 'Blog home page'; });
+
+ return $blog;
+
+ // app.php
+ $app->mount('/blog', include 'blog.php');
+
+ Instead of requiring a file, you can also create a :ref:`Controller
+ provider `.
diff --git a/vendor/silex/silex/doc/providers.rst b/vendor/silex/silex/doc/providers.rst
new file mode 100644
index 00000000..c3d049db
--- /dev/null
+++ b/vendor/silex/silex/doc/providers.rst
@@ -0,0 +1,262 @@
+Providers
+=========
+
+Providers allow the developer to reuse parts of an application into another
+one. Silex provides two types of providers defined by two interfaces:
+``ServiceProviderInterface`` for services and ``ControllerProviderInterface``
+for controllers.
+
+Service Providers
+-----------------
+
+Loading providers
+~~~~~~~~~~~~~~~~~
+
+In order to load and use a service provider, you must register it on the
+application::
+
+ $app = new Silex\Application();
+
+ $app->register(new Acme\DatabaseServiceProvider());
+
+You can also provide some parameters as a second argument. These will be set
+**after** the provider is registered, but **before** it is booted::
+
+ $app->register(new Acme\DatabaseServiceProvider(), array(
+ 'database.dsn' => 'mysql:host=localhost;dbname=myapp',
+ 'database.user' => 'root',
+ 'database.password' => 'secret_root_password',
+ ));
+
+Conventions
+~~~~~~~~~~~
+
+You need to watch out in what order you do certain things when interacting
+with providers. Just keep these rules in mind:
+
+* Overriding existing services must occur **after** the provider is
+ registered.
+
+ *Reason: If the service already exists, the provider will overwrite it.*
+
+* You can set parameters any time **after** the provider is registered, but
+ **before** the service is accessed.
+
+ *Reason: Providers can set default values for parameters. Just like with
+ services, the provider will overwrite existing values.*
+
+Included providers
+~~~~~~~~~~~~~~~~~~
+
+There are a few providers that you get out of the box. All of these are within
+the ``Silex\Provider`` namespace:
+
+* :doc:`AssetServiceProvider `
+* :doc:`CsrfServiceProvider `
+* :doc:`DoctrineServiceProvider `
+* :doc:`FormServiceProvider `
+* :doc:`HttpCacheServiceProvider `
+* :doc:`HttpFragmentServiceProvider `
+* :doc:`LocaleServiceProvider `
+* :doc:`MonologServiceProvider `
+* :doc:`RememberMeServiceProvider `
+* :doc:`SecurityServiceProvider `
+* :doc:`SerializerServiceProvider `
+* :doc:`ServiceControllerServiceProvider `
+* :doc:`SessionServiceProvider `
+* :doc:`SwiftmailerServiceProvider `
+* :doc:`TranslationServiceProvider `
+* :doc:`TwigServiceProvider `
+* :doc:`ValidatorServiceProvider `
+* :doc:`VarDumperServiceProvider `
+
+.. note::
+
+ The Silex core team maintains a `WebProfiler
+ `_ provider that helps debug
+ code in the development environment thanks to the Symfony web debug toolbar
+ and the Symfony profiler.
+
+Third party providers
+~~~~~~~~~~~~~~~~~~~~~
+
+Some service providers are developed by the community. Those third-party
+providers are listed on `Silex' repository wiki
+`_.
+
+You are encouraged to share yours.
+
+Creating a provider
+~~~~~~~~~~~~~~~~~~~
+
+Providers must implement the ``Pimple\ServiceProviderInterface``::
+
+ interface ServiceProviderInterface
+ {
+ public function register(Container $container);
+ }
+
+This is very straight forward, just create a new class that implements the
+register method. In the ``register()`` method, you can define services on the
+application which then may make use of other services and parameters.
+
+.. tip::
+
+ The ``Pimple\ServiceProviderInterface`` belongs to the Pimple package, so
+ take care to only use the API of ``Pimple\Container`` within your
+ ``register`` method. Not only is this a good practice due to the way Pimple
+ and Silex work, but may allow your provider to be used outside of Silex.
+
+Optionally, your service provider can implement the
+``Silex\Api\BootableProviderInterface``. A bootable provider must
+implement the ``boot()`` method, with which you can configure the application, just
+before it handles a request::
+
+ interface BootableProviderInterface
+ {
+ function boot(Application $app);
+ }
+
+Another optional interface, is the ``Silex\Api\EventListenerProviderInterface``.
+This interface contains the ``subscribe()`` method, which allows your provider to
+subscribe event listener with Silex's EventDispatcher, just before it handles a
+request::
+
+ interface EventListenerProviderInterface
+ {
+ function subscribe(Container $app, EventDispatcherInterface $dispatcher);
+ }
+
+Here is an example of such a provider::
+
+ namespace Acme;
+
+ use Pimple\Container;
+ use Pimple\ServiceProviderInterface;
+ use Silex\Application;
+ use Silex\Api\BootableProviderInterface;
+ use Silex\Api\EventListenerProviderInterface;
+ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+ use Symfony\Component\HttpKernel\KernelEvents;
+ use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+
+ class HelloServiceProvider implements ServiceProviderInterface, BootableProviderInterface, EventListenerProviderInterface
+ {
+ public function register(Container $app)
+ {
+ $app['hello'] = $app->protect(function ($name) use ($app) {
+ $default = $app['hello.default_name'] ? $app['hello.default_name'] : '';
+ $name = $name ?: $default;
+
+ return 'Hello '.$app->escape($name);
+ });
+ }
+
+ public function boot(Application $app)
+ {
+ // do something
+ }
+
+ public function subscribe(Container $app, EventDispatcherInterface $dispatcher)
+ {
+ $dispatcher->addListener(KernelEvents::REQUEST, function(FilterResponseEvent $event) use ($app) {
+ // do something
+ });
+ }
+ }
+
+This class provides a ``hello`` service which is a protected closure. It takes
+a ``name`` argument and will return ``hello.default_name`` if no name is
+given. If the default is also missing, it will use an empty string.
+
+You can now use this provider as follows::
+
+ use Symfony\Component\HttpFoundation\Request;
+
+ $app = new Silex\Application();
+
+ $app->register(new Acme\HelloServiceProvider(), array(
+ 'hello.default_name' => 'Igor',
+ ));
+
+ $app->get('/hello', function (Request $request) use ($app) {
+ $name = $request->get('name');
+
+ return $app['hello']($name);
+ });
+
+In this example we are getting the ``name`` parameter from the query string,
+so the request path would have to be ``/hello?name=Fabien``.
+
+.. _controller-providers:
+
+Controller Providers
+--------------------
+
+Loading providers
+~~~~~~~~~~~~~~~~~
+
+In order to load and use a controller provider, you must "mount" its
+controllers under a path::
+
+ $app = new Silex\Application();
+
+ $app->mount('/blog', new Acme\BlogControllerProvider());
+
+All controllers defined by the provider will now be available under the
+``/blog`` path.
+
+Creating a provider
+~~~~~~~~~~~~~~~~~~~
+
+Providers must implement the ``Silex\Api\ControllerProviderInterface``::
+
+ interface ControllerProviderInterface
+ {
+ public function connect(Application $app);
+ }
+
+Here is an example of such a provider::
+
+ namespace Acme;
+
+ use Silex\Application;
+ use Silex\Api\ControllerProviderInterface;
+
+ class HelloControllerProvider implements ControllerProviderInterface
+ {
+ public function connect(Application $app)
+ {
+ // creates a new controller based on the default route
+ $controllers = $app['controllers_factory'];
+
+ $controllers->get('/', function (Application $app) {
+ return $app->redirect('/hello');
+ });
+
+ return $controllers;
+ }
+ }
+
+The ``connect`` method must return an instance of ``ControllerCollection``.
+``ControllerCollection`` is the class where all controller related methods are
+defined (like ``get``, ``post``, ``match``, ...).
+
+.. tip::
+
+ The ``Application`` class acts in fact as a proxy for these methods.
+
+You can use this provider as follows::
+
+ $app = new Silex\Application();
+
+ $app->mount('/blog', new Acme\HelloControllerProvider());
+
+In this example, the ``/blog/`` path now references the controller defined in
+the provider.
+
+.. tip::
+
+ You can also define a provider that implements both the service and the
+ controller provider interface and package in the same class the services
+ needed to make your controllers work.
diff --git a/vendor/silex/silex/doc/providers/asset.rst b/vendor/silex/silex/doc/providers/asset.rst
new file mode 100644
index 00000000..72c3d703
--- /dev/null
+++ b/vendor/silex/silex/doc/providers/asset.rst
@@ -0,0 +1,67 @@
+Asset
+=====
+
+The *AssetServiceProvider* provides a way to manage URL generation and
+versioning of web assets such as CSS stylesheets, JavaScript files and image
+files.
+
+Parameters
+----------
+
+* **assets.version**: Default version for assets.
+
+* **assets.format_version** (optional): Default format for assets.
+
+* **assets.named_packages** (optional): Named packages. Keys are the package
+ names and values the configuration (supported keys are ``version``,
+ ``version_format``, ``base_urls``, and ``base_path``).
+
+Services
+--------
+
+* **assets.packages**: The asset service.
+
+Registering
+-----------
+
+.. code-block:: php
+
+ $app->register(new Silex\Provider\AssetServiceProvider(), array(
+ 'assets.version' => 'v1',
+ 'assets.version_format' => '%s?version=%s',
+ 'assets.named_packages' => array(
+ 'css' => array('version' => 'css2', 'base_path' => '/whatever-makes-sense'),
+ 'images' => array('base_urls' => array('https://img.example.com')),
+ ),
+ ));
+
+.. note::
+
+ Add the Symfony Asset Component as a dependency:
+
+ .. code-block:: bash
+
+ composer require symfony/asset
+
+ If you want to use assets in your Twig templates, you must also install the
+ Symfony Twig Bridge:
+
+ .. code-block:: bash
+
+ composer require symfony/twig-bridge
+
+Usage
+-----
+
+The AssetServiceProvider is mostly useful with the Twig provider:
+
+.. code-block:: jinja
+
+ {{ asset('/css/foo.png') }}
+ {{ asset('/css/foo.css', 'css') }}
+ {{ asset('/img/foo.png', 'images') }}
+
+ {{ asset_version('/css/foo.png') }}
+
+For more information, check out the `Asset Component documentation
+`_.
diff --git a/vendor/silex/silex/doc/providers/csrf.rst b/vendor/silex/silex/doc/providers/csrf.rst
new file mode 100644
index 00000000..3bd35f4b
--- /dev/null
+++ b/vendor/silex/silex/doc/providers/csrf.rst
@@ -0,0 +1,52 @@
+CSRF
+====
+
+The *CsrfServiceProvider* provides a service for building forms in your
+application with the Symfony Form component.
+
+Parameters
+----------
+
+* none
+
+Services
+--------
+
+* **csrf.token_manager**: An instance of an implementation of the
+ `CsrfProviderInterface
+ `_,
+ defaults to a `DefaultCsrfProvider
+ `_.
+
+Registering
+-----------
+
+.. code-block:: php
+
+ use Silex\Provider\CsrfServiceProvider;
+
+ $app->register(new CsrfServiceProvider());
+
+.. note::
+
+ Add the Symfony's `Security CSRF Component
+ `_ as a
+ dependency:
+
+ .. code-block:: bash
+
+ composer require symfony/security-csrf
+
+Usage
+-----
+
+When the CSRF Service Provider is registered, all forms created via the Form
+Service Provider are protected against CSRF by default.
+
+You can also use the CSRF protection even without using the Symfony Form
+component. If, for example, you're doing a DELETE action, you can check the
+CSRF token::
+
+ use Symfony\Component\Security\Csrf\CsrfToken;
+
+ $app['csrf.token_manager']->isTokenValid(new CsrfToken('token_id', 'TOKEN'));
diff --git a/vendor/silex/silex/doc/providers/doctrine.rst b/vendor/silex/silex/doc/providers/doctrine.rst
new file mode 100644
index 00000000..0ef167b7
--- /dev/null
+++ b/vendor/silex/silex/doc/providers/doctrine.rst
@@ -0,0 +1,137 @@
+Doctrine
+========
+
+The *DoctrineServiceProvider* provides integration with the `Doctrine DBAL
+`_ for easy database access
+(Doctrine ORM integration is **not** supplied).
+
+Parameters
+----------
+
+* **db.options**: Array of Doctrine DBAL options.
+
+ These options are available:
+
+ * **driver**: The database driver to use, defaults to ``pdo_mysql``.
+ Can be any of: ``pdo_mysql``, ``pdo_sqlite``, ``pdo_pgsql``,
+ ``pdo_oci``, ``oci8``, ``ibm_db2``, ``pdo_ibm``, ``pdo_sqlsrv``.
+
+ * **dbname**: The name of the database to connect to.
+
+ * **host**: The host of the database to connect to. Defaults to
+ localhost.
+
+ * **user**: The user of the database to connect to. Defaults to
+ root.
+
+ * **password**: The password of the database to connect to.
+
+ * **charset**: Only relevant for ``pdo_mysql``, and ``pdo_oci/oci8``,
+ specifies the charset used when connecting to the database.
+
+ * **path**: Only relevant for ``pdo_sqlite``, specifies the path to
+ the SQLite database.
+
+ * **port**: Only relevant for ``pdo_mysql``, ``pdo_pgsql``, and ``pdo_oci/oci8``,
+ specifies the port of the database to connect to.
+
+ These and additional options are described in detail in the `Doctrine DBAL
+ configuration documentation `_.
+
+Services
+--------
+
+* **db**: The database connection, instance of
+ ``Doctrine\DBAL\Connection``.
+
+* **db.config**: Configuration object for Doctrine. Defaults to
+ an empty ``Doctrine\DBAL\Configuration``.
+
+* **db.event_manager**: Event Manager for Doctrine.
+
+Registering
+-----------
+
+.. code-block:: php
+
+ $app->register(new Silex\Provider\DoctrineServiceProvider(), array(
+ 'db.options' => array(
+ 'driver' => 'pdo_sqlite',
+ 'path' => __DIR__.'/app.db',
+ ),
+ ));
+
+.. note::
+
+ Add the Doctrine DBAL as a dependency:
+
+ .. code-block:: bash
+
+ composer require "doctrine/dbal:~2.2"
+
+Usage
+-----
+
+The Doctrine provider provides a ``db`` service. Here is a usage
+example::
+
+ $app->get('/blog/{id}', function ($id) use ($app) {
+ $sql = "SELECT * FROM posts WHERE id = ?";
+ $post = $app['db']->fetchAssoc($sql, array((int) $id));
+
+ return "{$post['title']}
".
+ "{$post['body']}
";
+ });
+
+Using multiple databases
+------------------------
+
+The Doctrine provider can allow access to multiple databases. In order to
+configure the data sources, replace the **db.options** with **dbs.options**.
+**dbs.options** is an array of configurations where keys are connection names
+and values are options::
+
+ $app->register(new Silex\Provider\DoctrineServiceProvider(), array(
+ 'dbs.options' => array (
+ 'mysql_read' => array(
+ 'driver' => 'pdo_mysql',
+ 'host' => 'mysql_read.someplace.tld',
+ 'dbname' => 'my_database',
+ 'user' => 'my_username',
+ 'password' => 'my_password',
+ 'charset' => 'utf8mb4',
+ ),
+ 'mysql_write' => array(
+ 'driver' => 'pdo_mysql',
+ 'host' => 'mysql_write.someplace.tld',
+ 'dbname' => 'my_database',
+ 'user' => 'my_username',
+ 'password' => 'my_password',
+ 'charset' => 'utf8mb4',
+ ),
+ ),
+ ));
+
+The first registered connection is the default and can simply be accessed as
+you would if there was only one connection. Given the above configuration,
+these two lines are equivalent::
+
+ $app['db']->fetchAll('SELECT * FROM table');
+
+ $app['dbs']['mysql_read']->fetchAll('SELECT * FROM table');
+
+Using multiple connections::
+
+ $app->get('/blog/{id}', function ($id) use ($app) {
+ $sql = "SELECT * FROM posts WHERE id = ?";
+ $post = $app['dbs']['mysql_read']->fetchAssoc($sql, array((int) $id));
+
+ $sql = "UPDATE posts SET value = ? WHERE id = ?";
+ $app['dbs']['mysql_write']->executeUpdate($sql, array('newValue', (int) $id));
+
+ return "{$post['title']}
".
+ "{$post['body']}
";
+ });
+
+For more information, consult the `Doctrine DBAL documentation
+`_.
diff --git a/vendor/silex/silex/doc/providers/form.rst b/vendor/silex/silex/doc/providers/form.rst
new file mode 100644
index 00000000..6818b858
--- /dev/null
+++ b/vendor/silex/silex/doc/providers/form.rst
@@ -0,0 +1,216 @@
+Form
+====
+
+The *FormServiceProvider* provides a service for building forms in
+your application with the Symfony Form component.
+
+Parameters
+----------
+
+* none
+
+Services
+--------
+
+* **form.factory**: An instance of `FormFactory
+ `_,
+ that is used to build a form.
+
+Registering
+-----------
+
+.. code-block:: php
+
+ use Silex\Provider\FormServiceProvider;
+
+ $app->register(new FormServiceProvider());
+
+.. note::
+
+ If you don't want to create your own form layout, it's fine: a default one
+ will be used. But you will have to register the :doc:`translation provider
+ ` as the default form layout requires it::
+
+ $app->register(new Silex\Provider\TranslationServiceProvider(), array(
+ 'translator.domains' => array(),
+ ));
+
+ If you want to use validation with forms, do not forget to register the
+ :doc:`Validator provider `.
+
+.. note::
+
+ Add the Symfony Form Component as a dependency:
+
+ .. code-block:: bash
+
+ composer require symfony/form
+
+ If you are going to use the validation extension with forms, you must also
+ add a dependency to the ``symfony/validator`` and ``symfony/config``
+ components:
+
+ .. code-block:: bash
+
+ composer require symfony/validator symfony/config
+
+ If you want to use forms in your Twig templates, you can also install the
+ Symfony Twig Bridge. Make sure to install, if you didn't do that already,
+ the Translation component in order for the bridge to work:
+
+ .. code-block:: bash
+
+ composer require symfony/twig-bridge
+
+Usage
+-----
+
+The FormServiceProvider provides a ``form.factory`` service. Here is a usage
+example::
+
+ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+ use Symfony\Component\Form\Extension\Core\Type\FormType;
+ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+
+ $app->match('/form', function (Request $request) use ($app) {
+ // some default data for when the form is displayed the first time
+ $data = array(
+ 'name' => 'Your name',
+ 'email' => 'Your email',
+ );
+
+ $form = $app['form.factory']->createBuilder(FormType::class, $data)
+ ->add('name')
+ ->add('email')
+ ->add('billing_plan', ChoiceType::class, array(
+ 'choices' => array('free' => 1, 'small business' => 2, 'corporate' => 3),
+ 'expanded' => true,
+ ))
+ ->add('submit', SubmitType::class, [
+ 'label' => 'Save',
+ ])
+ ->getForm();
+
+ $form->handleRequest($request);
+
+ if ($form->isValid()) {
+ $data = $form->getData();
+
+ // do something with the data
+
+ // redirect somewhere
+ return $app->redirect('...');
+ }
+
+ // display the form
+ return $app['twig']->render('index.twig', array('form' => $form->createView()));
+ });
+
+And here is the ``index.twig`` form template (requires ``symfony/twig-bridge``):
+
+.. code-block:: jinja
+
+
+
+If you are using the validator provider, you can also add validation to your
+form by adding constraints on the fields::
+
+ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+ use Symfony\Component\Form\Extension\Core\Type\FormType;
+ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+ use Symfony\Component\Form\Extension\Core\Type\TextType;
+ use Symfony\Component\Validator\Constraints as Assert;
+
+ $app->register(new Silex\Provider\ValidatorServiceProvider());
+ $app->register(new Silex\Provider\TranslationServiceProvider(), array(
+ 'translator.domains' => array(),
+ ));
+
+ $form = $app['form.factory']->createBuilder(FormType::class)
+ ->add('name', TextType::class, array(
+ 'constraints' => array(new Assert\NotBlank(), new Assert\Length(array('min' => 5)))
+ ))
+ ->add('email', TextType::class, array(
+ 'constraints' => new Assert\Email()
+ ))
+ ->add('billing_plan', ChoiceType::class, array(
+ 'choices' => array('free' => 1, 'small business' => 2, 'corporate' => 3),
+ 'expanded' => true,
+ 'constraints' => new Assert\Choice(array(1, 2, 3)),
+ ))
+ ->add('submit', SubmitType::class, [
+ 'label' => 'Save',
+ ])
+ ->getForm();
+
+You can register form types by extending ``form.types``::
+
+ $app['your.type.service'] = function ($app) {
+ return new YourServiceFormType();
+ };
+ $app->extend('form.types', function ($types) use ($app) {
+ $types[] = new YourFormType();
+ $types[] = 'your.type.service';
+
+ return $types;
+ }));
+
+You can register form extensions by extending ``form.extensions``::
+
+ $app->extend('form.extensions', function ($extensions) use ($app) {
+ $extensions[] = new YourTopFormExtension();
+
+ return $extensions;
+ });
+
+
+You can register form type extensions by extending ``form.type.extensions``::
+
+ $app['your.type.extension.service'] = function ($app) {
+ return new YourServiceFormTypeExtension();
+ };
+ $app->extend('form.type.extensions', function ($extensions) use ($app) {
+ $extensions[] = new YourFormTypeExtension();
+ $extensions[] = 'your.type.extension.service';
+
+ return $extensions;
+ });
+
+You can register form type guessers by extending ``form.type.guessers``::
+
+ $app['your.type.guesser.service'] = function ($app) {
+ return new YourServiceFormTypeGuesser();
+ };
+ $app->extend('form.type.guessers', function ($guessers) use ($app) {
+ $guessers[] = new YourFormTypeGuesser();
+ $guessers[] = 'your.type.guesser.service';
+
+ return $guessers;
+ });
+
+.. warning::
+
+ CSRF protection is only available and automatically enabled when the
+ :doc:`CSRF Service Provider ` is registered.
+
+Traits
+------
+
+``Silex\Application\FormTrait`` adds the following shortcuts:
+
+* **form**: Creates a FormBuilderInterface instance.
+
+* **namedForm**: Creates a FormBuilderInterface instance (named).
+
+.. code-block:: php
+
+ $app->form($data);
+
+ $app->namedForm($name, $data, $options, $type);
+
+For more information, consult the `Symfony Forms documentation
+`_.
diff --git a/vendor/silex/silex/doc/providers/http_cache.rst b/vendor/silex/silex/doc/providers/http_cache.rst
new file mode 100644
index 00000000..8bc98f67
--- /dev/null
+++ b/vendor/silex/silex/doc/providers/http_cache.rst
@@ -0,0 +1,128 @@
+HTTP Cache
+==========
+
+The *HttpCacheServiceProvider* provides support for the Symfony Reverse
+Proxy.
+
+Parameters
+----------
+
+* **http_cache.cache_dir**: The cache directory to store the HTTP cache data.
+
+* **http_cache.options** (optional): An array of options for the `HttpCache
+ `_
+ constructor.
+
+Services
+--------
+
+* **http_cache**: An instance of `HttpCache
+ `_.
+
+* **http_cache.esi**: An instance of `Esi
+ `_,
+ that implements the ESI capabilities to Request and Response instances.
+
+* **http_cache.store**: An instance of `Store
+ `_,
+ that implements all the logic for storing cache metadata (Request and Response
+ headers).
+
+Registering
+-----------
+
+.. code-block:: php
+
+ $app->register(new Silex\Provider\HttpCacheServiceProvider(), array(
+ 'http_cache.cache_dir' => __DIR__.'/cache/',
+ ));
+
+Usage
+-----
+
+Silex already supports any reverse proxy like Varnish out of the box by
+setting Response HTTP cache headers::
+
+ use Symfony\Component\HttpFoundation\Response;
+
+ $app->get('/', function() {
+ return new Response('Foo', 200, array(
+ 'Cache-Control' => 's-maxage=5',
+ ));
+ });
+
+.. tip::
+
+ If you want Silex to trust the ``X-Forwarded-For*`` headers from your
+ reverse proxy at address $ip, you will need to whitelist it as documented
+ in `Trusting Proxies
+ `_.
+
+ If you would be running Varnish in front of your application on the same machine::
+
+ use Symfony\Component\HttpFoundation\Request;
+
+ Request::setTrustedProxies(array('127.0.0.1', '::1'));
+ $app->run();
+
+This provider allows you to use the Symfony reverse proxy natively with
+Silex applications by using the ``http_cache`` service. The Symfony reverse proxy
+acts much like any other proxy would, so you will want to whitelist it::
+
+ use Symfony\Component\HttpFoundation\Request;
+
+ Request::setTrustedProxies(array('127.0.0.1'));
+ $app['http_cache']->run();
+
+The provider also provides ESI support::
+
+ $app->get('/', function() {
+ $response = new Response(<<
+
+ Hello
+
+
+